src/opengl/qgl_egl.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   136     format.setBlueBufferSize(blueSize);
   136     format.setBlueBufferSize(blueSize);
   137     format.setAlphaBufferSize(alphaSize);
   137     format.setAlphaBufferSize(alphaSize);
   138     format.setDepthBufferSize(depthSize);
   138     format.setDepthBufferSize(depthSize);
   139     format.setStencilBufferSize(stencilSize);
   139     format.setStencilBufferSize(stencilSize);
   140     format.setSamples(sampleCount);
   140     format.setSamples(sampleCount);
   141     format.setPlane(level + 1);      // EGL calls level 0 "normal" whereas Qt calls 1 "normal"
   141     format.setPlane(level);
   142     format.setDirectRendering(true); // All EGL contexts are direct-rendered
   142     format.setDirectRendering(true); // All EGL contexts are direct-rendered
   143     format.setRgba(true);            // EGL doesn't support colour index rendering
   143     format.setRgba(true);            // EGL doesn't support colour index rendering
   144     format.setStereo(false);         // EGL doesn't support stereo buffers
   144     format.setStereo(false);         // EGL doesn't support stereo buffers
   145     format.setAccumBufferSize(0);    // EGL doesn't support accululation buffers
   145     format.setAccumBufferSize(0);    // EGL doesn't support accululation buffers
   146 
   146 
   188     if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) {
   188     if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) {
   189         QGLContextPrivate::setCurrentContext(this);
   189         QGLContextPrivate::setCurrentContext(this);
   190         if (!d->workaroundsCached) {
   190         if (!d->workaroundsCached) {
   191             d->workaroundsCached = true;
   191             d->workaroundsCached = true;
   192             const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
   192             const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
   193             if (strstr(renderer, "SGX") || strstr(renderer, "MBX")) {
   193             if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
   194                 // PowerVR MBX/SGX chips needs to clear all buffers when starting to render
   194                 // PowerVR MBX/SGX chips needs to clear all buffers when starting to render
   195                 // a new frame, otherwise there will be a performance penalty to pay for
   195                 // a new frame, otherwise there will be a performance penalty to pay for
   196                 // each frame.
   196                 // each frame.
   197                 d->workaround_needsFullClearOnEveryFrame = true;
   197                 d->workaround_needsFullClearOnEveryFrame = true;
   198 
   198 
   199                 // Older PowerVR SGX drivers (like the one in the N900) have a
   199                 // Older PowerVR SGX drivers (like the one in the N900) have a
   200                 // bug which prevents glCopyTexSubImage2D() to work with a POT
   200                 // bug which prevents glCopyTexSubImage2D() to work with a POT
   201                 // or GL_ALPHA texture bound to an FBO. The only way to
   201                 // or GL_ALPHA texture bound to an FBO. The only way to
   202                 // identify that driver is to check the EGL version number for it.
   202                 // identify that driver is to check the EGL version number for it.
   203                 if (strstr(eglQueryString(d->eglContext->display(), EGL_VERSION), "1.3"))
   203                 const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION);
       
   204                 if (egl_version && strstr(egl_version, "1.3"))
   204                     d->workaround_brokenFBOReadBack = true;
   205                     d->workaround_brokenFBOReadBack = true;
   205             }
   206             }
   206         }
   207         }
   207     }
   208     }
   208 }
   209 }
   229 void QGLContextPrivate::destroyEglSurfaceForDevice()
   230 void QGLContextPrivate::destroyEglSurfaceForDevice()
   230 {
   231 {
   231     if (eglSurface != EGL_NO_SURFACE) {
   232     if (eglSurface != EGL_NO_SURFACE) {
   232 #ifdef Q_WS_X11
   233 #ifdef Q_WS_X11
   233         // Make sure we don't call eglDestroySurface on a surface which
   234         // Make sure we don't call eglDestroySurface on a surface which
   234         // was created for a different winId:
   235         // was created for a different winId. This applies only to QGLWidget
       
   236         // paint device, so make sure this is the one we're operating on
       
   237         // (as opposed to a QGLWindowSurface use case).
   235         if (paintDevice && paintDevice->devType() == QInternal::Widget) {
   238         if (paintDevice && paintDevice->devType() == QInternal::Widget) {
   236             QGLWidget* w = static_cast<QGLWidget*>(paintDevice);
   239             QWidget *w = static_cast<QWidget *>(paintDevice);
   237 
   240             if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) {
   238             if (w->d_func()->eglSurfaceWindowId == w->winId())
   241                 if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) {
   239                 eglDestroySurface(eglContext->display(), eglSurface);
   242                     qWarning("WARNING: Potential EGL surface leak! Not destroying surface.");
   240             else
   243                     return;
   241                 qWarning("WARNING: Potential EGL surface leak!");
   244                 }
   242         } else
   245             }
       
   246         }
   243 #endif
   247 #endif
   244             eglDestroySurface(eglContext->display(), eglSurface);
   248         eglDestroySurface(eglContext->display(), eglSurface);
   245         eglSurface = EGL_NO_SURFACE;
   249         eglSurface = EGL_NO_SURFACE;
   246     }
   250     }
   247 }
   251 }
   248 
   252 
   249 EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
   253 EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
   268     }
   272     }
   269 
   273 
   270     return eglSurface;
   274     return eglSurface;
   271 }
   275 }
   272 
   276 
       
   277 void QGLContextPrivate::swapRegion(const QRegion *region)
       
   278 {
       
   279     if (!valid || !eglContext)
       
   280         return;
       
   281 
       
   282     eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), region);
       
   283 }
       
   284 
   273 void QGLWidget::setMouseTracking(bool enable)
   285 void QGLWidget::setMouseTracking(bool enable)
   274 {
   286 {
   275     QWidget::setMouseTracking(enable);
   287     QWidget::setMouseTracking(enable);
   276 }
   288 }
   277 
   289