summaryrefslogtreecommitdiffstats
path: root/src/opengl/qwindowsurface_gl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qwindowsurface_gl.cpp')
-rw-r--r--src/opengl/qwindowsurface_gl.cpp105
1 files changed, 39 insertions, 66 deletions
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 238d127..b48fe2c 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -184,7 +184,7 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
class QGLGlobalShareWidget
{
public:
- QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {}
+ QGLGlobalShareWidget() : widget(0), initializing(false) {}
QGLWidget *shareWidget() {
if (!initializing && !widget && !cleanedUp) {
@@ -224,9 +224,6 @@ public:
static bool cleanedUp;
- QGLPixmapData *firstPixmap;
- int widgetRefCount;
-
private:
QGLWidget *widget;
bool initializing;
@@ -257,43 +254,6 @@ void qt_destroy_gl_share_widget()
_qt_gl_share_widget()->destroy();
}
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd)
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_gl_unregister_pixmap(QGLPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-void qt_gl_hibernate_pixmaps()
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
-
- // Scan all QGLPixmapData objects in the system and hibernate them.
- QGLPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-}
-#endif
-
struct QGLWindowSurfacePrivate
{
QGLFramebufferObject *fbo;
@@ -393,22 +353,10 @@ QGLWindowSurface::~QGLWindowSurface()
if (QGLGlobalShareWidget::cleanedUp)
return;
- --(_qt_gl_share_widget()->widgetRefCount);
-
-#ifdef QGL_USE_TEXTURE_POOL
- if (_qt_gl_share_widget()->widgetRefCount <= 0) {
- // All of the widget window surfaces have been destroyed
- // but we still have GL pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_gl_hibernate_pixmaps();
-
+#ifdef Q_OS_SYMBIAN
// Destroy the context if necessary.
if (!qt_gl_share_widget()->context()->isSharing())
qt_destroy_gl_share_widget();
- }
#endif
}
@@ -457,9 +405,6 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
ctx->create(qt_gl_share_widget()->context());
- if (widget != qt_gl_share_widget())
- ++(_qt_gl_share_widget()->widgetRefCount);
-
#ifndef QT_NO_EGL
static bool checkedForNOKSwapRegion = false;
static bool haveNOKSwapRegion = false;
@@ -495,6 +440,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
voidPtr = &widgetPrivate->extraData()->glContext;
d_ptr->contexts << ctxPtr;
+
#ifndef Q_OS_SYMBIAN
qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
#endif
@@ -765,6 +711,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
} else {
+#ifndef Q_OS_SYMBIAN // We don't have FBO pool on Symbian
// can't do sub-region blits with multisample FBOs
QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat());
@@ -787,6 +734,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
qgl_fbo_pool()->release(temp);
+#endif // Q_OS_SYMBIAN
}
ctx->d_ptr->current_fbo = 0;
@@ -869,18 +817,43 @@ void QGLWindowSurface::updateGeometry() {
if (wd->extraData() && wd->extraData()->glContext) {
#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
if (d_ptr->size != geometry().size()) {
- if (window() != qt_gl_share_widget())
- --(_qt_gl_share_widget()->widgetRefCount);
+ QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
+
+ if (ctx == QGLContext::currentContext())
+ ctx->doneCurrent();
+
+ ctx->d_func()->destroyEglSurfaceForDevice();
- delete wd->extraData()->glContext;
- wd->extraData()->glContext = 0;
- d_ptr->ctx = 0;
+ // Delete other contexts (shouldn't happen too often, if at all)
+ while (d_ptr->contexts.size()) {
+ QGLContext **ctxPtrPtr = d_ptr->contexts.takeFirst();
+ if ((*ctxPtrPtr) != ctx)
+ delete *ctxPtrPtr;
+ }
+ union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
+ voidPtrPtr = &wd->extraData()->glContext;
+ d_ptr->contexts << ctxPtrPtr;
+
+ ctx->d_func()->eglSurface = ctx->d_func()->eglContext->createSurface(window());
+
+ // Partial update supported has been decided already in previous hijackWindow call.
+ // Reset swap behaviour based on that flag.
+ if (hasPartialUpdateSupport()) {
+ eglSurfaceAttrib(QEgl::display(), ctx->d_func()->eglSurfaceForDevice(),
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLWindowSurface::updateGeometry() - could not re-enable preserved swap behaviour");
+ } else {
+ eglSurfaceAttrib(QEgl::display(), ctx->d_func()->eglSurfaceForDevice(),
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLWindowSurface::updateGeometry() - could not re-enable destroyed swap behaviour");
+ }
}
- else
#endif
- {
- hijack = false; // we already have gl context for widget
- }
+ hijack = false; // we already have gl context for widget
}
if (hijack)