Revision: 4800 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4800&view=rev Author: ossman_ Date: 2011-11-14 16:02:06 +0000 (Mon, 14 Nov 2011) Log Message: ----------- Support and use fences in the client. This allows more aggressive use of update requests as we can now synchronise format changes.
Modified Paths: -------------- trunk/vncviewer/CConn.cxx trunk/vncviewer/CConn.h Modified: trunk/vncviewer/CConn.cxx =================================================================== --- trunk/vncviewer/CConn.cxx 2011-11-14 15:54:30 UTC (rev 4799) +++ trunk/vncviewer/CConn.cxx 2011-11-14 16:02:06 UTC (rev 4800) @@ -33,7 +33,10 @@ #include <rfb/LogWriter.h> #include <rfb/util.h> #include <rfb/screenTypes.h> +#include <rfb/fenceTypes.h> #include <rfb/Timer.h> +#include <rdr/MemInStream.h> +#include <rdr/MemOutStream.h> #include <network/TcpSocket.h> #include <FL/Fl.H> @@ -70,7 +73,7 @@ currentEncoding(encodingTight), lastServerEncoding((unsigned int)-1), formatChange(false), encodingChange(false), firstUpdate(true), pendingUpdate(false), - forceNonincremental(true) + forceNonincremental(true), supportsSyncFence(false) { setShared(::shared); @@ -130,10 +133,12 @@ void CConn::refreshFramebuffer() { - // FIXME: We cannot safely trigger an update request directly but must - // wait for the next update to arrive. - if (!formatChange) - forceNonincremental = true; + forceNonincremental = true; + + // Without fences, we cannot safely trigger an update request directly + // but must wait for the next update to arrive. + if (supportsSyncFence) + requestNewUpdate(); } const char *CConn::connectionInfo() @@ -284,6 +289,7 @@ // one. void CConn::framebufferUpdateStart() { + // Note: This might not be true if sync fences are supported pendingUpdate = false; requestNewUpdate(); @@ -300,6 +306,11 @@ if (firstUpdate) { int width, height; + // We need fences to make extra update requests "safe". + // See fence() for the next step. + if (cp.supportsFence) + writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, 0, NULL); + if (cp.supportsSetDesktopSize && sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) == 2) { ScreenSet layout; @@ -423,6 +434,34 @@ desktop->setCursor(width, height, hotspot, data, mask); } +void CConn::fence(rdr::U32 flags, unsigned len, const char data[]) +{ + CMsgHandler::fence(flags, len, data); + + if (flags & fenceFlagRequest) { + // We handle everything synchronously so we trivially honor these modes + flags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter); + + writer()->writeFence(flags, len, data); + return; + } + + if (len == 0) { + // Initial probe + if (flags & fenceFlagSyncNext) + supportsSyncFence = true; + } else { + // Pixel format change + rdr::MemInStream memStream(data, len); + PixelFormat pf; + + pf.read(&memStream); + + desktop->setServerPF(pf); + cp.setPF(pf); + } +} + rdr::U8* CConn::getRawPixelsRW(const rfb::Rect& r, int* stride) { return desktop->getPixelsRW(r, stride); } @@ -529,7 +568,7 @@ PixelFormat pf; /* Catch incorrect requestNewUpdate calls */ - assert(pendingUpdate == false); + assert(!pendingUpdate || supportsSyncFence); if (fullColour) { pf = fullColourPF; @@ -542,12 +581,24 @@ pf = mediumColourPF; } - // New requests are sent out at the start of processing the last - // one, so we cannot switch our internal format right now (doing so - // would mean misdecoding the current update). - pendingPFChange = true; - pendingPF = pf; + if (supportsSyncFence) { + // We let the fence carry the pixel format and switch once we + // get the response back. That way we will be synchronised with + // when the server switches. + rdr::MemOutStream memStream; + pf.write(&memStream); + + writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, + memStream.length(), (const char*)memStream.data()); + } else { + // New requests are sent out at the start of processing the last + // one, so we cannot switch our internal format right now (doing so + // would mean misdecoding the current update). + pendingPFChange = true; + pendingPF = pf; + } + char str[256]; pf.print(str, 256); vlog.info(_("Using pixel format %s"),str); @@ -607,6 +658,12 @@ pf = mediumColourPF; } - if (!pf.equal(self->cp.pf())) + if (!pf.equal(self->cp.pf())) { self->formatChange = true; + + // Without fences, we cannot safely trigger an update request directly + // but must wait for the next update to arrive. + if (self->supportsSyncFence) + self->requestNewUpdate(); + } } Modified: trunk/vncviewer/CConn.h =================================================================== --- trunk/vncviewer/CConn.h 2011-11-14 15:54:30 UTC (rev 4799) +++ trunk/vncviewer/CConn.h 2011-11-14 16:02:06 UTC (rev 4800) @@ -75,6 +75,8 @@ void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); + void fence(rdr::U32 flags, unsigned len, const char data[]); + private: void resizeFramebuffer(); @@ -107,6 +109,8 @@ bool pendingUpdate; bool forceNonincremental; + + bool supportsSyncFence; }; #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ RSA(R) Conference 2012 Save $700 by Nov 18 Register now http://p.sf.net/sfu/rsa-sfdev2dev1 _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits