]> source.dussan.org Git - tigervnc.git/commitdiff
New polling algorithm has been implemented. Video detection is not included in this...
authorConstantin Kaplinsky <const@tightvnc.com>
Thu, 4 Oct 2007 06:02:02 +0000 (06:02 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Thu, 4 Oct 2007 06:02:02 +0000 (06:02 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2342 3789f03b-4d11-0410-bbf8-ca57d06f2519

unix/x0vncserver/PollingManager.cxx
unix/x0vncserver/PollingManager.h

index 45b0fef30e834655cee72b6ff72de55b0d0c78e4..b07750e30308160453d52367d2c10569c49683ff 100644 (file)
@@ -43,8 +43,8 @@ BoolParameter PollingManager::pollPointer
 
 IntParameter PollingManager::pollingType
 ("PollingType",
- "DEBUG: Select particular polling algorithm (0..3)",
3);
+ "DEBUG: Select particular polling algorithm (0..4)",
4);
 
 const int PollingManager::m_pollingOrder[32] = {
    0, 16,  8, 24,  4, 20, 12, 28,
@@ -204,10 +204,13 @@ void PollingManager::poll()
   case 2:
     changes1 = poll_SkipCycles();
     break;
-//case 3:
-  default:
+  case 3:
     changes1 = poll_DetectVideo();
     break;
+//case 4:
+  default:
+    changes1 = poll_New();
+    break;
   }
 
   // Second step: optional thorough polling of the area around the pointer.
@@ -233,6 +236,76 @@ void PollingManager::poll()
 #endif
 }
 
+bool PollingManager::poll_New()
+{
+  if (!m_server)
+    return false;
+
+  // Resource allocation.
+  bool *mxChanged = new bool[m_widthTiles * m_heightTiles];
+  memset(mxChanged, 0, m_widthTiles * m_heightTiles);
+
+  // Handy shortcuts.
+  int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+  int bytesPerLine = m_image->xim->bytes_per_line;
+
+  // Fill in the mxChanged[] array.
+  int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+  int nTilesChanged = 0;
+  for (int y = 0; y < m_heightTiles; y++) {
+    int tile_h = (m_height - y * 32 >= 32) ? 32 : m_height - y * 32;
+    if (scanLine >= tile_h)
+      break;
+    int scan_y = y * 32 + scanLine;
+    getRow(scan_y);
+    char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+    char *ptr_new = m_rowImage->xim->data;
+    for (int x = 0; x < m_widthTiles; x++) {
+      int tile_w = (m_width - x * 32 >= 32) ? 32 : m_width - x * 32;
+      int nBytes = tile_w * bytesPerPixel;
+      if (memcmp(ptr_old, ptr_new, nBytes)) {
+        mxChanged[y * m_widthTiles + x] = true;
+        nTilesChanged++;
+      }
+      ptr_old += nBytes;
+      ptr_new += nBytes;
+    }
+  }
+
+  // Inform the server about the changes.
+  if (nTilesChanged) {
+    bool *pmxChanged = mxChanged;
+    Rect rect;
+    for (int y = 0; y < m_heightTiles; y++) {
+      for (int x = 0; x < m_widthTiles; x++) {
+        if (*pmxChanged++) {
+          // Count successive tiles marked as changed.
+          int count = 1;
+          while (x + count < m_widthTiles && *pmxChanged++) {
+            count++;
+          }
+          // Compute the coordinates and the size of this band.
+          rect.setXYWH(x * 32, y * 32, count * 32, 32);
+          if (rect.br.x > m_width)
+            rect.br.x = m_width;
+          if (rect.br.y > m_height)
+            rect.br.y = m_height;
+          // Add to the changed region maintained by the server.
+          getScreenRect(rect);
+          m_server->add_changed(rect);
+          // Skip processed tiles.
+          x += count;
+        }
+      }
+    }
+  }
+
+  // Cleanup.
+  delete[] mxChanged;
+
+  return (nTilesChanged != 0);
+}
+
 bool PollingManager::poll_DetectVideo()
 {
   if (!m_server)
index 58c16f990b3f3b28622bcee92f6efa1a7709c489..a67901be1cab13564199a4f994b6f1e654a5125e 100644 (file)
@@ -59,6 +59,7 @@ protected:
   // Implementations of different polling algorithms.
   // Return value of true reports that some changes were detected.
   //
+  bool poll_New();
   bool poll_DetectVideo();
   bool poll_SkipCycles();
   bool poll_Traditional();
@@ -90,6 +91,12 @@ private:
     m_image->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop);
   }
 
+  inline void getScreenRect(const Rect& r) {
+    m_image->get(DefaultRootWindow(m_dpy),
+                 m_offsetLeft + r.tl.x, m_offsetTop + r.tl.y,
+                 r.width(), r.height(), r.tl.x, r.tl.y);
+  }
+
   inline void getRow(int y) {
     m_rowImage->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop + y);
   }