I thought I'd have a look at double buffering and it turned out to be a lot simpler than I first thought.
Basically, the current code updates a local copy of the framebuffer, and at the same time copies it to the X window. This is done on every graphic operation. The included patch changes the system to just update the backing store. Once the entire framebuffer update is over, it copies the entire modified area to the X window. This avoids tearing and gives a much more pleasant experience. The downsides with my patch is: - we'll be doing blits from the backing store even for CopyRect. - we'll be shuffling more data to the X server than before since we'll be copying the bounding box of the changes, and not just the changes. - we won't see the screen updating progressively on a slow connection I plan to fix the last one by using a timer, and I think the other two are acceptable losses to get rid of the tearing. What do you think? Rgds -- Pierre Ossman OpenSource-based Thin Client Technology System Developer Telephone: +46-13-21 46 00 Cendio AB Web: http://www.cendio.com
Index: vncviewer/DesktopWindow.h =================================================================== --- vncviewer/DesktopWindow.h (revision 3714) +++ vncviewer/DesktopWindow.h (working copy) @@ -24,6 +24,7 @@ #include <rfb/Cursor.h> #include <rfb/Rect.h> +#include <rfb/Region.h> #include <rfb/Timer.h> #include "TXWindow.h" #include "TXViewport.h" @@ -61,13 +62,13 @@ void fillRect(const rfb::Rect& r, rfb::Pixel pix) { if (r.overlaps(cursorBackingRect)) hideLocalCursor(); im->fillRect(r, pix); - im->put(win(), gc, r); + damageRect(r); showLocalCursor(); } void imageRect(const rfb::Rect& r, void* pixels) { if (r.overlaps(cursorBackingRect)) hideLocalCursor(); im->imageRect(r, pixels); - im->put(win(), gc, r); + damageRect(r); showLocalCursor(); } void copyRect(const rfb::Rect& r, int srcX, int srcY) { @@ -75,11 +76,8 @@ cursorBackingRect.overlaps(rfb::Rect(srcX, srcY, srcX+r.width(), srcY+r.height()))) hideLocalCursor(); - if (im->usingShm()) - XSync(dpy, False); im->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY)); - XCopyArea(dpy, win(), win(), gc, srcX, srcY, - r.width(), r.height(), r.tl.x, r.tl.y); + damageRect(r); showLocalCursor(); } void invertRect(const rfb::Rect& r); @@ -97,12 +95,14 @@ void createXCursors(); void hideLocalCursor(); void showLocalCursor(); + void damageRect(const rfb::Rect& r) { damage.assign_union(rfb::Region(r)); }; bool handleTimeout(rfb::Timer* timer); void handlePointerEvent(const rfb::Point& pos, int buttonMask); CConn* cc; TXImage* im; GC gc; + rfb::Region damage; ::Cursor dotCursor, noCursor, localXCursor; rfb::Cursor cursor; Index: vncviewer/DesktopWindow.cxx =================================================================== --- vncviewer/DesktopWindow.cxx (revision 3714) +++ vncviewer/DesktopWindow.cxx (working copy) @@ -216,7 +216,6 @@ if (cursorVisible) { cursorVisible = false; im->imageRect(cursorBackingRect, cursorBacking.data); - im->put(win(), gc, cursorBackingRect); } } @@ -238,7 +237,6 @@ im->getImage(cursorBacking.data, cursorBackingRect); im->maskRect(cursorRect, cursor.data, cursor.mask.buf); - im->put(win(), gc, cursorBackingRect); } } @@ -278,7 +276,13 @@ void DesktopWindow::framebufferUpdateEnd() { - XSync(dpy, False); + Rect r; + + r = damage.get_bounding_rect(); + damage.clear(); + + fprintf(stderr, "Updating %dx%d+%d+%d\n", r.width(), r.height(), r.tl.x, r.tl.y); + im->put(win(), gc, r); } @@ -297,7 +301,7 @@ } } } - im->put(win(), gc, r); + damageRect(r); }
signature.asc
Description: PGP signature
------------------------------------------------------------------------------ Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________ Tigervnc-devel mailing list Tigervnc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-devel