]> source.dussan.org Git - tigervnc.git/commitdiff
Allow conditional dependencies between rects when decoding
authorPierre Ossman <ossman@cendio.se>
Fri, 13 Nov 2015 09:47:28 +0000 (10:47 +0100)
committerPierre Ossman <ossman@cendio.se>
Fri, 27 Nov 2015 10:10:41 +0000 (11:10 +0100)
Some encodings only cause dependencies between rects some of the
time. Make sure we can allow parallel decoding of those rect that
aren't dependent on each other.

common/rfb/DecodeManager.cxx
common/rfb/Decoder.cxx
common/rfb/Decoder.h
common/rfb/TightDecoder.cxx
common/rfb/TightDecoder.h

index 3c1ddb412c58dfbe11c127ff98544bc1b70b5164..ba2b2d2f33bc9c1a62dd53b07e02066872be6e74 100644 (file)
@@ -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;
index df785ebefb3dd22b1080ae84c346fc41da8fb884..370e1f9a29b7f44c916ffd01b1a2f0d77dc8bca7 100644 (file)
@@ -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) {
index 9a03eb3889d31fc2801d8bd6e542ecf024f8f9df..3840b3fd52edc810101bced50f5a652fb0292b7f 100644 (file)
@@ -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
index ec329e40a2712df41f2dd8b1c8306d852e5b8c20..86bb00698655fc3b68a4dcdecabf670bb2b11574 100644 (file)
@@ -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)
index 18497d41b6f2b3bbc2649a6e91626c8850e41f2c..a98788f6da4b6796746bb2931df5d1f3b4829e16 100644 (file)
@@ -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);