From: Constantin Kaplinsky Date: Thu, 4 Oct 2007 06:02:02 +0000 (+0000) Subject: New polling algorithm has been implemented. Video detection is not included in this... X-Git-Tag: v0.0.90~384^2~124 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a119b48c037a065fd2a5dafc556ada332a0d2f71;p=tigervnc.git New polling algorithm has been implemented. Video detection is not included in this version though. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2342 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/unix/x0vncserver/PollingManager.cxx b/unix/x0vncserver/PollingManager.cxx index 45b0fef3..b07750e3 100644 --- a/unix/x0vncserver/PollingManager.cxx +++ b/unix/x0vncserver/PollingManager.cxx @@ -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) diff --git a/unix/x0vncserver/PollingManager.h b/unix/x0vncserver/PollingManager.h index 58c16f99..a67901be 100644 --- a/unix/x0vncserver/PollingManager.h +++ b/unix/x0vncserver/PollingManager.h @@ -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); }