Repository: microsoft/terminal
File: src/terminal/adapter/SixelParser.cpp (C++)

Code before:
void SixelParser::_maybeFlushImageBuffer(const bool endOfSequence)
{
    // Regardless of whether we flush the image or not, we always calculate how
    // much we need to scroll in advance. This algorithm is a bit odd. If there
    // isn't enough space for the current segment, it'll scroll until it can fit
    // the segment with a pixel to spare. So in the case that it's an exact fit,
    // it's expected that we'd scroll an additional line. Although this is not
    // common, since it only occurs for pixel aspect ratios of 4:1 or more. Also
    // note that we never scroll more than the margin height, since that would
    // result in the top of the segment being pushed offscreen.
    if (_segmentHeight > _availablePixelHeight && !_displayMode) [[unlikely]]
    {
        const auto marginPixelHeight = _textMargins.height() * _cellSize.height;
        while (_availablePixelHeight < marginPixelHeight && _segmentHeight >= _availablePixelHeight)
        {
            _pendingTextScrollCount += 1;
            _availablePixelHeight += _cellSize.height;
        }
    }

    // Once we've calculated how much scrolling was necessary for the existing
    // segment height, we don't need to track that any longer. The next segment
    // will start with the active sixel height.
    _segmentHeight = _sixelHeight;

    // This method is called after every newline (DECGNL), but we don't want to
    // render partial output for high speed image sequences like video, so we
    // only flush if it has been more than 500ms since the last flush, or it
    // appears that the output is intentionally streamed. If the current buffer
    // has ended with a newline, and we've received no more than one line since
    // the last flush, that suggest it's an intentional break in the stream.
    const auto currentTime = steady_clock::now();
    const auto timeSinceLastFlush = duration_cast<milliseconds>(currentTime - _lastFlushTime);
    const auto linesSinceLastFlush = _imageLineCount - _lastFlushLine;
    if (endOfSequence || timeSinceLastFlush > 500ms || (linesSinceLastFlush <= 1 && _stateMachine.IsProcessingLastCharacter()))
    {
        _lastFlushTime = currentTime;
        _lastFlushLine = _imageLineCount;

        // Before we output anything, we need to scroll the text buffer to make
        // space for the image, using the precalculated scroll count from above.
        auto page = _dispatcher._pages.ActivePage();
        if (_pendingTextScrollCount > 0) [[unlikely]]
        {
            _scrollTextBuffer(page, _pendingTextScrollCount);
            _pendingTextScrollCount = 0;
        }

        // If there's no image width, there's nothing to render at this point,
        // so the only visible change will be the scrolling.
        if (_imageWidth > 0)

Review comment (suggestion):
To work around `std::fill` being bloated with memset and to work around the compiler inserting a pointless `rep stos` here, we can use volatile writes. This then compiles down to a very small compact loop = makes CPUs happy.

Code after:
            }

            _imageCursor.x += 1;
            imageBufferPtr += 1;
            repeatCount -= 1;
        } while (repeatCount > 0);
    }
    else
    {
        for (auto i = 0; i < 6; i++)
        {
            if (sixelValue & 1)
            {
                auto repeatAspectRatio = _pixelAspectRatio;
                do
                {
                    // If this used std::fill_n or just a primitive loop, MSVC would compile
                    // it to a `rep stosw` instruction, which has a high startup cost.
                    // This is not ideal when our repeatCount is almost always small.
                    // The way this does ptr++ and len-- is also ideal for optimization.
                    auto ptr = imageBufferPtr;
                    auto remaining = repeatCount;
                    do
                    {
                        __iso_volatile_store16(ptr++, foreground);
                    } while (--remaining != 0);

                    imageBufferPtr += _imageMaxWidth;
                } while (--repeatAspectRatio > 0);
            }
            else
            {
                std::advance(imageBufferPtr, _imageMaxWidth * _pixelAspectRatio);
            }
            sixelValue >>= 1;
        }
        _imageCursor.x += repeatCount;
    }
}

#pragma warning(pop)

void SixelParser::_eraseImageBufferRows(const int rowCount, const til::CoordType rowOffset) noexcept
{
    const auto pixelCount = rowCount * _cellSize.height;
    const auto bufferOffset = rowOffset * _cellSize.height * _imageMaxWidth;
    const auto bufferOffsetEnd = bufferOffset + pixelCount * _imageMaxWidth;
    if (static_cast<size_t>(bufferOffsetEnd) >= _imageBuffer.size()) [[unlikely]]
    {
        _decreaseFilledBackgroundHeight(_imageCursor.y);
        _imageBuffer.clear();