From 732c38e0def0c6fea4e326e51dd1f8f8dea0e402 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Sun, 24 May 2026 17:50:03 +0200 Subject: [PATCH] Drop redundant in-frame check --- lib/GfxRenderer/GfxRenderer.cpp | 13 ++++++++----- lib/GfxRenderer/GfxRenderer.h | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 3d16d584..403b1ed3 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -624,7 +624,9 @@ static void renderGlyphFast2BitPortrait(uint8_t* const frameBuffer, const uint8_ const int widthBytes, const int fbOriginY, const int fbRows) { for (int glyphX = 0; glyphX < glyphWidth; glyphX++) { const int phyY = inverted ? (screenXBase + glyphX) : (displayHeight - 1 - (screenXBase + glyphX)); - if (phyY < 0 || phyY >= displayHeight) continue; + // Single unsigned compare drops both off-band rows (strip mode) and any + // out-of-frame row (full-frame mode: fbOriginY=0, fbRows=displayHeight), + // matching what the Landscape* cases above do. const int rowY = phyY - fbOriginY; if (static_cast(rowY) >= static_cast(fbRows)) continue; uint8_t* const row = frameBuffer + rowY * widthBytes; @@ -2656,10 +2658,11 @@ void GfxRenderer::restoreBwBuffer() { bwSnapshotRowEnd = 0; } -/** - * Cleanup grayscale buffers using the current frame buffer. - * Use this when BW buffer was re-rendered instead of stored/restored. - */ +// Cleanup grayscale buffers using the current frame buffer. +// Use this when BW buffer was re-rendered instead of stored/restored. +// On X3 the display call transiently Y-flips frameBuffer in place and flips +// it back before returning; the logical contents are unchanged but callers +// must not race a framebuffer reader against this call. See the header. void GfxRenderer::cleanupGrayscaleWithFrameBuffer() const { if (frameBuffer) { display.cleanupGrayscaleBuffers(frameBuffer); diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index 4b0567b1..d44c0abd 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -303,6 +303,18 @@ class GfxRenderer { bool storeBwBuffer(); // Returns true if buffer was stored successfully bool storeBwBufferRect(int x, int y, int width, int height); // Store only rows intersecting logical rect void restoreBwBuffer(); // Restore and free the stored buffer + // Re-syncs the controller's RED RAM from the current BW framebuffer so the + // next differential page turn has a clean baseline. Called after the tiled + // grayscale path, which leaves the panel's gray planes loaded but the BW + // framebuffer untouched. + // + // const-correctness caveat: on X3 the underlying display call (see + // EInkDisplay::cleanupGrayscaleBuffers) performs an in-place Y-flip of the + // framebuffer bytes, sends them, and flips back. The framebuffer's logical + // contents are identical before and after, but during the call the bytes + // are transiently reordered. The method stays `const` because the renderer's + // observable state doesn't change; callers must not race a framebuffer + // reader against this call. void cleanupGrayscaleWithFrameBuffer() const; // Font helpers