--- a/src/opengl/qgl_p.h Tue Feb 02 00:43:10 2010 +0200
+++ b/src/opengl/qgl_p.h Wed Mar 31 11:06:36 2010 +0300
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -80,13 +80,19 @@
#define q_vertexTypeEnum GL_FIXED
#endif //QT_OPENGL_ES_1_CL
-#ifdef QT_OPENGL_ES
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
QT_BEGIN_INCLUDE_NAMESPACE
+
#if defined(QT_OPENGL_ES_2)
-#include <EGL/egl.h>
+# include <GLES2/gl2.h>
+#endif
+
+#if defined(QT_GLES_EGL)
+# include <GLES/egl.h>
#else
-#include <GLES/egl.h>
+# include <EGL/egl.h>
#endif
+
QT_END_INCLUDE_NAMESPACE
#endif
@@ -179,7 +185,9 @@
#if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
, eglSurfaceWindowId(0)
#endif
- {}
+ {
+ isGLWidget = 1;
+ }
~QGLWidgetPrivate() {}
@@ -222,9 +230,8 @@
typedef QHash<QString, GLuint> QGLDDSCache;
// QGLContextPrivate has the responsibility of creating context groups.
-// QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy
+// QGLContextPrivate maintains the reference counter and destroys
// context groups when needed.
-// QGLShareRegister has the responsibility of keeping the context pointer up to date.
class QGLContextGroup
{
public:
@@ -233,9 +240,13 @@
QGLExtensionFuncs &extensionFuncs() {return m_extensionFuncs;}
const QGLContext *context() const {return m_context;}
bool isSharing() const { return m_shares.size() >= 2; }
+ QList<const QGLContext *> shares() const { return m_shares; }
void addGuard(QGLSharedResourceGuard *guard);
void removeGuard(QGLSharedResourceGuard *guard);
+
+ static void addShare(const QGLContext *context, const QGLContext *share);
+ static void removeShare(const QGLContext *context);
private:
QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { }
@@ -249,14 +260,75 @@
void cleanupResources(const QGLContext *ctx);
- friend class QGLShareRegister;
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLContextResource;
};
+// Get the context that resources for "ctx" will transfer to once
+// "ctx" is destroyed. Returns null if nothing is sharing with ctx.
+Q_OPENGL_EXPORT const QGLContext *qt_gl_transfer_context(const QGLContext *);
+
+// GL extension definitions
+class QGLExtensions {
+public:
+ enum Extension {
+ TextureRectangle = 0x00000001,
+ SampleBuffers = 0x00000002,
+ GenerateMipmap = 0x00000004,
+ TextureCompression = 0x00000008,
+ FragmentProgram = 0x00000010,
+ MirroredRepeat = 0x00000020,
+ FramebufferObject = 0x00000040,
+ StencilTwoSide = 0x00000080,
+ StencilWrap = 0x00000100,
+ PackedDepthStencil = 0x00000200,
+ NVFloatBuffer = 0x00000400,
+ PixelBufferObject = 0x00000800,
+ FramebufferBlit = 0x00001000,
+ NPOTTextures = 0x00002000,
+ BGRATextureFormat = 0x00004000,
+ DDSTextureCompression = 0x00008000,
+ ETC1TextureCompression = 0x00010000,
+ PVRTCTextureCompression = 0x00020000,
+ FragmentShader = 0x00040000
+ };
+ Q_DECLARE_FLAGS(Extensions, Extension)
+
+ static Extensions glExtensions();
+
+private:
+ static Extensions currentContextExtensions();
+};
+
+/*
+ QGLTemporaryContext - the main objective of this class is to have a way of
+ creating a GL context and making it current, without going via QGLWidget
+ and friends. At certain points during GL initialization we need a current
+ context in order decide what GL features are available, and to resolve GL
+ extensions. Having a light-weight way of creating such a context saves
+ initial application startup time, and it doesn't wind up creating recursive
+ conflicts.
+ The class currently uses a private d pointer to hide the platform specific
+ types. This could possibly been done inline with #ifdef'ery, but it causes
+ major headaches on e.g. X11 due to namespace pollution.
+*/
+class QGLTemporaryContextPrivate;
+class QGLTemporaryContext {
+public:
+ QGLTemporaryContext(bool directRendering = true, QWidget *parent = 0);
+ ~QGLTemporaryContext();
+
+private:
+ QScopedPointer<QGLTemporaryContextPrivate> d;
+};
+
class QGLTexture;
+// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
+// all the GL2 engine uses:
+#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
+
class QGLContextPrivate
{
Q_DECLARE_PUBLIC(QGLContext)
@@ -276,6 +348,9 @@
void cleanup();
+ void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
+ void syncGlState(); // Makes sure the GL context's state is what we think it is
+
#if defined(Q_WS_WIN)
HGLRC rc;
HDC dc;
@@ -320,10 +395,12 @@
uint crWin : 1;
uint internal_context : 1;
uint version_flags_cached : 1;
+ uint extension_flags_cached : 1;
QPaintDevice *paintDevice;
QColor transpColor;
QGLContext *q_ptr;
QGLFormat::OpenGLVersionFlags version_flags;
+ QGLExtensions::Extensions extension_flags;
QGLContextGroup *group;
GLint max_texture_size;
@@ -332,6 +409,8 @@
GLuint default_fbo;
QPaintEngine *active_engine;
+ bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
+
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
#ifdef Q_WS_WIN
@@ -360,54 +439,8 @@
void aboutToDestroyContext(const QGLContext *context);
};
-// GL extension definitions
-class QGLExtensions {
-public:
- enum Extension {
- TextureRectangle = 0x00000001,
- SampleBuffers = 0x00000002,
- GenerateMipmap = 0x00000004,
- TextureCompression = 0x00000008,
- FragmentProgram = 0x00000010,
- MirroredRepeat = 0x00000020,
- FramebufferObject = 0x00000040,
- StencilTwoSide = 0x00000080,
- StencilWrap = 0x00000100,
- PackedDepthStencil = 0x00000200,
- NVFloatBuffer = 0x00000400,
- PixelBufferObject = 0x00000800,
- FramebufferBlit = 0x00001000,
- NPOTTextures = 0x00002000,
- BGRATextureFormat = 0x00004000,
- DDSTextureCompression = 0x00008000,
- ETC1TextureCompression = 0x00010000,
- PVRTCTextureCompression = 0x00020000,
- FragmentShader = 0x00040000
- };
- Q_DECLARE_FLAGS(Extensions, Extension)
-
- static Extensions glExtensions;
- static bool nvidiaFboNeedsFinish;
- static void init(); // sys dependent
- static void init_extensions(); // general: called by init()
-};
-
Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
-
-class Q_OPENGL_EXPORT QGLShareRegister
-{
-public:
- QGLShareRegister() {}
- ~QGLShareRegister() {}
-
- void addShare(const QGLContext *context, const QGLContext *share);
- QList<const QGLContext *> shares(const QGLContext *context);
- void removeShare(const QGLContext *context);
-};
-
-extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg();
-
// Temporarily make a context current if not already current or
// shared with the current contex. The previous context is made
// current when the object goes out of scope.
@@ -497,7 +530,7 @@
QSize bindCompressedTexturePVR(const char *buf, int len);
};
-class QGLTextureCache {
+class Q_AUTOTEST_EXPORT QGLTextureCache {
public:
QGLTextureCache();
~QGLTextureCache();
@@ -513,12 +546,9 @@
static QGLTextureCache *instance();
static void deleteIfEmpty();
- static void imageCleanupHook(qint64 cacheKey);
- static void cleanupTextures(QPixmap* pixmap);
-#ifdef Q_WS_X11
- // X11 needs to catch pixmap data destruction to delete EGL/GLX pixmap surfaces
- static void cleanupPixmapSurfaces(QPixmap* pixmap);
-#endif
+ static void cleanupTexturesForCacheKey(qint64 cacheKey);
+ static void cleanupTexturesForPixampData(QPixmapData* pixmap);
+ static void cleanupBeforePixmapDestruction(QPixmapData* pixmap);
private:
QCache<qint64, QGLTexture> m_cache;
@@ -531,7 +561,7 @@
inline GLenum qt_gl_preferredTextureFormat()
{
- return (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
+ return (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
? GL_BGRA : GL_RGBA;
}
@@ -540,7 +570,7 @@
#if defined(QT_OPENGL_ES_2)
return GL_TEXTURE_2D;
#else
- return (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle)
+ return (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
&& !qt_gl_preferGL2Engine()
? GL_TEXTURE_RECTANGLE_NV
: GL_TEXTURE_2D;
@@ -548,7 +578,7 @@
}
// One resource per group of shared contexts.
-class Q_AUTOTEST_EXPORT QGLContextResource
+class Q_OPENGL_EXPORT QGLContextResource
{
public:
typedef void (*FreeFunc)(void *);
@@ -612,7 +642,7 @@
};
-// This class can be used to match GL extensions with doing any mallocs. The
+// This class can be used to match GL extensions without doing any mallocs. The
// class assumes that the GL extension string ends with a space character,
// which it should do on all conformant platforms. Create the object and pass
// in a pointer to the extension string, then call match() on each extension