diff options
author | Pierre Ossman <ossman@cendio.se> | 2014-07-09 16:44:11 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2014-07-14 16:03:41 +0200 |
commit | 0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8 (patch) | |
tree | 500f61ee230d30fa1f8e955214c698e86b69e2f4 /vncviewer | |
parent | 126e56420e47d72cc950d03976ee57d1efda436e (diff) | |
download | tigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.tar.gz tigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.zip |
Use PixelBuffer objects as the interface for encoders and decoders
This avoid a lot of unnecessary middle men. This also pushes the
responsibility for pixel format conversion into the encoders and
decoders. The new bufferFromBuffer() is used for direct conversion,
rather than PixelTransformer/TransImageGetter.
Diffstat (limited to 'vncviewer')
-rw-r--r-- | vncviewer/CConn.cxx | 27 | ||||
-rw-r--r-- | vncviewer/CConn.h | 10 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 27 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.h | 16 | ||||
-rw-r--r-- | vncviewer/PlatformPixelBuffer.cxx | 16 | ||||
-rw-r--r-- | vncviewer/PlatformPixelBuffer.h | 6 | ||||
-rw-r--r-- | vncviewer/Viewport.cxx | 114 | ||||
-rw-r--r-- | vncviewer/Viewport.h | 24 |
8 files changed, 46 insertions, 194 deletions
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx index c78bb891..305eddce 100644 --- a/vncviewer/CConn.cxx +++ b/vncviewer/CConn.cxx @@ -263,7 +263,6 @@ void CConn::serverInit() // This initial update request is a bit of a corner case, so we need // to help out setting the correct format here. assert(pendingPFChange); - desktop->setServerPF(pendingPF); cp.setPF(pendingPF); pendingPFChange = false; } @@ -330,7 +329,6 @@ void CConn::framebufferUpdateEnd() // A format change has been scheduled and we are now past the update // with the old format. Time to active the new one. if (pendingPFChange) { - desktop->setServerPF(pendingPF); cp.setPF(pendingPF); pendingPFChange = false; } @@ -405,26 +403,11 @@ void CConn::dataRect(const Rect& r, int encoding) throw Exception("Unknown rect encoding"); } } - decoders[encoding]->readRect(r, this); + decoders[encoding]->readRect(r, desktop->getFramebuffer()); sock->inStream().stopTiming(); } -void CConn::fillRect(const rfb::Rect& r, rfb::Pixel p) -{ - desktop->fillRect(r,p); -} - -void CConn::imageRect(const rfb::Rect& r, void* p) -{ - desktop->imageRect(r,p); -} - -void CConn::copyRect(const rfb::Rect& r, int sx, int sy) -{ - desktop->copyRect(r,sx,sy); -} - void CConn::setCursor(int width, int height, const Point& hotspot, void* data, void* mask) { @@ -461,18 +444,10 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[]) pf.read(&memStream); - desktop->setServerPF(pf); cp.setPF(pf); } } -rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) { - return desktop->getBufferRW(r, stride); -} -void CConn::releaseRawBuffer(const rfb::Rect& r) { - desktop->commitBufferRW(r); -} - ////////////////////// Internal methods ////////////////////// diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h index f7f560bc..709ca2f8 100644 --- a/vncviewer/CConn.h +++ b/vncviewer/CConn.h @@ -64,18 +64,8 @@ public: void framebufferUpdateStart(); void framebufferUpdateEnd(); - void dataRect(const rfb::Rect& r, int encoding); - void fillRect(const rfb::Rect& r, rfb::Pixel p); - void imageRect(const rfb::Rect& r, void* p); - void copyRect(const rfb::Rect& r, int sx, int sy); - - rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride); - void releaseRawBuffer(const rfb::Rect& r); - - const rfb::PixelFormat &getPreferredPF() { return fullColourPF; } - void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index a64f02a2..d57d57ad 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -193,12 +193,6 @@ DesktopWindow::~DesktopWindow() } -void DesktopWindow::setServerPF(const rfb::PixelFormat& pf) -{ - viewport->setServerPF(pf); -} - - const rfb::PixelFormat &DesktopWindow::getPreferredPF() { return viewport->getPreferredPF(); @@ -216,24 +210,9 @@ void DesktopWindow::setName(const char *name) } -void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) { - viewport->fillRect(r, pix); -} - -void DesktopWindow::imageRect(const rfb::Rect& r, void* pixels) { - viewport->imageRect(r, pixels); -} - -void DesktopWindow::copyRect(const rfb::Rect& r, int srcX, int srcY) { - viewport->copyRect(r, srcX, srcY); -} - -rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) { - return viewport->getBufferRW(r, stride); -} - -void DesktopWindow::commitBufferRW(const rfb::Rect& r) { - viewport->commitBufferRW(r); +rfb::ModifiablePixelBuffer* DesktopWindow::getFramebuffer(void) +{ + return viewport->getFramebuffer(); } diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h index 83a8c767..8b91450f 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -27,6 +27,8 @@ #include <FL/Fl_Window.H> +namespace rfb { class ModifiablePixelBuffer; } + class CConn; class Viewport; @@ -39,26 +41,22 @@ public: const rfb::PixelFormat& serverPF, CConn* cc_); ~DesktopWindow(); - // PixelFormat of incoming write operations - void setServerPF(const rfb::PixelFormat& pf); // Most efficient format (from DesktopWindow's point of view) const rfb::PixelFormat &getPreferredPF(); // Flush updates to screen void updateWindow(); - // Methods forwarded from CConn + // Updated session title void setName(const char *name); - void fillRect(const rfb::Rect& r, rfb::Pixel pix); - void imageRect(const rfb::Rect& r, void* pixels); - void copyRect(const rfb::Rect& r, int srcX, int srcY); - - rdr::U8* getBufferRW(const rfb::Rect& r, int* stride); - void commitBufferRW(const rfb::Rect& r); + // Return a pointer to the framebuffer for decoders to write into + rfb::ModifiablePixelBuffer* getFramebuffer(void); + // Resize the current framebuffer, but retain the contents void resizeFramebuffer(int new_w, int new_h); + // New image for the locally rendered cursor void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx index ced04467..5bd50d2c 100644 --- a/vncviewer/PlatformPixelBuffer.cxx +++ b/vncviewer/PlatformPixelBuffer.cxx @@ -24,3 +24,19 @@ PlatformPixelBuffer::PlatformPixelBuffer(const rfb::PixelFormat& pf, FullFramePixelBuffer(pf, width, height, data, stride) { } + +void PlatformPixelBuffer::commitBufferRW(const rfb::Rect& r) +{ + FullFramePixelBuffer::commitBufferRW(r); + damage.assign_union(rfb::Region(r)); +} + +rfb::Rect PlatformPixelBuffer::getDamage(void) +{ + rfb::Rect r; + + r = damage.get_bounding_rect(); + damage.clear(); + + return r; +} diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h index 03842ac8..21b93be4 100644 --- a/vncviewer/PlatformPixelBuffer.h +++ b/vncviewer/PlatformPixelBuffer.h @@ -20,14 +20,20 @@ #define __PLATFORMPIXELBUFFER_H__ #include <rfb/PixelBuffer.h> +#include <rfb/Region.h> class PlatformPixelBuffer: public rfb::FullFramePixelBuffer { public: PlatformPixelBuffer(const rfb::PixelFormat& pf, int width, int height, rdr::U8* data, int stride); + virtual void commitBufferRW(const rfb::Rect& r); + virtual void draw(int src_x, int src_y, int x, int y, int w, int h) = 0; + rfb::Rect getDamage(void); +protected: + rfb::Region damage; }; #endif diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 70964b76..cd8b1bc3 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -27,7 +27,6 @@ #include <rfb/CMsgWriter.h> #include <rfb/LogWriter.h> -#include <rfb/PixelTransformer.h> // FLTK can pull in the X11 headers on some systems #ifndef XK_VoidSymbol @@ -84,7 +83,7 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_RESIZE, ID_REFRESH, ID_OPTIONS, ID_INFO, ID_ABOUT, ID_DISMISS }; Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_) - : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL), + : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), lastPointerPos(0, 0), lastButtonMask(0), cursor(NULL), menuCtrlKey(false), menuAltKey(false) { @@ -101,8 +100,6 @@ Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_) frameBuffer = createFramebuffer(w, h); assert(frameBuffer); - setServerPF(serverPF); - contextMenu = new Fl_Menu_Button(0, 0, 0, 0); // Setting box type to FL_NO_BOX prevents it from trying to draw the // button component (which we don't want) @@ -130,7 +127,6 @@ Viewport::~Viewport() { // Unregister all timeouts in case they get a change tro trigger // again later when this object is already gone. - Fl::remove_timeout(handleUpdateTimeout, this); Fl::remove_timeout(handlePointerTimeout, this); #ifdef HAVE_FLTK_CLIPBOARD @@ -141,9 +137,6 @@ Viewport::~Viewport() delete frameBuffer; - if (pixelTrans) - delete pixelTrans; - if (cursor) { if (!cursor->alloc_array) delete [] cursor->array; @@ -155,40 +148,6 @@ Viewport::~Viewport() } -void Viewport::setServerPF(const rfb::PixelFormat& pf) -{ - if (pixelTrans) - delete pixelTrans; - pixelTrans = NULL; - - if (pf.equal(getPreferredPF())) - return; - - pixelTrans = new PixelTransformer(); - - // FIXME: This is an ugly (temporary) hack to get around a corner - // case during startup. The conversion routines cannot handle - // non-native source formats, and we can sometimes get that - // as the initial format. We will switch to a better format - // before getting any updates, but we need something for now. - // Our old client used something completely bogus and just - // hoped nothing would ever go wrong. We try to at least match - // the pixel size so that we don't get any memory access issues - // should a stray update appear. - static rdr::U32 endianTest = 1; - static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1; - if ((pf.bpp > 8) && (pf.bigEndian != nativeBigEndian)) { - PixelFormat fake_pf(pf.bpp, pf.depth, nativeBigEndian, pf.trueColour, - pf.redMax, pf.greenMax, pf.blueMax, - pf.redShift, pf.greenShift, pf.blueShift); - pixelTrans->init(fake_pf, getPreferredPF()); - return; - } - - pixelTrans->init(pf, getPreferredPF()); -} - - const rfb::PixelFormat &Viewport::getPreferredPF() { return frameBuffer->getPF(); @@ -197,65 +156,21 @@ const rfb::PixelFormat &Viewport::getPreferredPF() // Copy the areas of the framebuffer that have been changed (damaged) // to the displayed window. +// FIXME: Make sure this gets called on slow updates void Viewport::updateWindow() { Rect r; - Fl::remove_timeout(handleUpdateTimeout, this); - - r = damage.get_bounding_rect(); - Fl_Widget::damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height()); - - damage.clear(); -} - -void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) { - if (pixelTrans) { - rfb::Pixel pix2; - pixelTrans->translatePixels(&pix, &pix2, 1); - pix = pix2; - } - - frameBuffer->fillRect(r, pix); - damageRect(r); + r = frameBuffer->getDamage(); + damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height()); } -void Viewport::imageRect(const rfb::Rect& r, void* pixels) { - if (pixelTrans) { - rdr::U8* buffer; - int stride; - buffer = frameBuffer->getBufferRW(r, &stride); - pixelTrans->translateRect(pixels, r.width(), - rfb::Rect(0, 0, r.width(), r.height()), - buffer, stride, rfb::Point(0, 0)); - frameBuffer->commitBufferRW(r); - } else { - frameBuffer->imageRect(r, pixels); - } - damageRect(r); -} - -void Viewport::copyRect(const rfb::Rect& r, int srcX, int srcY) { - frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY)); - damageRect(r); -} - -rdr::U8* Viewport::getBufferRW(const rfb::Rect& r, int* stride) { - return frameBuffer->getBufferRW(r, stride); -} - -void Viewport::commitBufferRW(const rfb::Rect& r) { - frameBuffer->commitBufferRW(r); - damageRect(r); +rfb::ModifiablePixelBuffer* Viewport::getFramebuffer(void) +{ + return frameBuffer; } -void Viewport::damageRect(const rfb::Rect& r) { - damage.assign_union(rfb::Region(r)); - if (!Fl::has_timeout(handleUpdateTimeout, this)) - Fl::add_timeout(0.500, handleUpdateTimeout, this); -}; - #ifdef HAVE_FLTK_CURSOR static const char * dotcursor_xpm[] = { "5 5 2 1", @@ -303,10 +218,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot, const PixelFormat *pf; - if (pixelTrans) - pf = &pixelTrans->getInPF(); - else - pf = &frameBuffer->getPF(); + pf = &cc->cp.pf(); i = (U8*)data; o = buffer; @@ -530,16 +442,6 @@ PlatformPixelBuffer* Viewport::createFramebuffer(int w, int h) } -void Viewport::handleUpdateTimeout(void *data) -{ - Viewport *self = (Viewport *)data; - - assert(self); - - self->updateWindow(); -} - - void Viewport::handleClipboardChange(int source, void *data) { Viewport *self = (Viewport *)data; diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h index e112efda..0523cd14 100644 --- a/vncviewer/Viewport.h +++ b/vncviewer/Viewport.h @@ -22,10 +22,9 @@ #include <map> -#include <FL/Fl_Widget.H> +namespace rfb { class ModifiablePixelBuffer; } -#include <rfb/Region.h> -#include <rfb/Pixel.h> +#include <FL/Fl_Widget.H> class Fl_Menu_Button; class Fl_RGB_Image; @@ -41,23 +40,16 @@ public: Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_); ~Viewport(); - // PixelFormat of incoming write operations - void setServerPF(const rfb::PixelFormat& pf); // Most efficient format (from Viewport's point of view) const rfb::PixelFormat &getPreferredPF(); // Flush updates to screen void updateWindow(); - // Methods forwarded from CConn - - void fillRect(const rfb::Rect& r, rfb::Pixel pix); - void imageRect(const rfb::Rect& r, void* pixels); - void copyRect(const rfb::Rect& r, int srcX, int srcY); - - rdr::U8* getBufferRW(const rfb::Rect& r, int* stride); - void commitBufferRW(const rfb::Rect& r); + // Return a pointer to the framebuffer for decoders to write into + rfb::ModifiablePixelBuffer* getFramebuffer(void); + // New image for the locally rendered cursor void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); @@ -71,12 +63,8 @@ public: private: - void damageRect(const rfb::Rect& r); - PlatformPixelBuffer* createFramebuffer(int w, int h); - static void handleUpdateTimeout(void *data); - static void handleClipboardChange(int source, void *data); void handlePointerEvent(const rfb::Point& pos, int buttonMask); @@ -96,8 +84,6 @@ private: CConn* cc; PlatformPixelBuffer* frameBuffer; - rfb::PixelTransformer *pixelTrans; - rfb::Region damage; rfb::Point lastPointerPos; int lastButtonMask; |