summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp12
-rw-r--r--src/opengl/gl2paintengineex/qtriangulatingstroker.cpp5
-rw-r--r--src/opengl/gl2paintengineex/qtriangulatingstroker_p.h4
-rw-r--r--src/opengl/qgl.cpp71
-rw-r--r--src/opengl/qgl_egl.cpp158
-rw-r--r--src/opengl/qgl_egl_p.h2
-rw-r--r--src/opengl/qgl_p.h4
-rw-r--r--src/opengl/qgl_qws.cpp3
-rw-r--r--src/opengl/qgl_wince.cpp3
-rw-r--r--src/opengl/qgl_x11.cpp2
-rw-r--r--src/opengl/qgl_x11egl.cpp18
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp2
-rw-r--r--src/opengl/qpixmapdata_x11gl_egl.cpp33
14 files changed, 177 insertions, 142 deletions
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index 192e01c..a1495dd 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
+#include "qglgradientcache_p.h"
#include <private/qdrawhelper_p.h>
#include <private/qgl_p.h>
-#include "qglgradientcache_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 2b5f2f4..d68a268 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -64,6 +64,7 @@
// #define QT_OPENGL_CACHE_AS_VBOS
+#include "qglgradientcache_p.h"
#include "qpaintengineex_opengl2_p.h"
#include <string.h> //for memcpy
@@ -80,7 +81,6 @@
#include <private/qstatictext_p.h>
#include <private/qtriangulator_p.h>
-#include "qglgradientcache_p.h"
#include "qglengineshadermanager_p.h"
#include "qgl2pexvertexarray_p.h"
#include "qtriangulatingstroker_p.h"
@@ -1155,16 +1155,20 @@ void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen)
// prepareForDraw() down below.
updateMatrix();
+ QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled
+ ? q->state()->rectangleClip
+ : QRectF(0, 0, width, height));
+
if (penStyle == Qt::SolidLine) {
- stroker.process(path, pen);
+ stroker.process(path, pen, clip);
} else { // Some sort of dash
- dasher.process(path, pen);
+ dasher.process(path, pen, clip);
QVectorPath dashStroke(dasher.points(),
dasher.elementCount(),
dasher.elementTypes());
- stroker.process(dashStroke, pen);
+ stroker.process(dashStroke, pen, clip);
}
if (opaque) {
diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
index 5229d3f..d952988 100644
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
@@ -73,7 +73,7 @@ void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal *
}
-void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen)
+void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &)
{
const qreal *pts = path.points();
const QPainterPath::ElementType *types = path.elements();
@@ -480,7 +480,7 @@ QDashedStrokeProcessor::QDashedStrokeProcessor()
m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo);
}
-void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen)
+void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip)
{
const qreal *pts = path.points();
@@ -497,6 +497,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen)
m_dash_stroker.setDashPattern(pen.dashPattern());
m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width);
m_dash_stroker.setMiterLimit(pen.miterLimit());
+ m_dash_stroker.setClipRect(clip);
qreal curvyness = sqrt(width) * m_inv_scale / 8;
if (count < 2)
diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h
index 06b8a44..956d7cc 100644
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
class QTriangulatingStroker
{
public:
- void process(const QVectorPath &path, const QPen &pen);
+ void process(const QVectorPath &path, const QPen &pen, const QRectF &clip);
inline int vertexCount() const { return m_vertices.size(); }
inline const float *vertices() const { return m_vertices.data(); }
@@ -96,7 +96,7 @@ class QDashedStrokeProcessor
public:
QDashedStrokeProcessor();
- void process(const QVectorPath &path, const QPen &pen);
+ void process(const QVectorPath &path, const QPen &pen, const QRectF &clip);
inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) {
m_points.add(x);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 73cd6a8..e0030ad 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -766,6 +766,7 @@ void QGLFormat::setSamples(int numSamples)
return;
}
d->numSamples = numSamples;
+ setSampleBuffers(numSamples > 0);
}
/*!
@@ -904,6 +905,7 @@ void QGLFormat::setDepthBufferSize(int size)
return;
}
d->depthSize = size;
+ setDepth(size > 0);
}
/*!
@@ -1017,7 +1019,7 @@ void QGLFormat::setAlphaBufferSize(int size)
return;
}
d->alphaSize = size;
- setOption(QGL::AlphaChannel);
+ setAlpha(size > 0);
}
/*!
@@ -1044,6 +1046,7 @@ void QGLFormat::setAccumBufferSize(int size)
return;
}
d->accumSize = size;
+ setAccum(size > 0);
}
/*!
@@ -1069,6 +1072,7 @@ void QGLFormat::setStencilBufferSize(int size)
return;
}
d->stencilSize = size;
+ setStencil(size > 0);
}
/*!
@@ -1579,6 +1583,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
vi = 0;
#endif
#if defined(QT_OPENGL_ES)
+ ownsEglContext = false;
eglContext = 0;
eglSurface = EGL_NO_SURFACE;
#endif
@@ -1684,14 +1689,12 @@ typedef void (*_qt_image_cleanup_hook_64)(qint64);
extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64;
extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64;
-static QGLTextureCache *qt_gl_texture_cache = 0;
+
+Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache)
QGLTextureCache::QGLTextureCache()
: m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
{
- Q_ASSERT(qt_gl_texture_cache == 0);
- qt_gl_texture_cache = this;
-
QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
@@ -1699,8 +1702,7 @@ QGLTextureCache::QGLTextureCache()
QGLTextureCache::~QGLTextureCache()
{
- qt_gl_texture_cache = 0;
-
+ Q_ASSERT(size() == 0);
QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
@@ -1750,22 +1752,14 @@ void QGLTextureCache::removeContextTextures(QGLContext* ctx)
}
}
-QGLTextureCache* QGLTextureCache::instance()
-{
- if (!qt_gl_texture_cache)
- qt_gl_texture_cache = new QGLTextureCache;
-
- return qt_gl_texture_cache;
-}
-
/*
a hook that removes textures from the cache when a pixmap/image
is deref'ed
*/
void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
{
- instance()->remove(cacheKey);
- Q_ASSERT(instance()->getTexture(cacheKey) == 0);
+ qt_gl_texture_cache()->remove(cacheKey);
+ Q_ASSERT(qt_gl_texture_cache()->getTexture(cacheKey) == 0);
}
@@ -1787,10 +1781,9 @@ void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
#endif
}
-void QGLTextureCache::deleteIfEmpty()
+QGLTextureCache *QGLTextureCache::instance()
{
- if (instance()->size() == 0)
- delete instance();
+ return qt_gl_texture_cache();
}
// DDS format structure
@@ -1956,7 +1949,6 @@ QGLContext::~QGLContext()
{
// remove any textures cached in this context
QGLTextureCache::instance()->removeContextTextures(this);
- QGLTextureCache::deleteIfEmpty(); // ### thread safety
d_ptr->group->cleanupResources(this);
@@ -5068,6 +5060,20 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
return glExtensions;
}
+
+class QGLDefaultExtensions
+{
+public:
+ QGLDefaultExtensions() {
+ QGLTemporaryContext tempContext;
+ extensions = QGLExtensions::currentContextExtensions();
+ }
+
+ QGLExtensions::Extensions extensions;
+};
+
+Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions)
+
/*
Returns the GL extensions for the current QGLContext. If there is no
current QGLContext, a default context will be created and the extensions
@@ -5075,34 +5081,19 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
*/
QGLExtensions::Extensions QGLExtensions::glExtensions()
{
- QGLTemporaryContext *tmpContext = 0;
- static bool cachedDefault = false;
- static Extensions defaultExtensions = 0;
+ Extensions extensionFlags = 0;
QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
if (currentCtx && currentCtx->d_func()->extension_flags_cached)
return currentCtx->d_func()->extension_flags;
if (!currentCtx) {
- if (cachedDefault) {
- return defaultExtensions;
- } else {
- tmpContext = new QGLTemporaryContext;
- cachedDefault = true;
- }
- }
-
- Extensions extensionFlags = currentContextExtensions();
- if (currentCtx) {
+ extensionFlags = qtDefaultExtensions()->extensions;
+ } else {
+ extensionFlags = currentContextExtensions();
currentCtx->d_func()->extension_flags_cached = true;
currentCtx->d_func()->extension_flags = extensionFlags;
- } else {
- defaultExtensions = extensionFlags;
}
-
- if (tmpContext)
- delete tmpContext;
-
return extensionFlags;
}
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 91b271b..822c9f6 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -53,77 +53,96 @@ 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);
- }
- 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);
+ 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)
+ alphaSize = 1;
+ 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);
}
-
// Updates "format" with the parameters of the selected configuration.
-void qt_egl_update_format(const QEglContext& context, QGLFormat& format)
+void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config)
{
- EGLint value = 0;
-
- if (context.configAttrib(EGL_RED_SIZE, &value))
- format.setRedBufferSize(value);
- if (context.configAttrib(EGL_GREEN_SIZE, &value))
- format.setGreenBufferSize(value);
- if (context.configAttrib(EGL_BLUE_SIZE, &value))
- format.setBlueBufferSize(value);
- if (context.configAttrib(EGL_ALPHA_SIZE, &value)) {
- format.setAlpha(value != 0);
- if (format.alpha())
- format.setAlphaBufferSize(value);
- }
-
- if (context.configAttrib(EGL_DEPTH_SIZE, &value)) {
- format.setDepth(value != 0);
- if (format.depth())
- format.setDepthBufferSize(value);
- }
-
- if (context.configAttrib(EGL_LEVEL, &value))
- format.setPlane(value);
-
- if (context.configAttrib(EGL_SAMPLE_BUFFERS, &value)) {
- format.setSampleBuffers(value != 0);
- if (format.sampleBuffers()) {
- context.configAttrib(EGL_SAMPLES, &value);
- format.setSamples(value);
- }
- }
-
- if (context.configAttrib(EGL_STENCIL_SIZE, &value)) {
- format.setStencil(value != 0);
- if (format.stencil())
- format.setStencilBufferSize(value);
- }
+ EGLint redSize = 0;
+ EGLint greenSize = 0;
+ EGLint blueSize = 0;
+ EGLint alphaSize = 0;
+ EGLint depthSize = 0;
+ EGLint stencilSize = 0;
+ EGLint sampleCount = 0;
+ EGLint level = 0;
+
+ EGLDisplay display = QEgl::display();
+ eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
+ eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
+ eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
+ eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
+ eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
+ eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
+ eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
+ eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
+
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ format.setAlphaBufferSize(alphaSize);
+ format.setDepthBufferSize(depthSize);
+ format.setStencilBufferSize(stencilSize);
+ format.setSamples(sampleCount);
+ format.setPlane(level + 1); // EGL calls level 0 "normal" whereas Qt calls 1 "normal"
+ format.setDirectRendering(true); // All EGL contexts are direct-rendered
+ format.setRgba(true); // EGL doesn't support colour index rendering
+ format.setStereo(false); // EGL doesn't support stereo buffers
+ format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
// Clear the EGL error state because some of the above may
// have errored out because the attribute is not applicable
@@ -143,10 +162,11 @@ void QGLContext::reset()
return;
d->cleanup();
doneCurrent();
- if (d->eglContext) {
+ if (d->eglContext && d->ownsEglContext) {
d->destroyEglSurfaceForDevice();
delete d->eglContext;
}
+ d->ownsEglContext = false;
d->eglContext = 0;
d->eglSurface = EGL_NO_SURFACE;
d->crWin = false;
@@ -194,7 +214,7 @@ void QGLContextPrivate::destroyEglSurfaceForDevice()
#ifdef Q_WS_X11
// Make sure we don't call eglDestroySurface on a surface which
// was created for a different winId:
- if (paintDevice->devType() == QInternal::Widget) {
+ if (paintDevice && paintDevice->devType() == QInternal::Widget) {
QGLWidget* w = static_cast<QGLWidget*>(paintDevice);
if (w->d_func()->eglSurfaceWindowId == w->winId())
diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h
index 6b65227..43793cd 100644
--- a/src/opengl/qgl_egl_p.h
+++ b/src/opengl/qgl_egl_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QGLFormat;
void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format);
-void qt_egl_update_format(const QEglContext& context, QGLFormat& format);
+void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config);
QT_END_NAMESPACE
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index ed34f79..45f8f30 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -278,8 +278,6 @@ public:
Q_DECLARE_FLAGS(Extensions, Extension)
static Extensions glExtensions();
-
-private:
static Extensions currentContextExtensions();
};
@@ -347,6 +345,7 @@ public:
HDC hbitmap_hdc;
#endif
#if defined(QT_OPENGL_ES)
+ bool ownsEglContext;
QEglContext *eglContext;
EGLSurface eglSurface;
void destroyEglSurfaceForDevice();
@@ -532,7 +531,6 @@ public:
bool remove(QGLContext *ctx, GLuint textureId);
void removeContextTextures(QGLContext *ctx);
static QGLTextureCache *instance();
- static void deleteIfEmpty();
static void cleanupTexturesForCacheKey(qint64 cacheKey);
static void cleanupTexturesForPixampData(QPixmapData* pixmap);
static void cleanupBeforePixmapDestruction(QPixmapData* pixmap);
diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp
index f72f051..38c3774 100644
--- a/src/opengl/qgl_qws.cpp
+++ b/src/opengl/qgl_qws.cpp
@@ -182,6 +182,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
// Get the display and initialize it.
d->eglContext = new QEglContext();
+ d->ownsEglContext = true;
d->eglContext->setApi(QEgl::OpenGL);
// Construct the configuration we need for this surface.
@@ -200,7 +201,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
}
// Inform the higher layers about the actual format properties.
- qt_egl_update_format(*(d->eglContext), d->glFormat);
+ qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
// Create a new context for the configuration.
if (!d->eglContext->createContext
diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp
index 3bf7f3a..47a19b5 100644
--- a/src/opengl/qgl_wince.cpp
+++ b/src/opengl/qgl_wince.cpp
@@ -145,6 +145,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
// Get the display and initialize it.
d->eglContext = new QEglContext();
+ d->ownsEglContext = true;
d->eglContext->setApi(QEgl::OpenGL);
// Construct the configuration we need for this surface.
@@ -163,7 +164,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
}
// Inform the higher layers about the actual format properties.
- qt_egl_update_format(*(d->eglContext), d->glFormat);
+ qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
// Create a new context for the configuration.
if (!d->eglContext->createContext
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 fdcc412..0954e69 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -182,6 +182,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
// Only create the eglContext if we don't already have one:
if (d->eglContext == 0) {
d->eglContext = new QEglContext();
+ d->ownsEglContext = true;
d->eglContext->setApi(QEgl::OpenGL);
// If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
@@ -198,10 +199,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;
@@ -220,9 +217,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
}
- // Inform the higher layers about the actual format properties.
- qt_egl_update_format(*(d->eglContext), d->glFormat);
-
+ // Inform the higher layers about the actual format properties
+ qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
// Do don't create the EGLSurface for everything.
// QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
@@ -243,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;
@@ -404,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;
}
@@ -423,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/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
index ee0714f..db9e754 100644
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ b/src/opengl/qglpixelbuffer_egl.cpp
@@ -113,7 +113,7 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
}
// Retrieve the actual format properties.
- qt_egl_update_format(*ctx, format);
+ qt_glformat_from_eglconfig(format, ctx->config());
// Create the attributes needed for the pbuffer.
QEglProperties attribs;
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
index 34915f5..a01eec4 100644
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ b/src/opengl/qpixmapdata_x11gl_egl.cpp
@@ -61,6 +61,10 @@ QT_BEGIN_NAMESPACE
// On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
// different contexts:
+
+Q_GLOBAL_STATIC(QEglContext, qt_x11gl_rgbContext);
+Q_GLOBAL_STATIC(QEglContext, qt_x11gl_argbContext)
+
QEglContext* QX11GLPixmapData::rgbContext = 0;
QEglContext* QX11GLPixmapData::argbContext = 0;
@@ -75,6 +79,9 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
checkedForX11Pixmaps = true;
+ EGLint rgbConfigId;
+ EGLint argbConfigId;
+
do {
if (qgetenv("QT_USE_X11GL_PIXMAPS").isEmpty())
break;
@@ -83,8 +90,11 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
QEgl::Renderable | QEgl::Translucent);
+ eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
+ eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);
+
if (!rgbContext) {
- rgbContext = new QEglContext;
+ rgbContext = qt_x11gl_rgbContext();
rgbContext->setConfig(rgbConfig);
rgbContext->createContext();
}
@@ -97,7 +107,7 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
argbContext = rgbContext;
if (!argbContext) {
- argbContext = new QEglContext;
+ argbContext = qt_x11gl_argbContext();
argbContext->setConfig(argbConfig);
argbContext->createContext();
}
@@ -138,6 +148,10 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
break;
}
}
+
+ // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
+ // must make sure this is instanciated:
+ QGLTextureCache::instance();
} while (0);
if (!haveX11Pixmaps) {
@@ -152,7 +166,7 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
}
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");
@@ -167,6 +181,8 @@ QX11GLPixmapData::QX11GLPixmapData()
QX11GLPixmapData::~QX11GLPixmapData()
{
+ if (ctx)
+ delete ctx;
}
#if !defined(QT_OPENGL_ES_1)
@@ -231,8 +247,15 @@ void QX11GLPixmapData::beginPaint()
if ((EGLSurface)gl_surface == EGL_NO_SURFACE) {
QPixmap tmpPixmap(this);
EGLConfig cfg = ctx->d_func()->eglContext->config();
- gl_surface = (Qt::HANDLE)QEgl::createSurface(&tmpPixmap, cfg);
- ctx->d_func()->eglSurface = (EGLSurface)gl_surface;
+ Q_ASSERT(cfg != QEGL_NO_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();