diff options
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 8 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 6 | ||||
-rw-r--r-- | src/opengl/qgl_egl.cpp | 98 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 2 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 2 | ||||
-rw-r--r-- | src/opengl/qgl_x11egl.cpp | 120 | ||||
-rw-r--r-- | src/opengl/qgraphicssystem_gl.cpp | 1 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_egl.cpp | 162 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_p.h | 9 |
9 files changed, 166 insertions, 242 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 25ad5d7..2b5f2f4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1641,7 +1641,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp s->matrix = old; } -void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints) +void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints) { Q_D(QGL2PaintEngineEx); // Use fallback for extended composition modes. @@ -1655,9 +1656,9 @@ void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, } -void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::Fragment *fragments, +void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QPainter::FragmentHints hints) + QPainter::PixmapFragmentHints hints) { GLfloat dx = 1.0f / pixmap.size().width(); GLfloat dy = 1.0f / pixmap.size().height(); @@ -1867,6 +1868,7 @@ bool QGL2PaintEngineEx::end() delete d->shaderManager; d->shaderManager = 0; + d->currentBrush = QBrush(); #ifdef QT_OPENGL_CACHE_AS_VBOS if (!d->unusedVBOSToClean.isEmpty()) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 5d3608b..ed8fbbc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -125,7 +125,8 @@ public: virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints); + virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor); virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); @@ -196,7 +197,8 @@ public: void fill(const QVectorPath &path); void stroke(const QVectorPath &path, const QPen &pen); void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); - void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints); + void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem, bool includeMatrixInCache); diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 7bfcf27..3d146b7 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -53,35 +53,62 @@ QT_BEGIN_NAMESPACE void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat) { - // NOTE: QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that - // type has been requested. - if (glFormat.depth()) { - int depthSize = glFormat.depthBufferSize(); - eglProperties.setValue(EGL_DEPTH_SIZE, depthSize == -1 ? 1 : depthSize); + int redSize = glFormat.redBufferSize(); + int greenSize = glFormat.greenBufferSize(); + int blueSize = glFormat.blueBufferSize(); + int alphaSize = glFormat.alphaBufferSize(); + int depthSize = glFormat.depthBufferSize(); + int stencilSize = glFormat.stencilBufferSize(); + int sampleCount = glFormat.samples(); + + // QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that + // type has been requested. So we must check QGLFormat's booleans too if size is -1: + if (glFormat.alpha() && alphaSize <= 0) { + qDebug("QGLFormat::alpha() returned true"); + alphaSize = 1; } - if (glFormat.stencil()) { - int stencilSize = glFormat.stencilBufferSize(); - eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize == -1 ? 1 : stencilSize); - } - if (glFormat.sampleBuffers()) { - int sampleCount = glFormat.samples(); - eglProperties.setValue(EGL_SAMPLES, sampleCount == -1 ? 1 : sampleCount); - eglProperties.setValue(EGL_SAMPLE_BUFFERS, 1); - } - if (glFormat.alpha()) { - int alphaSize = glFormat.alphaBufferSize(); - eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize == -1 ? 1 : alphaSize); - } - - int redSize = glFormat.redBufferSize(); - int greenSize = glFormat.greenBufferSize(); - int blueSize = glFormat.blueBufferSize(); - int alphaSize = glFormat.alphaBufferSize(); - - eglProperties.setValue(EGL_RED_SIZE, redSize > 0 ? redSize : 1); - eglProperties.setValue(EGL_GREEN_SIZE, greenSize > 0 ? greenSize : 1); - eglProperties.setValue(EGL_BLUE_SIZE, blueSize > 0 ? blueSize : 1); - eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize > 0 ? alphaSize : 0); + if (glFormat.depth() && depthSize <= 0) + depthSize = 1; + if (glFormat.stencil() && stencilSize <= 0) + stencilSize = 1; + if (glFormat.sampleBuffers() && sampleCount <= 0) + sampleCount = 1; + + // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide + // the best performance. The EGL config selection algorithm is a bit stange in this regard: + // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard + // 32-bit configs completely from the selection. So it then comes to the sorting algorithm. + // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort + // order is special and described as "by larger _total_ number of color bits.". So EGL will + // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on + // to say "If the requested number of bits in attrib_list for a particular component is 0, + // then the number of bits for that component is not considered". This part of the spec also + // seems to imply that setting the red/green/blue bits to zero means none of the components + // are considered and EGL disregards the entire sorting rule. It then looks to the next + // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being + // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are + // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, + // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that + // if the application sets the red/green/blue size to 5/6/5 on the QGLFormat, they will + // probably get a 32-bit config, even when there's an RGB565 config avaliable. Oh well. + + // Now normalize the values so -1 becomes 0 + redSize = redSize > 0 ? redSize : 0; + greenSize = greenSize > 0 ? greenSize : 0; + blueSize = blueSize > 0 ? blueSize : 0; + alphaSize = alphaSize > 0 ? alphaSize : 0; + depthSize = depthSize > 0 ? depthSize : 0; + stencilSize = stencilSize > 0 ? stencilSize : 0; + sampleCount = sampleCount > 0 ? sampleCount : 0; + + eglProperties.setValue(EGL_RED_SIZE, redSize); + eglProperties.setValue(EGL_GREEN_SIZE, greenSize); + eglProperties.setValue(EGL_BLUE_SIZE, blueSize); + eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize); + eglProperties.setValue(EGL_DEPTH_SIZE, depthSize); + eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize); + eglProperties.setValue(EGL_SAMPLES, sampleCount); + eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0); } @@ -210,23 +237,26 @@ void QGLContextPrivate::destroyEglSurfaceForDevice() EGLSurface QGLContextPrivate::eglSurfaceForDevice() const { - if (paintDevice->devType() == QInternal::Widget) + // If a QPixmapData had to create the QGLContext, we don't have a paintDevice + if (!paintDevice) return eglSurface; - if (paintDevice->devType() == QInternal::Pixmap) { + #ifdef Q_WS_X11 + if (paintDevice->devType() == QInternal::Pixmap) { QPixmapData *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data(); if (pmd->classId() == QPixmapData::X11Class) { QX11PixmapData* x11PixmapData = static_cast<QX11PixmapData*>(pmd); return (EGLSurface)x11PixmapData->gl_surface; - } else -#endif - return eglSurface; + } } +#endif + if (paintDevice->devType() == QInternal::Pbuffer) { QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice); return pbuf->d_func()->pbuf; } - return EGL_NO_SURFACE; + + return eglSurface; } void QGLWidget::setMouseTracking(bool enable) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index c142715..ed34f79 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -64,7 +64,7 @@ #include "qcache.h" #include "qglpaintdevice_p.h" -#ifdef QT_OPENGL_ES +#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) #include <QtGui/private/qegl_p.h> #endif diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index f0b06ef5..4fa1467 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1753,7 +1753,7 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, con if (!glxPixmap) return 0; - pixmapData->gl_surface = (Qt::HANDLE)glxPixmap; + pixmapData->gl_surface = (void*)glxPixmap; // Make sure the cleanup hook gets called so we can delete the glx pixmap QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 123bbdd..a7c92cf 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -42,7 +42,6 @@ #include "qgl.h" #include <private/qt_x11_p.h> #include <private/qpixmap_x11_p.h> -#include <private/qimagepixmapcleanuphooks_p.h> #include <private/qgl_p.h> #include <private/qpaintengine_opengl_p.h> #include "qgl_egl_p.h" @@ -199,10 +198,6 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) configProps.setRenderableType(QEgl::OpenGL); qt_eglproperties_set_glformat(configProps, d->glFormat); - // Use EGL_BUFFER_SIZE to make sure we prefer a 16-bit config over a 32-bit config - if (device()->depth() == 16 && !d->glFormat.alpha()) - configProps.setValue(EGL_BUFFER_SIZE, 16); - if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { delete d->eglContext; d->eglContext = 0; @@ -244,7 +239,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) if (x11PixmapData->gl_surface) eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface); - x11PixmapData->gl_surface = (Qt::HANDLE)QEgl::createSurface(device(), d->eglContext->config()); + x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config()); } return true; @@ -358,113 +353,6 @@ void QGLWidgetPrivate::recreateEglSurface(bool force) } } -// Selects which configs should be used -EGLConfig Q_OPENGL_EXPORT qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly) -{ - // Cache the configs we select as they wont change: - static EGLConfig roPixmapRGBConfig = 0; - static EGLConfig roPixmapRGBAConfig = 0; - static EGLConfig rwPixmapRGBConfig = 0; - static EGLConfig rwPixmapRGBAConfig = 0; - - EGLConfig* targetConfig; - - if (hasAlpha) { - if (readOnly) - targetConfig = &roPixmapRGBAConfig; - else - targetConfig = &rwPixmapRGBAConfig; - } - else { - if (readOnly) - targetConfig = &roPixmapRGBConfig; - else - targetConfig = &rwPixmapRGBConfig; - } - - if (*targetConfig == 0) { - QEglProperties configAttribs; - configAttribs.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT); - configAttribs.setRenderableType(QEgl::OpenGL); - if (hasAlpha) - configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); - else - configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); - - // If this is going to be a render target, it needs to have a depth, stencil & sample buffer - if (!readOnly) { - configAttribs.setValue(EGL_DEPTH_SIZE, 1); - configAttribs.setValue(EGL_STENCIL_SIZE, 1); - configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1); - } - - EGLint configCount = 0; - do { - eglChooseConfig(QEgl::display(), configAttribs.properties(), targetConfig, 1, &configCount); - if (configCount > 0) { - // Got one - qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" ) - << "config to create a pixmap surface:"; - -// QEglProperties configProps(*targetConfig); -// qDebug() << configProps.toString(); - break; - } - qWarning("choosePixmapConfig() - No suitible config found, reducing requirements"); - } while (configAttribs.reduceConfiguration()); - } - - if (*targetConfig == 0) - qWarning("choosePixmapConfig() - Couldn't find a suitable config"); - - return *targetConfig; -} - -bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly) -{ - Q_ASSERT(pmd->classId() == QPixmapData::X11Class); - QX11PixmapData* pixmapData = static_cast<QX11PixmapData*>(pmd); - - bool hasAlpha = pixmapData->hasAlphaChannel(); - - EGLConfig pixmapConfig = qt_chooseEGLConfigForPixmap(hasAlpha, readOnly); - - QEglProperties pixmapAttribs; - - // If the pixmap can't be bound to a texture, it's pretty useless - pixmapAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); - if (hasAlpha) - pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); - else - pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); - - EGLSurface pixmapSurface; - pixmapSurface = eglCreatePixmapSurface(QEgl::display(), - pixmapConfig, - (EGLNativePixmapType) pixmapData->handle(), - pixmapAttribs.properties()); -// qDebug("qt_createEGLSurfaceForPixmap() created surface 0x%x for pixmap 0x%x", -// pixmapSurface, pixmapData->handle()); - if (pixmapSurface == EGL_NO_SURFACE) { - qWarning() << "Failed to create a pixmap surface:" << QEgl::errorString(); - return false; - } - - static bool doneOnce = false; - if (!doneOnce) { - // Make sure QGLTextureCache is instanciated so it can install cleanup hooks - // which cleanup the EGL surface. - QGLTextureCache::instance(); - doneOnce = true; - } - - Q_ASSERT(sizeof(Qt::HANDLE) >= sizeof(EGLSurface)); // Just to make totally sure! - pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface; - QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData); // Make sure the cleanup hook gets called - - return true; -} - QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key, QGLContext::BindOptions options) @@ -512,8 +400,8 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons hasAlpha ? QEgl::Translucent : QEgl::NoOptions); QPixmap tmpPixmap(pixmapData); //### - pixmapData->gl_surface = (Qt::HANDLE)QEgl::createSurface(&tmpPixmap, config); - if (pixmapData->gl_surface == (Qt::HANDLE)EGL_NO_SURFACE) { + pixmapData->gl_surface = (void*)QEgl::createSurface(&tmpPixmap, config); + if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) { haveTFP = false; return 0; } @@ -531,7 +419,7 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons if (success == EGL_FALSE) { qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface); - pixmapData->gl_surface = (Qt::HANDLE)EGL_NO_SURFACE; + pixmapData->gl_surface = (void*)EGL_NO_SURFACE; haveTFP = false; return 0; } diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp index 3a399ae..a282e4c 100644 --- a/src/opengl/qgraphicssystem_gl.cpp +++ b/src/opengl/qgraphicssystem_gl.cpp @@ -62,7 +62,6 @@ QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) co if (type == QPixmapData::PixmapType && QX11GLPixmapData::hasX11GLPixmaps()) return new QX11GLPixmapData(); #endif - return new QGLPixmapData(type); } diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp index 811e554..d7fae16 100644 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ b/src/opengl/qpixmapdata_x11gl_egl.cpp @@ -58,13 +58,16 @@ QT_BEGIN_NAMESPACE -extern EGLConfig qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly); // in qgl_x11egl.cpp -extern bool qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly); // in qgl_x11egl.cpp // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need // different contexts: -static EGLContext qPixmapARGBSharedEglContext = EGL_NO_CONTEXT; -static EGLContext qPixmapRGBSharedEglContext = EGL_NO_CONTEXT; + +Q_GLOBAL_STATIC(QEglContext, qt_x11gl_rgbContext); +Q_GLOBAL_STATIC(QEglContext, qt_x11gl_argbContext) + +QEglContext* QX11GLPixmapData::rgbContext = 0; +QEglContext* QX11GLPixmapData::argbContext = 0; + bool QX11GLPixmapData::hasX11GLPixmaps() { @@ -76,109 +79,94 @@ bool QX11GLPixmapData::hasX11GLPixmaps() checkedForX11Pixmaps = true; - QX11PixmapData *argbPixmapData = 0; - QX11PixmapData *rgbPixmapData = 0; + EGLint rgbConfigId; + EGLint argbConfigId; + do { if (qgetenv("QT_USE_X11GL_PIXMAPS").isEmpty()) break; - // Check we actually have EGL configs which support pixmaps - EGLConfig argbConfig = qt_chooseEGLConfigForPixmap(true, false); - EGLConfig rgbConfig = qt_chooseEGLConfigForPixmap(false, false); + EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable); + EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, + QEgl::Renderable | QEgl::Translucent); - if (argbConfig == 0 || rgbConfig == 0) - break; + eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId); + eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId); - // Create the shared contexts: - eglBindAPI(EGL_OPENGL_ES_API); - EGLint contextAttribs[] = { -#if defined(QT_OPENGL_ES_2) - EGL_CONTEXT_CLIENT_VERSION, 2, -#endif - EGL_NONE - }; - qPixmapARGBSharedEglContext = eglCreateContext(QEgl::display(), - argbConfig, 0, contextAttribs); - - if (argbConfig == rgbConfig) { - // If the configs are the same, we can re-use the same context. - qPixmapRGBSharedEglContext = qPixmapARGBSharedEglContext; - } else { - qPixmapRGBSharedEglContext = eglCreateContext(QEgl::display(), - rgbConfig, 0, contextAttribs); + if (!rgbContext) { + rgbContext = qt_x11gl_rgbContext(); + rgbContext->setConfig(rgbConfig); + rgbContext->createContext(); } - argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); - argbPixmapData->resize(100, 100); - argbPixmapData->fill(Qt::transparent); // Force ARGB + if (!rgbContext->isValid()) + break; - if (!qt_createEGLSurfaceForPixmap(argbPixmapData, false)) + // If the configs are the same, use the same egl contexts: + if (rgbConfig == argbConfig) + argbContext = rgbContext; + + if (!argbContext) { + argbContext = qt_x11gl_argbContext(); + argbContext->setConfig(argbConfig); + argbContext->createContext(); + } + + if (!argbContext->isValid()) break; - haveX11Pixmaps = eglMakeCurrent(QEgl::display(), - (EGLSurface)argbPixmapData->gl_surface, - (EGLSurface)argbPixmapData->gl_surface, - qPixmapARGBSharedEglContext); + { + QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); + argbPixmapData->resize(100, 100); + argbPixmapData->fill(Qt::transparent); // Force ARGB + QPixmap argbPixmap(argbPixmapData); + EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig); + haveX11Pixmaps = argbContext->makeCurrent(argbPixmapSurface); + argbContext->doneCurrent(); + eglDestroySurface(QEgl::display(), argbPixmapSurface); + } + if (!haveX11Pixmaps) { - qWarning() << "Unable to make pixmap config current:" << QEgl::errorString(); + qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString(); break; } - // If the ARGB & RGB configs are the same, we don't need to check RGB too - if (haveX11Pixmaps && (argbConfig != rgbConfig)) { - rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); + // If the ARGB & RGB configs are different, check RGB too: + if (argbConfig != rgbConfig) { + QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); rgbPixmapData->resize(100, 100); rgbPixmapData->fill(Qt::red); - // Try to actually create an EGL pixmap surface - if (!qt_createEGLSurfaceForPixmap(rgbPixmapData, false)) - break; + QPixmap rgbPixmap(rgbPixmapData); + EGLSurface rgbPixmapSurface = QEgl::createSurface(&rgbPixmap, rgbConfig); + haveX11Pixmaps = rgbContext->makeCurrent(rgbPixmapSurface); + rgbContext->doneCurrent(); + eglDestroySurface(QEgl::display(), rgbPixmapSurface); - haveX11Pixmaps = eglMakeCurrent(QEgl::display(), - (EGLSurface)rgbPixmapData->gl_surface, - (EGLSurface)rgbPixmapData->gl_surface, - qPixmapRGBSharedEglContext); if (!haveX11Pixmaps) { qWarning() << "Unable to make pixmap config current:" << QEgl::errorString(); break; } } - } while (0); - - if (qPixmapARGBSharedEglContext || qPixmapRGBSharedEglContext) { - eglMakeCurrent(QEgl::display(), - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - if (argbPixmapData) { - if (argbPixmapData->gl_surface) - QGLContextPrivate::destroyGlSurfaceForPixmap(argbPixmapData); - delete argbPixmapData; - argbPixmapData = 0; - } - if (rgbPixmapData) { - if (rgbPixmapData->gl_surface) - QGLContextPrivate::destroyGlSurfaceForPixmap(rgbPixmapData); - delete rgbPixmapData; - rgbPixmapData = 0; - } + // The pixmap surface destruction hooks are installed by QGLTextureCache, so we + // must make sure this is instanciated: + QGLTextureCache::instance(); + } while (0); if (!haveX11Pixmaps) { - // Clean up the context(s) if we can't use X11GL pixmaps - if (qPixmapARGBSharedEglContext != EGL_NO_CONTEXT) - eglDestroyContext(QEgl::display(), qPixmapARGBSharedEglContext); - - if (qPixmapRGBSharedEglContext != qPixmapARGBSharedEglContext && - qPixmapRGBSharedEglContext != EGL_NO_CONTEXT) - { - eglDestroyContext(QEgl::display(), qPixmapRGBSharedEglContext); + if (argbContext && (argbContext != rgbContext)) { + delete argbContext; + argbContext = 0; + } + if (rgbContext) { + delete rgbContext; + rgbContext = 0; } - qPixmapRGBSharedEglContext = EGL_NO_CONTEXT; - qPixmapARGBSharedEglContext = EGL_NO_CONTEXT; } if (haveX11Pixmaps) - qDebug("QX11GLPixmapData is supported"); + qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId); else qDebug("QX11GLPixmapData is *NOT* being used"); @@ -209,11 +197,8 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const // We need to create the context before beginPaint - do it here: if (!ctx) { ctx = new QGLContext(glFormat()); - if (ctx->d_func()->eglContext == 0) - ctx->d_func()->eglContext = new QEglContext(); - ctx->d_func()->eglContext->setApi(QEgl::OpenGL); - ctx->d_func()->eglContext->setContext(hasAlphaChannel() ? qPixmapARGBSharedEglContext - : qPixmapRGBSharedEglContext); + Q_ASSERT(ctx->d_func()->eglContext == 0); + ctx->d_func()->eglContext = hasAlphaChannel() ? argbContext : rgbContext; } QPaintEngine* engine; @@ -256,10 +241,19 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const void QX11GLPixmapData::beginPaint() { // qDebug("QX11GLPixmapData::beginPaint()"); + // TODO: Check to see if the surface is renderable if ((EGLSurface)gl_surface == EGL_NO_SURFACE) { - qt_createEGLSurfaceForPixmap(this, false); - ctx->d_func()->eglSurface = (EGLSurface)gl_surface; - ctx->d_func()->valid = true; // ;-) + QPixmap tmpPixmap(this); + EGLConfig cfg = ctx->d_func()->eglContext->config(); + + EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg); + if (surface == EGL_NO_SURFACE) { + qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString(); + return; + } + gl_surface = (void*)surface; + ctx->d_func()->eglSurface = surface; + ctx->d_func()->valid = true; } QGLPaintDevice::beginPaint(); } diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h index c9f4f56..83cd780 100644 --- a/src/opengl/qpixmapdata_x11gl_p.h +++ b/src/opengl/qpixmapdata_x11gl_p.h @@ -59,6 +59,10 @@ #include <qgl.h> +#ifndef QT_NO_EGL +#include <QtGui/private/qeglcontext_p.h> +#endif + QT_BEGIN_NAMESPACE class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice @@ -76,6 +80,11 @@ public: static bool hasX11GLPixmaps(); static QGLFormat glFormat(); + +#ifndef QT_NO_EGL + static QEglContext* rgbContext; + static QEglContext* argbContext; +#endif private: mutable QGLContext* ctx; }; |