From 1412789e1264b73f7f4d05242bcfbf960f618b15 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 12 Nov 2015 13:17:42 +0100 Subject: [PATCH] Decode overlapping rectangles in order --- common/rfb/CopyRectDecoder.cxx | 18 ++++++++++++++++++ common/rfb/CopyRectDecoder.h | 3 +++ common/rfb/DecodeManager.cxx | 23 ++++++++++++++++++++--- common/rfb/DecodeManager.h | 2 ++ common/rfb/Decoder.cxx | 8 ++++++++ common/rfb/Decoder.h | 7 +++++++ 6 files changed, 58 insertions(+), 3 deletions(-) diff --git a/common/rfb/CopyRectDecoder.cxx b/common/rfb/CopyRectDecoder.cxx index 32ed1b3b..23949a8b 100644 --- a/common/rfb/CopyRectDecoder.cxx +++ b/common/rfb/CopyRectDecoder.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include using namespace rfb; @@ -36,6 +37,23 @@ void CopyRectDecoder::readRect(const Rect& r, rdr::InStream* is, os->copyBytes(is, 4); } + +void CopyRectDecoder::getAffectedRegion(const Rect& rect, + const void* buffer, + size_t buflen, + const ConnParams& cp, + Region* region) +{ + rdr::MemInStream is(buffer, buflen); + int srcX = is.readU16(); + int srcY = is.readU16(); + + Decoder::getAffectedRegion(rect, buffer, buflen, cp, region); + + region->assign_union(Region(rect.translate(Point(srcX-rect.tl.x, + srcY-rect.tl.y)))); +} + void CopyRectDecoder::decodeRect(const Rect& r, const void* buffer, size_t buflen, const ConnParams& cp, ModifiablePixelBuffer* pb) diff --git a/common/rfb/CopyRectDecoder.h b/common/rfb/CopyRectDecoder.h index 998a5091..1d2ce53b 100644 --- a/common/rfb/CopyRectDecoder.h +++ b/common/rfb/CopyRectDecoder.h @@ -28,6 +28,9 @@ namespace rfb { virtual ~CopyRectDecoder(); virtual void readRect(const Rect& r, rdr::InStream* is, const ConnParams& cp, rdr::OutStream* os); + virtual void getAffectedRegion(const Rect& rect, const void* buffer, + size_t buflen, const ConnParams& cp, + Region* region); virtual void decodeRect(const Rect& r, const void* buffer, size_t buflen, const ConnParams& cp, ModifiablePixelBuffer* pb); diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx index a444eb7b..ddebf0a3 100644 --- a/common/rfb/DecodeManager.cxx +++ b/common/rfb/DecodeManager.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -129,6 +130,10 @@ void DecodeManager::decodeRect(const Rect& r, int encoding, entry->pb = pb; entry->bufferStream = bufferStream; + decoder->getAffectedRegion(r, bufferStream->data(), + bufferStream->length(), conn->cp, + &entry->affectedRegion); + queueMutex->lock(); // The workers add buffers to the end so it's safe to assume @@ -233,6 +238,7 @@ void DecodeManager::DecodeThread::worker() DecodeManager::QueueEntry* DecodeManager::DecodeThread::findEntry() { std::list::iterator iter; + Region lockedRegion; if (manager->workQueue.empty()) return NULL; @@ -243,13 +249,24 @@ DecodeManager::QueueEntry* DecodeManager::DecodeThread::findEntry() for (iter = manager->workQueue.begin(); iter != manager->workQueue.end(); ++iter) { + DecodeManager::QueueEntry* entry; + + entry = *iter; + // Another thread working on this? - if ((*iter)->active) - continue; + if (entry->active) + goto next; + + // Check overlap with earlier rectangles + if (!lockedRegion.intersect(entry->affectedRegion).is_empty()) + goto next; // FIXME: check dependencies between rects - return *iter; + return entry; + +next: + lockedRegion.assign_union(entry->affectedRegion); } return NULL; diff --git a/common/rfb/DecodeManager.h b/common/rfb/DecodeManager.h index 1a974ea4..dec7a6cb 100644 --- a/common/rfb/DecodeManager.h +++ b/common/rfb/DecodeManager.h @@ -23,6 +23,7 @@ #include +#include #include namespace os { @@ -60,6 +61,7 @@ namespace rfb { const ConnParams* cp; ModifiablePixelBuffer* pb; rdr::MemOutStream* bufferStream; + Region affectedRegion; }; std::list freeBuffers; diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx index f9bbffca..df785ebe 100644 --- a/common/rfb/Decoder.cxx +++ b/common/rfb/Decoder.cxx @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -36,6 +37,13 @@ Decoder::~Decoder() { } +void Decoder::getAffectedRegion(const Rect& rect, const void* buffer, + size_t buflen, const ConnParams& cp, + Region* region) +{ + region->reset(rect); +} + bool Decoder::supported(int encoding) { switch (encoding) { diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h index 95c14668..f631a551 100644 --- a/common/rfb/Decoder.h +++ b/common/rfb/Decoder.h @@ -53,6 +53,13 @@ namespace rfb { // A lock will be held whilst these are called so it is safe to // read and update internal state as necessary. + // getAffectedRegion() returns the parts of the frame buffer will + // be either read from or written do when decoding this rect. The + // default implementation simply returns the given rectangle. + virtual void getAffectedRegion(const Rect& rect, const void* buffer, + size_t buflen, const ConnParams& cp, + Region* region); + // decodeRect() decodes the given rectangle with data from the // given buffer, onto the ModifiablePixelBuffer. The PixelFormat of // the PixelBuffer might not match the ConnParams and it is up to -- 2.39.5