]> source.dussan.org Git - tigervnc.git/commitdiff
Special handling of a rectangular video area in the UpdateTracker and derived/related...
authorConstantin Kaplinsky <const@tightvnc.com>
Fri, 31 Aug 2007 21:06:53 +0000 (21:06 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Fri, 31 Aug 2007 21:06:53 +0000 (21:06 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2327 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/ComparingUpdateTracker.cxx
common/rfb/UpdateTracker.cxx
common/rfb/UpdateTracker.h
common/rfb/VNCSConnectionST.cxx
common/rfb/VNCSConnectionST.h
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index ce3d68aeb752e9234feb1613fff83296cdb36381..ec323020fae9d9f2f2f0b24e05e623a8ef2bfe78 100644 (file)
@@ -38,6 +38,14 @@ ComparingUpdateTracker::~ComparingUpdateTracker()
 
 void ComparingUpdateTracker::compare()
 {
+  // First of all, exclude video area from both changed and copied regions.
+  // We handle video area separately and do not compare it -- we know it's
+  // being changed continuously.
+  if (!video_area.is_empty()) {
+    changed.assign_subtract(video_area);
+    copied.assign_subtract(video_area);
+  }
+
   std::vector<Rect> rects;
   std::vector<Rect>::iterator i;
 
index 14ac49d786239edd5de0d5b569faab404b7ae0f8..79f43f606e12873bbab591256a7de09c5f5788bf 100644 (file)
@@ -60,6 +60,10 @@ void ClippingUpdateTracker::add_copied(const Region &dest, const Point &delta) {
     ut->add_changed(tmp);
 }
 
+void ClippingUpdateTracker::set_video_area(const Rect &rect) {
+  ut->set_video_area(rect.intersect(clipRect));
+}
+
 // SimpleUpdateTracker
 
 SimpleUpdateTracker::SimpleUpdateTracker(bool use_copyrect) {
@@ -135,6 +139,18 @@ void SimpleUpdateTracker::add_copied(const Region &dest, const Point &delta) {
   return;
 }
 
+void SimpleUpdateTracker::set_video_area(const Rect &rect)
+{
+  video_area = rect;
+}
+
+//
+// subtract() is called to mark some region as unchanged. We just remove that
+// region from both `copied' and `changed' regions. Note that `video_area' is
+// not affected intentionally; we assume that video is continuously changing,
+// so it should always be treated as "changed".
+//
+
 void SimpleUpdateTracker::subtract(const Region& region) {
   copied.assign_subtract(region);
   changed.assign_subtract(region);
@@ -142,10 +158,15 @@ void SimpleUpdateTracker::subtract(const Region& region) {
 
 void SimpleUpdateTracker::getUpdateInfo(UpdateInfo* info, const Region& clip)
 {
-  copied.assign_subtract(changed);
+  changed.assign_subtract(video_area);
+  copied.assign_subtract(changed.union_(video_area));
   info->changed = changed.intersect(clip);
   info->copied = copied.intersect(clip);
   info->copy_delta = copy_delta;
+  // FIXME: Using get_bounding_rect() is not what should actually be done!
+  //        We should use the biggest inner rectangle of the `clip' instead.
+  //        From the other side, `clip' is usually just a sole rectangle.
+  info->video_area = video_area.intersect(clip.get_bounding_rect());
 }
 
 void SimpleUpdateTracker::copyTo(UpdateTracker* to) const {
@@ -153,4 +174,5 @@ void SimpleUpdateTracker::copyTo(UpdateTracker* to) const {
     to->add_copied(copied, copy_delta);
   if (!changed.is_empty())
     to->add_changed(changed);
+  to->set_video_area(video_area);
 }
index 8e96d55ed007dbff9cfdf0e9074d15eaa3a188b1..b6a7d748a4205f582f802b78219145fcce69e464 100644 (file)
@@ -30,14 +30,15 @@ namespace rfb {
     Region changed;
     Region copied;
     Point copy_delta;
+    Rect video_area;
     bool is_empty() const {
-      return copied.is_empty() && changed.is_empty();
+      return copied.is_empty() && changed.is_empty() && video_area.is_empty();
     }
     // NOTE: We do not ever use UpdateInfo::numRects(), because Tight encoding
     //       complicates computing the number of rectangles.
     /*
     int numRects() const {
-      return copied.numRects() + changed.numRects();
+      return copied.numRects() + changed.numRects() + !video_area.is_empty();
     }
     */
   };
@@ -49,6 +50,7 @@ namespace rfb {
 
     virtual void add_changed(const Region &region) = 0;
     virtual void add_copied(const Region &dest, const Point &delta) = 0;
+    virtual void set_video_area(const Rect &rect) = 0;
   };
 
   class ClippingUpdateTracker : public UpdateTracker {
@@ -61,6 +63,7 @@ namespace rfb {
 
     virtual void add_changed(const Region &region);
     virtual void add_copied(const Region &dest, const Point &delta);
+    virtual void set_video_area(const Rect &rect);
   protected:
     UpdateTracker* ut;
     Rect clipRect;
@@ -75,6 +78,7 @@ namespace rfb {
 
     virtual void add_changed(const Region &region);
     virtual void add_copied(const Region &dest, const Point &delta);
+    virtual void set_video_area(const Rect &rect);
     virtual void subtract(const Region& region);
 
     // Fill the supplied UpdateInfo structure with update information
@@ -85,16 +89,33 @@ namespace rfb {
     virtual void copyTo(UpdateTracker* to) const;
 
     // Move the entire update region by an offset
-    void translate(const Point& p) {changed.translate(p); copied.translate(p);}
+    void translate(const Point& p) {
+      changed.translate(p);
+      copied.translate(p);
+      video_area.translate(p);
+    }
 
-    virtual bool is_empty() const {return changed.is_empty() && copied.is_empty();}
+    virtual bool is_empty() const {
+      return changed.is_empty() && copied.is_empty() && video_area.is_empty();
+    }
+
+    // NOTE: We do not clear video_area intentionally.
+    virtual void clear() {
+      changed.clear();
+      copied.clear();
+    }
 
-    virtual void clear() {changed.clear(); copied.clear();};
   protected:
     Region changed;
     Region copied;
     Point copy_delta;
     bool copy_enabled;
+
+    // We can track one rectangle on the screen as a "video area". We assume
+    // it is changing continuously, in whole. Thus, we don't need to detect
+    // and track individual changes in the video area -- we can assume it's
+    // always in the changed state.
+    Rect video_area;
   };
 
 }
index 9055017e928b568c0da949c3d26e264b035e2c91..5237c1b4d67fa5c5a26495a19cb6bafc8ff52df4 100644 (file)
@@ -574,7 +574,7 @@ void VNCSConnectionST::writeFramebufferUpdate()
 
   // Get the lists of updates. Prior to exporting the data to the `ui' object,
   // getUpdateInfo() will normalize the `updates' object such way that its
-  // `changed' and `copied' regions would not intersect.
+  // `changed', `copied' and `video_area' regions would not intersect.
 
   UpdateInfo ui;
   updates.getUpdateInfo(&ui, requested);
@@ -645,7 +645,11 @@ void VNCSConnectionST::writeFramebufferUpdate()
     // Compute the number of rectangles. Tight encoder makes the things more
     // complicated as compared to the original VNC4.
     writer()->setupCurrentEncoder();
-    int nRects = ui.copied.numRects() + (drawRenderedCursor ? 1 : 0);
+    int nRects = (ui.copied.numRects() +
+                  /* FIXME: Sending video area is not yet enabled.
+                  (ui.video_area.is_empty() ? 0 : 1) +
+                  */
+                  (drawRenderedCursor ? 1 : 0));
     std::vector<Rect> rects;
     std::vector<Rect>::const_iterator i;
     ui.changed.get_rects(&rects);
index 7fe2e323ac88ac3ce01cb9d78e81a8448b73d620..a388873d4485da3d891a81eb981e906930ba3f5c 100644 (file)
@@ -93,6 +93,7 @@ namespace rfb {
     void add_copied(const Region& dest, const Point& delta) {
       updates.add_copied(dest, delta);
     }
+    void set_video_area(const Rect &rect) { updates.set_video_area(rect); }
 
     const char* getPeerEndpoint() const {return peerEndpoint.buf;}
 
index c02c2eb0721c229dc82951724fa0b58d5383bd12..e5354a41ab0da8ec6dd23927937dcdfa9cf85b2f 100644 (file)
@@ -314,6 +314,11 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta)
   comparer->add_copied(dest, delta);
 }
 
+void VNCServerST::set_video_area(const Rect &rect)
+{
+  comparer->set_video_area(rect);
+}
+
 bool VNCServerST::clientsReadyForUpdate()
 {
   std::list<VNCSConnectionST*>::iterator ci;
@@ -459,7 +464,7 @@ void VNCServerST::checkUpdate()
   if (ui.is_empty() && !(renderCursor && renderedCursorInvalid))
     return;
 
-  Region toCheck = ui.changed.union_(ui.copied);
+  Region toCheck = ui.changed.union_(ui.copied).union_(ui.video_area);
 
   if (renderCursor) {
     Rect clippedCursorRect
@@ -495,6 +500,7 @@ void VNCServerST::checkUpdate()
     ci_next = ci; ci_next++;
     (*ci)->add_copied(ui.copied, ui.copy_delta);
     (*ci)->add_changed(ui.changed);
+    (*ci)->set_video_area(ui.video_area);
   }
 
   comparer->clear();
index bc15b7f476a8f9e0b5f68dfb061310c30b21a470..37b75eafaddf8746180747058530489f7b7b575b 100644 (file)
@@ -83,6 +83,7 @@ namespace rfb {
     virtual void serverCutText(const char* str, int len);
     virtual void add_changed(const Region &region);
     virtual void add_copied(const Region &dest, const Point &delta);
+    virtual void set_video_area(const Rect &rect);
     virtual bool clientsReadyForUpdate();
     virtual void tryUpdate();
     virtual void setCursor(int width, int height, const Point& hotspot,