From 847ed4183c4b75493afd95a19af25ba6c779a726 Mon Sep 17 00:00:00 2001 From: Chris Pinkham Date: Fri, 13 Dec 2019 10:09:32 -0800 Subject: [PATCH] Fix some flicker when scrolling text in Pixel Overlay model When scrolling text across the Pixel Overlay model, the channel output code would sometimes grab the frame in the middle of the clear() call. This was causing occasional flicker. Now, we double buffer and only need to clear our buffer before drawing on it again and then copying the whole buffer into place. This still doesn't fix 'tearing' that may occur because the scroll is not gen locked to the channel output code, but it is better than before. (cherry picked from commit c02a5d635b3915ad538d5b911cb3570598cd5b0a) --- src/PixelOverlay.cpp | 17 ++++++++++++++--- src/PixelOverlay.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/PixelOverlay.cpp b/src/PixelOverlay.cpp index 1ecae1b7b..82326aa43 100644 --- a/src/PixelOverlay.cpp +++ b/src/PixelOverlay.cpp @@ -66,7 +66,7 @@ PixelOverlayModel::PixelOverlayModel(FPPChannelMemoryMapControlBlock *b, char *cdm, uint32_t *pm) : block(b), name(n), chanDataMap(cdm), pixelMap(pm), - updateThread(nullptr),threadKeepRunning(false), + updateThread(nullptr),threadKeepRunning(false), overlayBuffer(nullptr), imageData(nullptr), imageDataRows(0), imageDataCols(0) { } @@ -79,6 +79,9 @@ PixelOverlayModel::~PixelOverlayModel() { if (imageData) { free(imageData); } + if (overlayBuffer) { + free(overlayBuffer); + } } int PixelOverlayModel::getWidth() const { @@ -293,6 +296,10 @@ void PixelOverlayModel::doText(const std::string &msg, np[2] = b; } } + + if (!overlayBuffer) + overlayBuffer = (uint8_t*)malloc(block->channelCount); + copyImageData(x, y); lock(); threadKeepRunning = true; @@ -336,7 +343,7 @@ void PixelOverlayModel::doImageMovementThread(const std::string &direction, int void PixelOverlayModel::copyImageData(int xoff, int yoff) { if (imageData) { - clear(); + memset(overlayBuffer, 0, block->channelCount); int h, w; getSize(w, h); for (int y = 0; y < imageDataRows; ++y) { @@ -351,9 +358,13 @@ void PixelOverlayModel::copyImageData(int xoff, int yoff) { continue; } uint8_t *p = &imageData[idx + (x*3)]; - setPixelValue(nx, ny, p[0], p[1], p[2]); + int c = (ny*getWidth()*3) + nx*3; + overlayBuffer[c++] = p[0]; + overlayBuffer[c++] = p[1]; + overlayBuffer[c++] = p[2]; } } + setData(overlayBuffer); } } diff --git a/src/PixelOverlay.h b/src/PixelOverlay.h index bf71e5094..309579a20 100644 --- a/src/PixelOverlay.h +++ b/src/PixelOverlay.h @@ -128,6 +128,7 @@ class PixelOverlayModel { std::thread *updateThread; volatile bool threadKeepRunning; + uint8_t *overlayBuffer; uint8_t *imageData; int imageDataRows; int imageDataCols;