diff options
author | Pierre Ossman <ossman@cendio.se> | 2017-01-02 19:49:52 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2017-02-10 17:05:20 +0100 |
commit | 3d74d88806d09f3a899be5d8f1df8ec20ed9a14d (patch) | |
tree | a2a86607aa8dda47559c5be82fadad9247844193 /vncviewer/DesktopWindow.cxx | |
parent | 403ac27d2377df4fed8bf5039125f6d89aaa6955 (diff) | |
download | tigervnc-3d74d88806d09f3a899be5d8f1df8ec20ed9a14d.tar.gz tigervnc-3d74d88806d09f3a899be5d8f1df8ec20ed9a14d.zip |
Render on a temporary surface when needed
Some platforms draw directly to the screen, which means that updates
will flicker if we draw multiple layers. Prevent this by first
composing the update on a hidden surface.
Diffstat (limited to 'vncviewer/DesktopWindow.cxx')
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index 707628ee..3da25054 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -34,6 +34,7 @@ #include "parameters.h" #include "vncviewer.h" #include "CConn.h" +#include "Surface.h" #include "Viewport.h" #include <FL/Fl.H> @@ -59,7 +60,7 @@ static rfb::LogWriter vlog("DesktopWindow"); DesktopWindow::DesktopWindow(int w, int h, const char *name, const rfb::PixelFormat& serverPF, CConn* cc_) - : Fl_Window(w, h), cc(cc_), firstUpdate(true), + : Fl_Window(w, h), cc(cc_), offscreen(NULL), firstUpdate(true), delayedFullscreen(false), delayedDesktopSize(false) { Fl_Group* group; @@ -183,6 +184,8 @@ DesktopWindow::~DesktopWindow() OptionsDialog::removeCallback(handleOptions); + delete offscreen; + // FLTK automatically deletes all child widgets, so we shouldn't touch // them ourselves here } @@ -263,7 +266,19 @@ void DesktopWindow::draw() { bool redraw; - int W, H; + int X, Y, W, H; + + // X11 needs an off screen buffer for compositing to avoid flicker +#if !defined(WIN32) && !defined(__APPLE__) + + // Adjust offscreen surface dimensions + if ((offscreen == NULL) || + (offscreen->width() != w()) || (offscreen->height() != h())) { + delete offscreen; + offscreen = new Surface(w(), h()); + } + +#endif // Active area inside scrollbars W = w() - (vscroll->visible() ? vscroll->w() : 0); @@ -274,30 +289,33 @@ void DesktopWindow::draw() // Redraw background only on full redraws if (redraw) { - if (viewport->h() < h()) { - fl_rectf(0, 0, W, viewport->y(), 40, 40, 40); - fl_rectf(0, viewport->y() + viewport->h(), W, - h() - (viewport->y() + viewport->h()), - 40, 40, 40); - } - if (viewport->w() < w()) { - fl_rectf(0, 0, viewport->x(), H, 40, 40, 40); - fl_rectf(viewport->x() + viewport->w(), 0, - w() - (viewport->x() + viewport->w()), - H, 40, 40, 40); - } + if (offscreen) + offscreen->clear(40, 40, 40); + else + fl_rectf(0, 0, W, H, 40, 40, 40); } // Make sure the viewport isn't trampling on the scrollbars fl_push_clip(0, 0, W, H); - if (redraw) - draw_child(*viewport); - else - update_child(*viewport); + if (offscreen) { + viewport->draw(offscreen); + viewport->clear_damage(); + } else { + if (redraw) + draw_child(*viewport); + else + update_child(*viewport); + } fl_pop_clip(); + // Flush offscreen surface to screen + if (offscreen) { + fl_clip_box(0, 0, W, H, X, Y, W, H); + offscreen->draw(X, Y, X, Y, W, H); + } + // Finally the scrollbars if (redraw) { |