src/opengl/qgl_p.h
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 7 3f74d0d4af4c
--- a/src/opengl/qgl_p.h	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/opengl/qgl_p.h	Fri Feb 19 23:40:16 2010 +0200
@@ -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)
 **
@@ -222,9 +222,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 +232,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 +252,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 +340,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 +387,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 +401,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 +431,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.
@@ -531,7 +556,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 +565,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;
@@ -612,7 +637,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