diff options
Diffstat (limited to 'src/opengl/qwindowsurface_gl.cpp')
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 105 |
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) |