From 269b61dd08b7e37445f40e3a1d0854bcf85f445b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 29 Mar 2011 11:07:49 +0200 Subject: Added preserved contents property to QWindowSurface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we used hasPartialUpdateSupport() to deduce whether the window surface's contents are preserved when flush is called or not, but that limits us from fully supporting platforms which might allow partial updates even though the surface contents aren't preserved on flush. If hasPreservedContents() returns false, that means a flush of a region is never allowed without first painting to that region. If hasPartialUpdateSupport() returns false, the whole window surface must always be painted whenever an update is requested. Note that hasPreservedContents() will typically imply hasPartialUpdateSupport(), but not vice versa. Reviewed-by: Bjørn Erik Nilsen --- src/gui/painting/qbackingstore.cpp | 4 ++-- src/gui/painting/qwindowsurface.cpp | 10 +++++++++ src/gui/painting/qwindowsurface_p.h | 1 + src/opengl/qwindowsurface_gl.cpp | 43 +++++++++++++++---------------------- src/opengl/qwindowsurface_gl_p.h | 1 + 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index e5d8abc..a06a121 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -1143,9 +1143,9 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg return; } - // If there's no partial update support we always need + // If there's no preserved contents support we always need // to do a full repaint before flushing - if (!windowSurface->hasPartialUpdateSupport()) + if (!windowSurface->hasPreservedContents()) fullUpdatePending = true; // Nothing to repaint. diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index 9b71818..050805e 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -332,6 +332,16 @@ bool QWindowSurface::hasPartialUpdateSupport() const return true; } +/*! + Says whether the window surface's contents are preserved on flush. + If not, the window surface contents need to be fully repainted before the + next flush. +*/ +bool QWindowSurface::hasPreservedContents() const +{ + return hasPartialUpdateSupport(); +} + #ifdef Q_WS_QPA #define Q_EXPORT_SCROLLRECT Q_GUI_EXPORT #else diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h index 4a2775f..95b2ee4 100644 --- a/src/gui/painting/qwindowsurface_p.h +++ b/src/gui/painting/qwindowsurface_p.h @@ -102,6 +102,7 @@ public: virtual bool hasStaticContentsSupport() const; virtual bool hasPartialUpdateSupport() const; + virtual bool hasPreservedContents() const; void setStaticContents(const QRegion ®ion); QRegion staticContents() const; diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index eae1c9b..4682d0d 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -338,7 +338,7 @@ struct QGLWindowSurfacePrivate QGLWindowSurfaceGLPaintDevice glDevice; QGLWindowSurface* q_ptr; - bool partialUpdateSupport; + bool swap_region_support; }; QGLFormat QGLWindowSurface::surfaceFormat; @@ -391,7 +391,7 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window) d_ptr->q_ptr = this; d_ptr->geometry_updated = false; d_ptr->did_paint = false; - d_ptr->partialUpdateSupport = false; + d_ptr->swap_region_support = false; } QGLWindowSurface::~QGLWindowSurface() @@ -491,22 +491,10 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) if (haveNOKSwapRegion) qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates."; } - bool swapBehaviourPreserved = (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED) - || (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT); - if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) { - EGLint swapBehavior; - if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface - , EGL_SWAP_BEHAVIOR, &swapBehavior)) { - swapBehaviourPreserved = (swapBehavior == EGL_BUFFER_PRESERVED); - } - } - if (!swapBehaviourPreserved && !haveNOKSwapRegion) - d_ptr->partialUpdateSupport = false; // Force full-screen updates - else - d_ptr->partialUpdateSupport = true; -#else - d_ptr->partialUpdateSupport = false; + d_ptr->destructive_swap_buffers = !swapBehaviourPreserved; + + d_ptr->swap_region_support = haveNOKSwapRegion; #endif widgetPrivate->extraData()->glContext = ctx; @@ -622,7 +610,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & // mistake to call swapBuffers if nothing was painted unless // EGL_BUFFER_PRESERVED is set. This check protects the flush func from // being executed if it's for nothing. - if (!hasPartialUpdateSupport() && !d_ptr->did_paint) + if (!d_ptr->destructive_swap_buffers && !d_ptr->did_paint) return; QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); @@ -698,12 +686,12 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } #endif bool doingPartialUpdate = false; - if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap) - doingPartialUpdate = hasPartialUpdateSupport() && br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2; - else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysFullSwap) - doingPartialUpdate = false; - else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap) - doingPartialUpdate = hasPartialUpdateSupport(); + if (d_ptr->swap_region_support) { + if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap) + doingPartialUpdate = br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2; + else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap) + doingPartialUpdate = true; + } QGLContext *ctx = reinterpret_cast(parent->d_func()->extraData()->glContext); if (widget != window()) { @@ -1168,10 +1156,13 @@ QImage *QGLWindowSurface::buffer(const QWidget *widget) bool QGLWindowSurface::hasPartialUpdateSupport() const { - return d_ptr->partialUpdateSupport; + return !d_ptr->destructive_swap_buffers || d_ptr->swap_region_support; } - +bool QGLWindowSurface::hasPreservedContents() const +{ + return !d_ptr->destructive_swap_buffers; +} QT_END_NAMESPACE diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h index e1689bf..cabb35a 100644 --- a/src/opengl/qwindowsurface_gl_p.h +++ b/src/opengl/qwindowsurface_gl_p.h @@ -109,6 +109,7 @@ public: QImage *buffer(const QWidget *widget); bool hasPartialUpdateSupport() const; + bool hasPreservedContents() const; QGLContext *context() const; -- cgit v0.12