diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/rfb/DecodeManager.cxx | 17 | ||||
-rw-r--r-- | common/rfb/Decoder.cxx | 8 | ||||
-rw-r--r-- | common/rfb/Decoder.h | 14 | ||||
-rw-r--r-- | common/rfb/TightDecoder.cxx | 35 | ||||
-rw-r--r-- | common/rfb/TightDecoder.h | 7 |
5 files changed, 80 insertions, 1 deletions
diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx index 3c1ddb41..ba2b2d2f 100644 --- a/common/rfb/DecodeManager.cxx +++ b/common/rfb/DecodeManager.cxx @@ -268,6 +268,23 @@ DecodeManager::QueueEntry* DecodeManager::DecodeThread::findEntry() } } + // For a partially ordered decoder we must ask the decoder for each + // pair of rectangles. + if (entry->decoder->flags & DecoderPartiallyOrdered) { + for (iter2 = manager->workQueue.begin(); iter2 != iter; ++iter2) { + if (entry->encoding != (*iter2)->encoding) + continue; + if (entry->decoder->doRectsConflict(entry->rect, + entry->bufferStream->data(), + entry->bufferStream->length(), + (*iter2)->rect, + (*iter2)->bufferStream->data(), + (*iter2)->bufferStream->length(), + *entry->cp)) + goto next; + } + } + // Check overlap with earlier rectangles if (!lockedRegion.intersect(entry->affectedRegion).is_empty()) goto next; diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx index df785ebe..370e1f9a 100644 --- a/common/rfb/Decoder.cxx +++ b/common/rfb/Decoder.cxx @@ -44,6 +44,14 @@ void Decoder::getAffectedRegion(const Rect& rect, const void* buffer, region->reset(rect); } +bool Decoder::doRectsConflict(const Rect& rectA, const void* bufferA, + size_t buflenA, const Rect& rectB, + const void* bufferB, size_t buflenB, + const ConnParams& cp) +{ + return false; +} + bool Decoder::supported(int encoding) { switch (encoding) { diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h index 9a03eb38..3840b3fd 100644 --- a/common/rfb/Decoder.h +++ b/common/rfb/Decoder.h @@ -35,6 +35,9 @@ namespace rfb { DecoderPlain = 0, // All rects for this decoder must be handled in order DecoderOrdered = 1 << 0, + // Only some of the rects must be handled in order, + // see doesRectsConflict() + DecoderPartiallyOrdered = 1 << 1, }; class Decoder { @@ -62,6 +65,17 @@ namespace rfb { size_t buflen, const ConnParams& cp, Region* region); + // doesRectsConflict() determines if two rectangles must be decoded + // in the order they were received. This will only be called if the + // DecoderPartiallyOrdered flag has been set. + virtual bool doRectsConflict(const Rect& rectA, + const void* bufferA, + size_t buflenA, + const Rect& rectB, + const void* bufferB, + size_t buflenB, + const ConnParams& cp); + // 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 diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx index ec329e40..86bb0069 100644 --- a/common/rfb/TightDecoder.cxx +++ b/common/rfb/TightDecoder.cxx @@ -46,7 +46,7 @@ static const int TIGHT_MIN_TO_COMPRESS = 12; #include <rfb/tightDecode.h> #undef BPP -TightDecoder::TightDecoder() : Decoder(DecoderOrdered) +TightDecoder::TightDecoder() : Decoder(DecoderPartiallyOrdered) { } @@ -148,6 +148,39 @@ void TightDecoder::readRect(const Rect& r, rdr::InStream* is, } } +bool TightDecoder::doRectsConflict(const Rect& rectA, + const void* bufferA, + size_t buflenA, + const Rect& rectB, + const void* bufferB, + size_t buflenB, + const ConnParams& cp) +{ + rdr::U8 comp_ctl_a, comp_ctl_b; + + assert(buflenA >= 1); + assert(buflenB >= 1); + + comp_ctl_a = *(const rdr::U8*)bufferA; + comp_ctl_b = *(const rdr::U8*)bufferB; + + // Resets or use of zlib pose the same problem, so merge them + if ((comp_ctl_a & 0x80) == 0x00) + comp_ctl_a |= 1 << ((comp_ctl_a >> 4) & 0x03); + if ((comp_ctl_b & 0x80) == 0x00) + comp_ctl_b |= 1 << ((comp_ctl_b >> 4) & 0x03); + + if (((comp_ctl_a & 0x0f) & (comp_ctl_b & 0x0f)) != 0) + return true; + + // We have a shared JpegDecompressor, so one at a time + if (((comp_ctl_a >> 4) == tightJpeg) && + ((comp_ctl_b >> 4) == tightJpeg)) + return true; + + return false; +} + void TightDecoder::decodeRect(const Rect& r, const void* buffer, size_t buflen, const ConnParams& cp, ModifiablePixelBuffer* pb) diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h index 18497d41..a98788f6 100644 --- a/common/rfb/TightDecoder.h +++ b/common/rfb/TightDecoder.h @@ -33,6 +33,13 @@ namespace rfb { virtual ~TightDecoder(); virtual void readRect(const Rect& r, rdr::InStream* is, const ConnParams& cp, rdr::OutStream* os); + virtual bool doRectsConflict(const Rect& rectA, + const void* bufferA, + size_t buflenA, + const Rect& rectB, + const void* bufferB, + size_t buflenB, + const ConnParams& cp); virtual void decodeRect(const Rect& r, const void* buffer, size_t buflen, const ConnParams& cp, ModifiablePixelBuffer* pb); |