]> source.dussan.org Git - tigervnc.git/commitdiff
Decode overlapping rectangles in order
authorPierre Ossman <ossman@cendio.se>
Thu, 12 Nov 2015 12:17:42 +0000 (13:17 +0100)
committerPierre Ossman <ossman@cendio.se>
Fri, 27 Nov 2015 10:09:38 +0000 (11:09 +0100)
common/rfb/CopyRectDecoder.cxx
common/rfb/CopyRectDecoder.h
common/rfb/DecodeManager.cxx
common/rfb/DecodeManager.h
common/rfb/Decoder.cxx
common/rfb/Decoder.h

index 32ed1b3bdd81c5ac29cedb8b63306e0c8b418fbd..23949a8bb2ae0f398cc6910c811ffbfa4908857c 100644 (file)
@@ -18,6 +18,7 @@
 #include <rdr/MemInStream.h>
 #include <rdr/OutStream.h>
 #include <rfb/PixelBuffer.h>
+#include <rfb/Region.h>
 #include <rfb/CopyRectDecoder.h>
 
 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)
index 998a50918455743d97168fd42ef15429fa9f0f8d..1d2ce53b9051afa1c35eefe4219717d64674bd1b 100644 (file)
@@ -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);
index a444eb7b1500d15719c51e34abc7fb6b1d31bc10..ddebf0a3796fc9be0b2ed9ecad372227cf3c7a1a 100644 (file)
@@ -22,6 +22,7 @@
 #include <rfb/CConnection.h>
 #include <rfb/DecodeManager.h>
 #include <rfb/Decoder.h>
+#include <rfb/Region.h>
 
 #include <rfb/LogWriter.h>
 
@@ -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<DecodeManager::QueueEntry*>::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;
index 1a974ea4add55b85bf8be1dd67e06028ed220f5a..dec7a6cbf351ceeb7574579becfde176c480fd52 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <os/Thread.h>
 
+#include <rfb/Region.h>
 #include <rfb/encodings.h>
 
 namespace os {
@@ -60,6 +61,7 @@ namespace rfb {
       const ConnParams* cp;
       ModifiablePixelBuffer* pb;
       rdr::MemOutStream* bufferStream;
+      Region affectedRegion;
     };
 
     std::list<rdr::MemOutStream*> freeBuffers;
index f9bbffcae8c19bab2d956d802ac97796ede12e0e..df785ebefb3dd22b1080ae84c346fc41da8fb884 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include <stdio.h>
 #include <rfb/encodings.h>
+#include <rfb/Region.h>
 #include <rfb/Decoder.h>
 #include <rfb/RawDecoder.h>
 #include <rfb/CopyRectDecoder.h>
@@ -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) {
index 95c146682aacf7643ee2573c28dddad15294f3ab..f631a5512130bd6e2ce9b61ed8088a561779c576 100644 (file)
@@ -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