Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 23731)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 23732)
@@ -484,6 +484,7 @@
 if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_GUI_USE_QGL)
  VirtualBox_SOURCES += \
- 	src/VBoxFBQGL.cpp \
- 	src/VBoxFBOverlay.cpp
+    src/VBoxFBQGL.cpp \
+    src/VBoxFBOverlay.cpp \
+    src/VBoxGLSupportInfo.cpp
 endif
 # The Qt modules we're using.
@@ -645,4 +646,21 @@
 endif # darwin
 
+#
+# App for testing GL support
+#
+if defined(VBOX_WITH_VIDEOHWACCEL)
+ if1of ($(KBUILD_TARGET), win linux)
+  PROGRAMS += VBoxTestOGL2D
+  VBoxTestOGL2D_TEMPLATE := $(if $(VBOX_WITH_HARDENING),VBOXQT4GUI,VBOXQT4GUIEXE)
+  VBoxTestOGL2D_SOURCES = \
+      src/VBoxTestQGLApp.cpp \
+      src/VBoxGLSupportInfo.cpp
+  VBoxTestOGL2D_QT_MODULES = Core Gui OpenGL
+  VBoxTestOGL2D_INCS = include
+  VBoxTestOGL2D_LDFLAGS.darwin += -framework OpenGL
+  VBoxTestOGL2D_LIBS.win     += $(PATH_SDK_WINPSDK_LIB)/Opengl32.lib
+  VBoxTestOGL2D_LIBS.solaris += GL
+ endif 
+endif
 
 #
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h	(revision 23731)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h	(revision 23732)
@@ -27,93 +27,12 @@
 //#define VBOXQGL_DBG_SURF 1
 
-#include "COMDefs.h"
+//#include "COMDefs.h"
 #include <QGLWidget>
 #include <iprt/assert.h>
 #include <iprt/critsect.h>
 
+#include "VBoxGLSupportInfo.h"
+
 #define VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY 1
-
-#if defined(DEBUG) && !defined(DEBUG_sandervl)
-# include "iprt/stream.h"
-# define VBOXQGLLOG(_m) RTPrintf _m
-# define VBOXQGLLOGREL(_m) do { RTPrintf _m ; LogRel( _m ); } while(0)
-#else
-# define VBOXQGLLOG(_m)    do {}while(0)
-# define VBOXQGLLOGREL(_m) LogRel( _m )
-#endif
-#define VBOXQGLLOG_ENTER(_m)
-//do{VBOXQGLLOG(("==>[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
-#define VBOXQGLLOG_EXIT(_m)
-//do{VBOXQGLLOG(("<==[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
-#ifdef DEBUG
- #define VBOXQGL_ASSERTNOERR() \
-    do { GLenum err = glGetError(); \
-        if(err != GL_NO_ERROR) VBOXQGLLOG(("gl error ocured (0x%x)\n", err)); \
-        Assert(err == GL_NO_ERROR); \
-    }while(0)
-
- #define VBOXQGL_CHECKERR(_op) \
-    do { \
-        glGetError(); \
-        _op \
-        VBOXQGL_ASSERTNOERR(); \
-    }while(0)
-#else
- #define VBOXQGL_ASSERTNOERR() \
-    do {}while(0)
-
- #define VBOXQGL_CHECKERR(_op) \
-    do { \
-        _op \
-    }while(0)
-#endif
-
-#ifdef DEBUG
-#include <iprt/time.h>
-
-#define VBOXGETTIME() RTTimeNanoTS()
-
-#define VBOXPRINTDIF(_nano, _m) do{\
-        uint64_t cur = VBOXGETTIME(); \
-        VBOXQGLLOG(_m); \
-        VBOXQGLLOG(("(%Lu)\n", cur - (_nano))); \
-    }while(0)
-
-class VBoxVHWADbgTimeCounter
-{
-public:
-    VBoxVHWADbgTimeCounter(const char* msg) {mTime = VBOXGETTIME(); mMsg=msg;}
-    ~VBoxVHWADbgTimeCounter() {VBOXPRINTDIF(mTime, (mMsg));}
-private:
-    uint64_t mTime;
-    const char* mMsg;
-};
-
-#define VBOXQGLLOG_METHODTIME(_m) VBoxVHWADbgTimeCounter _dbgTimeCounter(_m)
-
-#define VBOXQG_CHECKCONTEXT() \
-        { \
-            const GLubyte * str; \
-            VBOXQGL_CHECKERR(   \
-                    str = glGetString(GL_VERSION); \
-            ); \
-            Assert(str); \
-            if(str) \
-            { \
-                Assert(str[0]); \
-            } \
-        }
-#else
-#define VBOXQGLLOG_METHODTIME(_m)
-#define VBOXQG_CHECKCONTEXT() do{}while(0)
-#endif
-
-#define VBOXQGLLOG_QRECT(_p, _pr, _s) do{\
-    VBOXQGLLOG((_p " x(%d), y(%d), w(%d), h(%d)" _s, (_pr)->x(), (_pr)->y(), (_pr)->width(), (_pr)->height()));\
-    }while(0)
-
-#define VBOXQGLLOG_CKEY(_p, _pck, _s) do{\
-    VBOXQGLLOG((_p " l(0x%x), u(0x%x)" _s, (_pck)->lower(), (_pck)->upper()));\
-    }while(0)
 
 class VBoxVHWADirtyRect
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGLSupportInfo.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGLSupportInfo.h	(revision 23732)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGLSupportInfo.h	(revision 23732)
@@ -0,0 +1,395 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * OpenGL support info used for 2D support detection
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+#ifndef __VBoxGLSupportInfo_h__
+#define __VBoxGLSupportInfo_h__
+#include <QGLWidget>
+#include <iprt/types.h>
+
+#if defined(DEBUG) && !defined(DEBUG_sandervl)
+# include "iprt/stream.h"
+# define VBOXQGLLOG(_m) RTPrintf _m
+# define VBOXQGLLOGREL(_m) do { RTPrintf _m ; LogRel( _m ); } while(0)
+#else
+# define VBOXQGLLOG(_m)    do {}while(0)
+# define VBOXQGLLOGREL(_m) LogRel( _m )
+#endif
+#define VBOXQGLLOG_ENTER(_m)
+//do{VBOXQGLLOG(("==>[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
+#define VBOXQGLLOG_EXIT(_m)
+//do{VBOXQGLLOG(("<==[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
+#ifdef DEBUG
+ #define VBOXQGL_ASSERTNOERR() \
+    do { GLenum err = glGetError(); \
+        if(err != GL_NO_ERROR) VBOXQGLLOG(("gl error ocured (0x%x)\n", err)); \
+        Assert(err == GL_NO_ERROR); \
+    }while(0)
+
+ #define VBOXQGL_CHECKERR(_op) \
+    do { \
+        glGetError(); \
+        _op \
+        VBOXQGL_ASSERTNOERR(); \
+    }while(0)
+#else
+ #define VBOXQGL_ASSERTNOERR() \
+    do {}while(0)
+
+ #define VBOXQGL_CHECKERR(_op) \
+    do { \
+        _op \
+    }while(0)
+#endif
+
+#ifdef DEBUG
+#include <iprt/time.h>
+
+#define VBOXGETTIME() RTTimeNanoTS()
+
+#define VBOXPRINTDIF(_nano, _m) do{\
+        uint64_t cur = VBOXGETTIME(); \
+        VBOXQGLLOG(_m); \
+        VBOXQGLLOG(("(%Lu)\n", cur - (_nano))); \
+    }while(0)
+
+class VBoxVHWADbgTimeCounter
+{
+public:
+    VBoxVHWADbgTimeCounter(const char* msg) {mTime = VBOXGETTIME(); mMsg=msg;}
+    ~VBoxVHWADbgTimeCounter() {VBOXPRINTDIF(mTime, (mMsg));}
+private:
+    uint64_t mTime;
+    const char* mMsg;
+};
+
+#define VBOXQGLLOG_METHODTIME(_m) VBoxVHWADbgTimeCounter _dbgTimeCounter(_m)
+
+#define VBOXQG_CHECKCONTEXT() \
+        { \
+            const GLubyte * str; \
+            VBOXQGL_CHECKERR(   \
+                    str = glGetString(GL_VERSION); \
+            ); \
+            Assert(str); \
+            if(str) \
+            { \
+                Assert(str[0]); \
+            } \
+        }
+#else
+#define VBOXQGLLOG_METHODTIME(_m)
+#define VBOXQG_CHECKCONTEXT() do{}while(0)
+#endif
+
+#define VBOXQGLLOG_QRECT(_p, _pr, _s) do{\
+    VBOXQGLLOG((_p " x(%d), y(%d), w(%d), h(%d)" _s, (_pr)->x(), (_pr)->y(), (_pr)->width(), (_pr)->height()));\
+    }while(0)
+
+#define VBOXQGLLOG_CKEY(_p, _pck, _s) do{\
+    VBOXQGLLOG((_p " l(0x%x), u(0x%x)" _s, (_pck)->lower(), (_pck)->upper()));\
+    }while(0)
+
+typedef char GLchar;
+
+#ifndef GL_COMPILE_STATUS
+# define GL_COMPILE_STATUS 0x8b81
+#endif
+#ifndef GL_LINK_STATUS
+# define GL_LINK_STATUS    0x8b82
+#endif
+#ifndef GL_FRAGMENT_SHADER
+# define GL_FRAGMENT_SHADER 0x8b30
+#endif
+#ifndef GL_VERTEX_SHADER
+# define GL_VERTEX_SHADER 0x8b31
+#endif
+
+/* GL_ARB_multitexture */
+#ifndef GL_TEXTURE0
+# define GL_TEXTURE0                    0x84c0
+#endif
+#ifndef GL_TEXTURE1
+# define GL_TEXTURE1                    0x84c1
+#endif
+#ifndef GL_MAX_TEXTURE_COORDS
+# define GL_MAX_TEXTURE_COORDS          0x8871
+#endif
+#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
+# define GL_MAX_TEXTURE_IMAGE_UNITS     0x8872
+#endif
+
+#ifndef APIENTRY
+# define APIENTRY
+#endif
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_ACTIVE_TEXTURE) (GLenum texture);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2I) (GLenum texture, GLint v0, GLint v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2F) (GLenum texture, GLfloat v0, GLfloat v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2D) (GLenum texture, GLdouble v0, GLdouble v1);
+
+/* GL_ARB_texture_rectangle */
+#ifndef GL_TEXTURE_RECTANGLE
+# define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+
+/* GL_ARB_shader_objects */
+/* GL_ARB_fragment_shader */
+
+typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_SHADER)  (GLenum type);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_SHADER_SOURCE)  (GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_COMPILE_SHADER) (GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_SHADER)  (GLuint shader);
+
+typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_PROGRAM) ();
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_ATTACH_SHADER)  (GLuint program, GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DETACH_SHADER)  (GLuint program, GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_LINK_PROGRAM)   (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_USE_PROGRAM)    (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_PROGRAM) (GLuint program);
+
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_SHADER)   (GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADERIV)   (GLuint shader, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_PROGRAM)  (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAMIV)  (GLuint program, GLenum pname, GLint *params);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_ATTACHED_SHADERS) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADER_INFO_LOG)  (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAM_INFO_LOG) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef GLint (APIENTRY *PFNVBOXVHWA_GET_UNIFORM_LOCATION) (GLint programObj, const GLchar *name);
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1F)(GLint location, GLfloat v0);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2F)(GLint location, GLfloat v0, GLfloat v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1I)(GLint location, GLint v0);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2I)(GLint location, GLint v0, GLint v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3I)(GLint location, GLint v0, GLint v1, GLint v2);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4I)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+
+/* GL_ARB_pixel_buffer_object*/
+#ifndef Q_WS_MAC
+/* apears to be defined on mac */
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_READ_ONLY
+# define GL_READ_ONLY                   0x88B8
+#endif
+#ifndef GL_WRITE_ONLY
+# define GL_WRITE_ONLY                  0x88B9
+#endif
+#ifndef GL_READ_WRITE
+# define GL_READ_WRITE                  0x88BA
+#endif
+#ifndef GL_STREAM_DRAW
+# define GL_STREAM_DRAW                 0x88E0
+#endif
+#ifndef GL_STREAM_READ
+# define GL_STREAM_READ                 0x88E1
+#endif
+#ifndef GL_STREAM_COPY
+# define GL_STREAM_COPY                 0x88E2
+#endif
+
+#ifndef GL_PIXEL_PACK_BUFFER
+# define GL_PIXEL_PACK_BUFFER           0x88EB
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER
+# define GL_PIXEL_UNPACK_BUFFER         0x88EC
+#endif
+#ifndef GL_PIXEL_PACK_BUFFER_BINDING
+# define GL_PIXEL_PACK_BUFFER_BINDING   0x88ED
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER_BINDING
+# define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#endif
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GEN_BUFFERS)(GLsizei n, GLuint *buffers);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_BUFFERS)(GLsizei n, const GLuint *buffers);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_BIND_BUFFER)(GLenum target, GLuint buffer);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_BUFFER_DATA)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef GLvoid* (APIENTRY *PFNVBOXVHWA_MAP_BUFFER)(GLenum target, GLenum access);
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_UNMAP_BUFFER)(GLenum target);
+
+
+/*****************/
+
+/* functions */
+
+/* @todo: move those to VBoxGLInfo class instance members ??? */
+extern PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f;
+
+
+extern PFNVBOXVHWA_CREATE_SHADER   vboxglCreateShader;
+extern PFNVBOXVHWA_SHADER_SOURCE   vboxglShaderSource;
+extern PFNVBOXVHWA_COMPILE_SHADER  vboxglCompileShader;
+extern PFNVBOXVHWA_DELETE_SHADER   vboxglDeleteShader;
+
+extern PFNVBOXVHWA_CREATE_PROGRAM  vboxglCreateProgram;
+extern PFNVBOXVHWA_ATTACH_SHADER   vboxglAttachShader;
+extern PFNVBOXVHWA_DETACH_SHADER   vboxglDetachShader;
+extern PFNVBOXVHWA_LINK_PROGRAM    vboxglLinkProgram;
+extern PFNVBOXVHWA_USE_PROGRAM     vboxglUseProgram;
+extern PFNVBOXVHWA_DELETE_PROGRAM  vboxglDeleteProgram;
+
+extern PFNVBOXVHWA_IS_SHADER       vboxglIsShader;
+extern PFNVBOXVHWA_GET_SHADERIV    vboxglGetShaderiv;
+extern PFNVBOXVHWA_IS_PROGRAM      vboxglIsProgram;
+extern PFNVBOXVHWA_GET_PROGRAMIV   vboxglGetProgramiv;
+extern PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders;
+extern PFNVBOXVHWA_GET_SHADER_INFO_LOG  vboxglGetShaderInfoLog;
+extern PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog;
+
+extern PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation;
+
+extern PFNVBOXVHWA_UNIFORM1F vboxglUniform1f;
+extern PFNVBOXVHWA_UNIFORM2F vboxglUniform2f;
+extern PFNVBOXVHWA_UNIFORM3F vboxglUniform3f;
+extern PFNVBOXVHWA_UNIFORM4F vboxglUniform4f;
+
+extern PFNVBOXVHWA_UNIFORM1I vboxglUniform1i;
+extern PFNVBOXVHWA_UNIFORM2I vboxglUniform2i;
+extern PFNVBOXVHWA_UNIFORM3I vboxglUniform3i;
+extern PFNVBOXVHWA_UNIFORM4I vboxglUniform4i;
+
+extern PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers;
+extern PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers;
+extern PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer;
+extern PFNVBOXVHWA_BUFFER_DATA vboxglBufferData;
+extern PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer;
+extern PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer;
+
+class VBoxGLInfo
+{
+public:
+    VBoxGLInfo() :
+        mGLVersion(0),
+        mFragmentShaderSupported(false),
+        mTextureRectangleSupported(false),
+        mTextureNP2Supported(false),
+        mPBOSupported(false),
+        mMultiTexNumSupported(1), /* 1 would mean it is not supported */
+        m_GL_ARB_multitexture(false),
+        m_GL_ARB_shader_objects(false),
+        m_GL_ARB_fragment_shader(false),
+        m_GL_ARB_pixel_buffer_object(false),
+        m_GL_ARB_texture_rectangle(false),
+        m_GL_EXT_texture_rectangle(false),
+        m_GL_NV_texture_rectangle(false),
+        m_GL_ARB_texture_non_power_of_two(false),
+        mInitialized(false)
+    {}
+
+    void init(const class QGLContext * pContext);
+
+    bool isInitialized() const { return mInitialized; }
+
+    int getGLVersion() const { return mGLVersion; }
+    bool isFragmentShaderSupported() const { return mFragmentShaderSupported; }
+    bool isTextureRectangleSupported() const { return mTextureRectangleSupported; }
+    bool isTextureNP2Supported() const { return mTextureNP2Supported; }
+    bool isPBOSupported() const { return mPBOSupported; }
+    /* 1 would mean it is not supported */
+    int getMultiTexNumSupported() const { return mMultiTexNumSupported; }
+
+    static int parseVersion(const GLubyte * ver);
+private:
+    void initExtSupport(const class QGLContext & context);
+
+    int mGLVersion;
+    bool mFragmentShaderSupported;
+    bool mTextureRectangleSupported;
+    bool mTextureNP2Supported;
+    bool mPBOSupported;
+    int mMultiTexNumSupported; /* 1 would mean it is not supported */
+
+    bool m_GL_ARB_multitexture;
+    bool m_GL_ARB_shader_objects;
+    bool m_GL_ARB_fragment_shader;
+    bool m_GL_ARB_pixel_buffer_object;
+    bool m_GL_ARB_texture_rectangle;
+    bool m_GL_EXT_texture_rectangle;
+    bool m_GL_NV_texture_rectangle;
+    bool m_GL_ARB_texture_non_power_of_two;
+
+    bool mInitialized;
+};
+
+class VBoxGLTmpContext
+{
+public:
+    VBoxGLTmpContext();
+    ~VBoxGLTmpContext();
+
+    const class QGLContext * makeCurrent();
+private:
+    class QGLWidget * mWidget;
+};
+
+
+#define VBOXQGL_MAKEFOURCC(ch0, ch1, ch2, ch3)                              \
+                ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) |       \
+                ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
+
+#define FOURCC_AYUV VBOXQGL_MAKEFOURCC('A', 'Y', 'U', 'V')
+#define FOURCC_UYVY VBOXQGL_MAKEFOURCC('U', 'Y', 'V', 'Y')
+#define FOURCC_YUY2 VBOXQGL_MAKEFOURCC('Y', 'U', 'Y', '2')
+#define FOURCC_YV12 VBOXQGL_MAKEFOURCC('Y', 'V', '1', '2')
+#define VBOXVHWA_NUMFOURCC 4
+
+class VBoxVHWAInfo
+{
+public:
+    VBoxVHWAInfo() :
+        mFourccSupportedCount(0),
+        mInitialized(false)
+    {}
+
+    VBoxVHWAInfo(const VBoxGLInfo & glInfo) :
+        mglInfo(glInfo),
+        mFourccSupportedCount(0),
+        mInitialized(false)
+    {}
+
+    void init(const class QGLContext * pContext);
+
+    bool isInitialized() const { return mInitialized; }
+
+    const VBoxGLInfo & getGlInfo() const { return mglInfo; }
+
+    bool isVHWASupported() const;
+
+    int getFourccSupportedCount() const { return mFourccSupportedCount; }
+    const uint32_t * getFourccSupportedList() const { return mFourccSupportedList; }
+
+    static bool checkVHWASupport();
+private:
+    VBoxGLInfo mglInfo;
+    uint32_t mFourccSupportedList[VBOXVHWA_NUMFOURCC];
+    int mFourccSupportedCount;
+
+    bool mInitialized;
+};
+
+#endif /* #ifndef __VBoxGLSupportInfo_h__ */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 23731)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 23732)
@@ -29,4 +29,6 @@
 #include "VBoxGlobal.h"
 
+#include "VBoxGLSupportInfo.h"
+
 /* Qt includes */
 #include <QGLWidget>
@@ -127,677 +129,28 @@
 #endif
 
-#define VBOXQGL_MAKEFOURCC(ch0, ch1, ch2, ch3)                              \
-                ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) |       \
-                ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
-
-#define FOURCC_AYUV VBOXQGL_MAKEFOURCC('A', 'Y', 'U', 'V')
-#define FOURCC_UYVY VBOXQGL_MAKEFOURCC('U', 'Y', 'V', 'Y')
-#define FOURCC_YUY2 VBOXQGL_MAKEFOURCC('Y', 'U', 'Y', '2')
-#define FOURCC_YV12 VBOXQGL_MAKEFOURCC('Y', 'V', '1', '2')
-#define VBOXVHWA_NUMFOURCC 4
-
-typedef char GLchar;
-
-#ifndef GL_COMPILE_STATUS
-# define GL_COMPILE_STATUS 0x8b81
-#endif
-#ifndef GL_LINK_STATUS
-# define GL_LINK_STATUS    0x8b82
-#endif
-#ifndef GL_FRAGMENT_SHADER
-# define GL_FRAGMENT_SHADER 0x8b30
-#endif
-#ifndef GL_VERTEX_SHADER
-# define GL_VERTEX_SHADER 0x8b31
-#endif
-
-/* GL_ARB_multitexture */
-#ifndef GL_TEXTURE0
-# define GL_TEXTURE0                    0x84c0
-#endif
-#ifndef GL_TEXTURE1
-# define GL_TEXTURE1                    0x84c1
-#endif
-#ifndef GL_MAX_TEXTURE_COORDS
-# define GL_MAX_TEXTURE_COORDS          0x8871
-#endif
-#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
-# define GL_MAX_TEXTURE_IMAGE_UNITS     0x8872
-#endif
-
-#ifndef APIENTRY
-# define APIENTRY
-#endif
-
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_ACTIVE_TEXTURE) (GLenum texture);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2I) (GLenum texture, GLint v0, GLint v1);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2F) (GLenum texture, GLfloat v0, GLfloat v1);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2D) (GLenum texture, GLdouble v0, GLdouble v1);
-
-/* GL_ARB_texture_rectangle */
-#ifndef GL_TEXTURE_RECTANGLE
-# define GL_TEXTURE_RECTANGLE 0x84F5
-#endif
-
-/* GL_ARB_shader_objects */
-/* GL_ARB_fragment_shader */
-
-typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_SHADER)  (GLenum type);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_SHADER_SOURCE)  (GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_COMPILE_SHADER) (GLuint shader);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_SHADER)  (GLuint shader);
-
-typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_PROGRAM) ();
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_ATTACH_SHADER)  (GLuint program, GLuint shader);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_DETACH_SHADER)  (GLuint program, GLuint shader);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_LINK_PROGRAM)   (GLuint program);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_USE_PROGRAM)    (GLuint program);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_PROGRAM) (GLuint program);
-
-typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_SHADER)   (GLuint shader);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADERIV)   (GLuint shader, GLenum pname, GLint *params);
-typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_PROGRAM)  (GLuint program);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAMIV)  (GLuint program, GLenum pname, GLint *params);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_ATTACHED_SHADERS) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADER_INFO_LOG)  (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAM_INFO_LOG) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
-typedef GLint (APIENTRY *PFNVBOXVHWA_GET_UNIFORM_LOCATION) (GLint programObj, const GLchar *name);
-
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1F)(GLint location, GLfloat v0);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2F)(GLint location, GLfloat v0, GLfloat v1);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
-
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1I)(GLint location, GLint v0);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2I)(GLint location, GLint v0, GLint v1);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3I)(GLint location, GLint v0, GLint v1, GLint v2);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4I)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
-
-/* GL_ARB_pixel_buffer_object*/
-#ifndef Q_WS_MAC
-/* apears to be defined on mac */
-typedef ptrdiff_t GLsizeiptr;
-#endif
-
-#ifndef GL_READ_ONLY
-# define GL_READ_ONLY                   0x88B8
-#endif
-#ifndef GL_WRITE_ONLY
-# define GL_WRITE_ONLY                  0x88B9
-#endif
-#ifndef GL_READ_WRITE
-# define GL_READ_WRITE                  0x88BA
-#endif
-#ifndef GL_STREAM_DRAW
-# define GL_STREAM_DRAW                 0x88E0
-#endif
-#ifndef GL_STREAM_READ
-# define GL_STREAM_READ                 0x88E1
-#endif
-#ifndef GL_STREAM_COPY
-# define GL_STREAM_COPY                 0x88E2
-#endif
-
-#ifndef GL_PIXEL_PACK_BUFFER
-# define GL_PIXEL_PACK_BUFFER           0x88EB
-#endif
-#ifndef GL_PIXEL_UNPACK_BUFFER
-# define GL_PIXEL_UNPACK_BUFFER         0x88EC
-#endif
-#ifndef GL_PIXEL_PACK_BUFFER_BINDING
-# define GL_PIXEL_PACK_BUFFER_BINDING   0x88ED
-#endif
-#ifndef GL_PIXEL_UNPACK_BUFFER_BINDING
-# define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
-#endif
-
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_GEN_BUFFERS)(GLsizei n, GLuint *buffers);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_BUFFERS)(GLsizei n, const GLuint *buffers);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_BIND_BUFFER)(GLenum target, GLuint buffer);
-typedef GLvoid (APIENTRY *PFNVBOXVHWA_BUFFER_DATA)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
-typedef GLvoid* (APIENTRY *PFNVBOXVHWA_MAP_BUFFER)(GLenum target, GLenum access);
-typedef GLboolean (APIENTRY *PFNVBOXVHWA_UNMAP_BUFFER)(GLenum target);
-
-/*****************/
-
-/* functions */
-
-PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture = NULL;
-PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i = NULL;
-PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d = NULL;
-PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f = NULL;
-
-
-PFNVBOXVHWA_CREATE_SHADER   vboxglCreateShader  = NULL;
-PFNVBOXVHWA_SHADER_SOURCE   vboxglShaderSource  = NULL;
-PFNVBOXVHWA_COMPILE_SHADER  vboxglCompileShader = NULL;
-PFNVBOXVHWA_DELETE_SHADER   vboxglDeleteShader  = NULL;
-
-PFNVBOXVHWA_CREATE_PROGRAM  vboxglCreateProgram = NULL;
-PFNVBOXVHWA_ATTACH_SHADER   vboxglAttachShader  = NULL;
-PFNVBOXVHWA_DETACH_SHADER   vboxglDetachShader  = NULL;
-PFNVBOXVHWA_LINK_PROGRAM    vboxglLinkProgram   = NULL;
-PFNVBOXVHWA_USE_PROGRAM     vboxglUseProgram    = NULL;
-PFNVBOXVHWA_DELETE_PROGRAM  vboxglDeleteProgram = NULL;
-
-PFNVBOXVHWA_IS_SHADER       vboxglIsShader      = NULL;
-PFNVBOXVHWA_GET_SHADERIV    vboxglGetShaderiv   = NULL;
-PFNVBOXVHWA_IS_PROGRAM      vboxglIsProgram     = NULL;
-PFNVBOXVHWA_GET_PROGRAMIV   vboxglGetProgramiv  = NULL;
-PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders = NULL;
-PFNVBOXVHWA_GET_SHADER_INFO_LOG  vboxglGetShaderInfoLog   = NULL;
-PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog  = NULL;
-
-PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation = NULL;
-
-PFNVBOXVHWA_UNIFORM1F vboxglUniform1f;
-PFNVBOXVHWA_UNIFORM2F vboxglUniform2f;
-PFNVBOXVHWA_UNIFORM3F vboxglUniform3f;
-PFNVBOXVHWA_UNIFORM4F vboxglUniform4f;
-
-PFNVBOXVHWA_UNIFORM1I vboxglUniform1i;
-PFNVBOXVHWA_UNIFORM2I vboxglUniform2i;
-PFNVBOXVHWA_UNIFORM3I vboxglUniform3i;
-PFNVBOXVHWA_UNIFORM4I vboxglUniform4i;
-
-PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers = NULL;
-PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers = NULL;
-PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer = NULL;
-PFNVBOXVHWA_BUFFER_DATA vboxglBufferData = NULL;
-PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer = NULL;
-PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer = NULL;
-
-#if 0
-#if defined Q_WS_WIN
-#define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)wglGetProcAddress(_n)
-#elif defined Q_WS_X11
-#include <GL/glx.h>
-#define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)glXGetProcAddress((const GLubyte *)(_n))
-#else
-#error "Port me!!!"
-#endif
-#endif
-
-#define VBOXVHWA_GETPROCADDRESS(_c, _t, _n) ((_t)(_c).getProcAddress(QString(_n)))
-
-#define VBOXVHWA_PFNINIT_SAME(_c, _t, _v, _rc) \
-    do { \
-        if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v)) == NULL) \
-        { \
-            VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v));\
-            AssertBreakpoint(); \
-            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
-            { \
-                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
-                AssertBreakpoint(); \
-                if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"EXT")) == NULL) \
-                { \
-                    VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"EXT"));\
-                    AssertBreakpoint(); \
-                    (_rc)++; \
-                } \
-            } \
-        } \
-    }while(0)
-
-#define VBOXVHWA_PFNINIT(_c, _t, _v, _f,_rc) \
-    do { \
-        if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_f)) == NULL) \
-        { \
-            VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_f));\
-            AssertBreakpoint(); \
-            (_rc)++; \
-        } \
-    }while(0)
-
-//#define VBOXVHWA_PFNINIT_OBJECT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ObjectARB" ,_rc)
-#define VBOXVHWA_PFNINIT_OBJECT_ARB(_c, _t, _v, _rc) \
-        do { \
-            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ObjectARB")) == NULL) \
-            { \
-                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ObjectARB"));\
-                AssertBreakpoint(); \
-                (_rc)++; \
-            } \
-        }while(0)
-
-//#define VBOXVHWA_PFNINIT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ARB" ,_rc)
-#define VBOXVHWA_PFNINIT_ARB(_c, _t, _v, _rc) \
-        do { \
-            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
-            { \
-                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
-                AssertBreakpoint(); \
-                (_rc)++; \
-            } \
-        }while(0)
-
-
-static bool g_vboxVHWAGlSupportInitialized = false;
-/* vbox version in the format 0x00mjmnbl
- * in case of a failure contains -1 (0xffffffff) */
-static int g_vboxVHWAGlVersion = 0;
-
-static bool g_GL_ARB_multitexture        = false;
-static bool g_GL_ARB_shader_objects      = false;
-static bool g_GL_ARB_fragment_shader     = false;
-static bool g_GL_ARB_pixel_buffer_object = false;
-static bool g_GL_ARB_texture_rectangle   = false;
-static bool g_GL_EXT_texture_rectangle   = false;
-static bool g_GL_NV_texture_rectangle         = false;
-static bool g_GL_ARB_texture_non_power_of_two = false;
-
-/* gl features supported */
-static bool g_vboxVHWAGlShaderSupported = false;
-static bool g_vboxVHWAGlTextureRectangleSupported = false;
-static bool g_vboxVHWAGlTextureNP2Supported = false;
-static bool g_vboxVHWAGlPBOSupported = false;
-static int g_vboxVHWAGlMultiTexNumSupported = 1; /* 1 would mean it is not supported */
-
-/* vhwa features supported */
-static uint32_t g_vboxVHWAFourccSupportedList[VBOXVHWA_NUMFOURCC];
-static uint32_t g_vboxVHWAFourccSupportedCount = 0;
-
-
-static int vboxVHWAGlParseSubver(const GLubyte * ver, const GLubyte ** pNext, bool bSpacePrefixAllowed)
-{
-    int val = 0;
-
-    for(;;++ver)
-    {
-        if(*ver >= '0' && *ver <= '9')
-        {
-            if(!val)
+static VBoxVHWAInfo g_VBoxVHWASupportInfo;
+static bool g_bVBoxVHWAChecked = false;
+static bool g_bVBoxVHWASupported = false;
+
+static const VBoxVHWAInfo & vboxVHWAGetSupportInfo(const QGLContext *pContext)
+{
+    if(!g_VBoxVHWASupportInfo.isInitialized())
+    {
+        if(pContext)
+        {
+            g_VBoxVHWASupportInfo.init(pContext);
+        }
+        else
+        {
+            VBoxGLTmpContext ctx;
+            const QGLContext *pContext = ctx.makeCurrent();
+            Assert(pContext);
+            if(pContext)
             {
-                if(*ver == '0')
-                    continue;
+                g_VBoxVHWASupportInfo.init(pContext);
             }
-            else
-            {
-                val *= 10;
-            }
-            val += *ver - '0';
-        }
-        else if(*ver == '.')
-        {
-            *pNext = ver+1;
-            break;
-        }
-        else if(*ver == '\0')
-        {
-            *pNext = NULL;
-            break;
-        }
-        else if(*ver == ' ' || *ver == '\t' ||  *ver == 0x0d || *ver == 0x0a)
-        {
-            if(bSpacePrefixAllowed)
-            {
-                if(!val)
-                {
-                    continue;
-                }
-            }
-
-            /* treat this as the end ov version string */
-            *pNext = NULL;
-            break;
-        }
-        else
-        {
-            Assert(0);
-            val = -1;
-            break;
-        }
-    }
-
-    return val;
-}
-
-static int vboxVHWAGlParseVersion(const GLubyte * ver)
-{
-    int iVer = vboxVHWAGlParseSubver(ver, &ver, true);
-    if(iVer)
-    {
-        iVer <<= 16;
-        if(ver)
-        {
-            int tmp = vboxVHWAGlParseSubver(ver, &ver, false);
-            if(tmp >= 0)
-            {
-                iVer |= tmp << 8;
-                if(ver)
-                {
-                    tmp = vboxVHWAGlParseSubver(ver, &ver, false);
-                    if(tmp >= 0)
-                    {
-                        iVer |= tmp;
-                    }
-                    else
-                    {
-                        Assert(0);
-                        iVer = -1;
-                    }
-                }
-            }
-            else
-            {
-                Assert(0);
-                iVer = -1;
-            }
-        }
-    }
-    return iVer;
-}
-
-static void vboxVHWAGlInitExtSupport(const QGLContext & context)
-{
-    int rc = 0;
-    do
-    {
-        rc = 0;
-        g_vboxVHWAGlMultiTexNumSupported = 1; /* default, 1 means not supported */
-        if(g_vboxVHWAGlVersion >= 0x010201) /* ogl >= 1.2.1 */
-        {
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
-        }
-        else if(g_GL_ARB_multitexture)
-        {
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
-        }
-        else
-        {
-            break;
-        }
-
-        if(RT_FAILURE(rc))
-            break;
-
-        GLint maxCoords, maxUnits;
-        glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxCoords);
-        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits);
-
-        VBOXQGLLOGREL(("Max Tex Coords (%d), Img Units (%d)\n", maxCoords, maxUnits));
-        /* take the minimum of those */
-        if(maxUnits < maxCoords)
-            maxCoords = maxUnits;
-        if(maxUnits < 2)
-        {
-            VBOXQGLLOGREL(("Max Tex Coord or Img Units < 2 disabling MultiTex support\n"));
-            break;
-        }
-
-        g_vboxVHWAGlMultiTexNumSupported = maxUnits;
-    }while(0);
-
-
-    do
-    {
-        rc = 0;
-        g_vboxVHWAGlPBOSupported = false;
-
-        if(g_GL_ARB_pixel_buffer_object)
-        {
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GEN_BUFFERS, GenBuffers, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_DELETE_BUFFERS, DeleteBuffers, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BIND_BUFFER, BindBuffer, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BUFFER_DATA, BufferData, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MAP_BUFFER, MapBuffer, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNMAP_BUFFER, UnmapBuffer, rc);
-        }
-        else
-        {
-            break;
-        }
-
-        if(RT_FAILURE(rc))
-            break;
-
-        g_vboxVHWAGlPBOSupported = true;
-    } while(0);
-
-    do
-    {
-        rc = 0;
-        g_vboxVHWAGlShaderSupported = false;
-
-        if(g_vboxVHWAGlVersion >= 0x020000)  /* if ogl >= 2.0*/
-        {
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, rc);
-
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, rc);
-
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_SHADER, IsShader, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders,  rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, rc);
-
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
-
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
-
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
-            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
-        }
-        else if(g_GL_ARB_shader_objects && g_GL_ARB_fragment_shader)
-        {
-            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, DeleteObjectARB, rc);
-
-            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, AttachObjectARB, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, DetachObjectARB, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
-            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, DeleteObjectARB, rc);
-
-        //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_SHADER, IsShader, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, GetObjectParameterivARB, rc);
-        //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, GetObjectParameterivARB, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders, GetAttachedObjectsARB, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, GetInfoLogARB, rc);
-            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, GetInfoLogARB, rc);
-
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
-
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
-
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
-            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
-        }
-        else
-        {
-            break;
-        }
-
-        if(RT_FAILURE(rc))
-            break;
-
-        g_vboxVHWAGlShaderSupported = true;
-    } while(0);
-
-    if(g_GL_ARB_texture_rectangle || g_GL_EXT_texture_rectangle || g_GL_NV_texture_rectangle)
-    {
-        g_vboxVHWAGlTextureRectangleSupported = true;
-    }
-    else
-    {
-        g_vboxVHWAGlTextureRectangleSupported = false;
-    }
-
-    g_vboxVHWAGlTextureNP2Supported = g_GL_ARB_texture_non_power_of_two;
-}
-
-static void vboxVHWAGlInitFeatureSupport()
-{
-    if(g_vboxVHWAGlShaderSupported && g_vboxVHWAGlTextureRectangleSupported)
-    {
-        uint32_t num = 0;
-        g_vboxVHWAFourccSupportedList[num++] = FOURCC_AYUV;
-        g_vboxVHWAFourccSupportedList[num++] = FOURCC_UYVY;
-        g_vboxVHWAFourccSupportedList[num++] = FOURCC_YUY2;
-        if(g_vboxVHWAGlMultiTexNumSupported >= 4)
-        {
-            /* YV12 currently requires 3 units (for each color component)
-             * + 1 unit for dst texture for color-keying + 3 units for each color component
-             * TODO: we could store YV12 data in one texture to eliminate this requirement*/
-            g_vboxVHWAFourccSupportedList[num++] = FOURCC_YV12;
-        }
-
-        Assert(num <= VBOXVHWA_NUMFOURCC);
-        g_vboxVHWAFourccSupportedCount = num;
-    }
-    else
-    {
-        g_vboxVHWAFourccSupportedCount = 0;
-    }
-}
-
-static void vboxVHWAGlInit(const QGLContext * pContext)
-{
-    if(g_vboxVHWAGlSupportInitialized)
-        return;
-
-    g_vboxVHWAGlSupportInitialized = true;
-
-    if (!QGLFormat::hasOpenGL())
-    {
-        VBOXQGLLOGREL (("no gl support available\n"));
-        return;
-    }
-
-    QGLWidget *pTmpWidget = NULL;
-
-    if(!pContext)
-    {
-        QGLWidget *pTmpWidget = new QGLWidget();
-        pTmpWidget->makeCurrent();
-        pContext = pTmpWidget->context();
-    }
-
-    const GLubyte * str;
-    VBOXQGL_CHECKERR(
-            str = glGetString(GL_VERSION);
-            );
-
-    if(str)
-    {
-        VBOXQGLLOGREL (("gl version string: 0%s\n", str));
-
-        g_vboxVHWAGlVersion = vboxVHWAGlParseVersion(str);
-        Assert(g_vboxVHWAGlVersion > 0);
-        if(g_vboxVHWAGlVersion < 0)
-        {
-            g_vboxVHWAGlVersion = 0;
-        }
-        else
-        {
-            VBOXQGLLOGREL (("gl version: 0x%x\n", g_vboxVHWAGlVersion));
-            VBOXQGL_CHECKERR(
-                    str = glGetString(GL_EXTENSIONS);
-                    );
-
-            const char * pos = strstr((const char *)str, "GL_ARB_multitexture");
-            g_GL_ARB_multitexture = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_multitexture: %d\n", g_GL_ARB_multitexture));
-
-            pos = strstr((const char *)str, "GL_ARB_shader_objects");
-            g_GL_ARB_shader_objects = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_shader_objects: %d\n", g_GL_ARB_shader_objects));
-
-            pos = strstr((const char *)str, "GL_ARB_fragment_shader");
-            g_GL_ARB_fragment_shader = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_fragment_shader: %d\n", g_GL_ARB_fragment_shader));
-
-            pos = strstr((const char *)str, "GL_ARB_pixel_buffer_object");
-            g_GL_ARB_pixel_buffer_object = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_pixel_buffer_object: %d\n", g_GL_ARB_pixel_buffer_object));
-
-            pos = strstr((const char *)str, "GL_ARB_texture_rectangle");
-            g_GL_ARB_texture_rectangle = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_texture_rectangle: %d\n", g_GL_ARB_texture_rectangle));
-
-            pos = strstr((const char *)str, "GL_EXT_texture_rectangle");
-            g_GL_EXT_texture_rectangle = pos != NULL;
-            VBOXQGLLOGREL (("GL_EXT_texture_rectangle: %d\n", g_GL_EXT_texture_rectangle));
-
-            pos = strstr((const char *)str, "GL_NV_texture_rectangle");
-            g_GL_NV_texture_rectangle = pos != NULL;
-            VBOXQGLLOGREL (("GL_NV_texture_rectangle: %d\n", g_GL_NV_texture_rectangle));
-
-            pos = strstr((const char *)str, "GL_ARB_texture_non_power_of_two");
-            g_GL_ARB_texture_non_power_of_two = pos != NULL;
-            VBOXQGLLOGREL (("GL_ARB_texture_non_power_of_two: %d\n", g_GL_ARB_texture_non_power_of_two));
-
-            vboxVHWAGlInitExtSupport(*pContext);
-
-            vboxVHWAGlInitFeatureSupport();
-        }
-    }
-    else
-    {
-        VBOXQGLLOGREL (("failed to make the context current, treating as unsupported\n"));
-    }
-
-
-    if(pTmpWidget)
-    {
-        delete pTmpWidget;
-    }
-}
-
-static bool vboxVHWASupportedInternal()
-{
-    if(g_vboxVHWAGlVersion <= 0)
-    {
-        /* error occurred while gl info initialization */
-        return false;
-    }
-
-#ifndef DEBUGVHWASTRICT
-    /* in case we do not support shaders & multitexturing we can not supprt dst colorkey,
-     * no sense to report Video Acceleration supported */
-    if(!g_vboxVHWAGlShaderSupported)
-        return false;
-#endif
-    if(g_vboxVHWAGlMultiTexNumSupported < 2)
-        return false;
-
-    /* color conversion now supported only GL_TEXTURE_RECTANGLE
-     * in this case only stretching is accelerated
-     * report as unsupported, TODO: probably should report as supported for stretch acceleration */
-    if(!g_vboxVHWAGlTextureRectangleSupported)
-        return false;
-
-    return true;
+        }
+    }
+    return g_VBoxVHWASupportInfo;
 }
 
@@ -913,17 +266,19 @@
 }
 
-static VBoxVHWATexture* vboxVHWATextureCreate(const QRect & aRect, const VBoxVHWAColorFormat & aFormat, bool bVGA)
-{
-    if(!bVGA && g_GL_ARB_pixel_buffer_object)
+static VBoxVHWATexture* vboxVHWATextureCreate(const QGLContext * pContext, const QRect & aRect, const VBoxVHWAColorFormat & aFormat, bool bVGA)
+{
+    const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(pContext);
+
+    if(!bVGA && info.getGlInfo().isPBOSupported())
     {
         VBOXQGLLOG(("VBoxVHWATextureNP2RectPBO\n"));
         return new VBoxVHWATextureNP2RectPBO(aRect, aFormat);
     }
-    else if(g_vboxVHWAGlTextureRectangleSupported)
+    else if(info.getGlInfo().isTextureRectangleSupported())
     {
         VBOXQGLLOG(("VBoxVHWATextureNP2Rect\n"));
         return new VBoxVHWATextureNP2Rect(aRect, aFormat);
     }
-    else if(g_GL_ARB_texture_non_power_of_two)
+    else if(info.getGlInfo().isTextureNP2Supported())
     {
         VBOXQGLLOG(("VBoxVHWATextureNP2\n"));
@@ -1856,10 +1211,10 @@
     resetDefaultSrcOverlayCKey();
 
-    mpTex[0] = vboxVHWATextureCreate(QRect(0,0,aSize.width(),aSize.height()), mColorFormat, bVGA);
+    mpTex[0] = vboxVHWATextureCreate(mWidget->context(), QRect(0,0,aSize.width(),aSize.height()), mColorFormat, bVGA);
     if(mColorFormat.fourcc() == FOURCC_YV12)
     {
         QRect rect(0,0,aSize.width()/2,aSize.height()/2);
-        mpTex[1] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
-        mpTex[2] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
+        mpTex[1] = vboxVHWATextureCreate(mWidget->context(), rect, mColorFormat, bVGA);
+        mpTex[2] = vboxVHWATextureCreate(mWidget->context(), rect, mColorFormat, bVGA);
     }
 
@@ -3350,4 +2705,6 @@
     VBOXQGLLOG_ENTER(("\n"));
 
+    const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
+
     if(!(pCmd->SurfInfo.flags & VBOXVHWA_SD_CAPS))
     {
@@ -3417,7 +2774,7 @@
             /* detect whether we support this format */
             bool bFound = false;
-            for(uint32_t i = 0; i < g_vboxVHWAFourccSupportedCount; i++)
+            for(int i = 0; i < info.getFourccSupportedCount(); i++)
             {
-                if(g_vboxVHWAFourccSupportedList[i] == pCmd->SurfInfo.PixelFormat.fourCC)
+                if(info.getFourccSupportedList()[i] == pCmd->SurfInfo.PixelFormat.fourCC)
                 {
                     bFound = true;
@@ -4083,5 +3440,6 @@
     VBOXQGLLOG_ENTER(("\n"));
     bool bEnabled = false;
-    if(vboxVHWASupportedInternal())
+    const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
+    if(info.isVHWASupported())
     {
         Assert(pCmd->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ);
@@ -4142,5 +3500,5 @@
                             ;
 
-        if(g_vboxVHWAGlShaderSupported && g_vboxVHWAGlMultiTexNumSupported >= 2)
+        if(info.getGlInfo().isFragmentShaderSupported() && info.getGlInfo().getMultiTexNumSupported() >= 2)
         {
             pCmd->u.out.caps |= VBOXVHWA_CAPS_COLORKEY
@@ -4155,5 +3513,5 @@
                             ;
 
-            if(g_vboxVHWAGlTextureRectangleSupported)
+            if(info.getGlInfo().isTextureRectangleSupported())
             {
                 pCmd->u.out.caps |= VBOXVHWA_CAPS_OVERLAYFOURCC
@@ -4168,5 +3526,5 @@
 //              pCmd->u.out.caps2 |= VBOXVHWA_CAPS2_COPYFOURCC;
 
-                pCmd->u.out.numFourCC = g_vboxVHWAFourccSupportedCount;
+                pCmd->u.out.numFourCC = info.getFourccSupportedCount();
             }
         }
@@ -4180,12 +3538,14 @@
     VBOXQGLLOG_ENTER(("\n"));
 
-    Assert(pCmd->numFourCC >= g_vboxVHWAFourccSupportedCount);
-    if(pCmd->numFourCC < g_vboxVHWAFourccSupportedCount)
+    const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
+
+    Assert(pCmd->numFourCC >= (uint32_t)info.getFourccSupportedCount());
+    if(pCmd->numFourCC < (uint32_t)info.getFourccSupportedCount())
         return VERR_GENERAL_FAILURE;
 
-    pCmd->numFourCC = g_vboxVHWAFourccSupportedCount;
-    for(uint32_t i = 0; i < g_vboxVHWAFourccSupportedCount; i++)
-    {
-        pCmd->FourCC[i] = g_vboxVHWAFourccSupportedList[i];
+    pCmd->numFourCC = (uint32_t)info.getFourccSupportedCount();
+    for(int i = 0; i < info.getFourccSupportedCount(); i++)
+    {
+        pCmd->FourCC[i] = info.getFourccSupportedList()[i];
     }
     return VINF_SUCCESS;
@@ -4708,5 +4068,5 @@
 void VBoxGLWidget::initializeGL()
 {
-    vboxVHWAGlInit(context());
+    vboxVHWAGetSupportInfo(context());
     VBoxVHWASurfaceBase::globalInit();
 }
@@ -5835,6 +5195,12 @@
 bool VBoxQGLOverlay::isAcceleration2DVideoAvailable()
 {
-    vboxVHWAGlInit(NULL);
-    return vboxVHWASupportedInternal();
+    static bool g_bVBoxVHWAChecked = false;
+    static bool g_bVBoxVHWASupported = false;
+    if(!g_bVBoxVHWAChecked)
+    {
+        g_bVBoxVHWAChecked = true;
+        g_bVBoxVHWASupported = VBoxVHWAInfo::checkVHWASupport();
+    }
+    return g_bVBoxVHWASupported;
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp	(revision 23732)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp	(revision 23732)
@@ -0,0 +1,639 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * OpenGL support info used for 2D support detection
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+#include "VBoxGLSupportInfo.h"
+
+#include <iprt/assert.h>
+#include <iprt/log.h>
+#include <iprt/err.h>
+#include <iprt/env.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/process.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+#include <iprt/thread.h>
+
+#include <QGLWidget>
+#include <QGLContext>
+
+/*****************/
+
+/* functions */
+
+PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture = NULL;
+PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i = NULL;
+PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d = NULL;
+PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f = NULL;
+
+
+PFNVBOXVHWA_CREATE_SHADER   vboxglCreateShader  = NULL;
+PFNVBOXVHWA_SHADER_SOURCE   vboxglShaderSource  = NULL;
+PFNVBOXVHWA_COMPILE_SHADER  vboxglCompileShader = NULL;
+PFNVBOXVHWA_DELETE_SHADER   vboxglDeleteShader  = NULL;
+
+PFNVBOXVHWA_CREATE_PROGRAM  vboxglCreateProgram = NULL;
+PFNVBOXVHWA_ATTACH_SHADER   vboxglAttachShader  = NULL;
+PFNVBOXVHWA_DETACH_SHADER   vboxglDetachShader  = NULL;
+PFNVBOXVHWA_LINK_PROGRAM    vboxglLinkProgram   = NULL;
+PFNVBOXVHWA_USE_PROGRAM     vboxglUseProgram    = NULL;
+PFNVBOXVHWA_DELETE_PROGRAM  vboxglDeleteProgram = NULL;
+
+PFNVBOXVHWA_IS_SHADER       vboxglIsShader      = NULL;
+PFNVBOXVHWA_GET_SHADERIV    vboxglGetShaderiv   = NULL;
+PFNVBOXVHWA_IS_PROGRAM      vboxglIsProgram     = NULL;
+PFNVBOXVHWA_GET_PROGRAMIV   vboxglGetProgramiv  = NULL;
+PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders = NULL;
+PFNVBOXVHWA_GET_SHADER_INFO_LOG  vboxglGetShaderInfoLog   = NULL;
+PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog  = NULL;
+
+PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation = NULL;
+
+PFNVBOXVHWA_UNIFORM1F vboxglUniform1f = NULL;
+PFNVBOXVHWA_UNIFORM2F vboxglUniform2f = NULL;
+PFNVBOXVHWA_UNIFORM3F vboxglUniform3f = NULL;
+PFNVBOXVHWA_UNIFORM4F vboxglUniform4f = NULL;
+
+PFNVBOXVHWA_UNIFORM1I vboxglUniform1i = NULL;
+PFNVBOXVHWA_UNIFORM2I vboxglUniform2i = NULL;
+PFNVBOXVHWA_UNIFORM3I vboxglUniform3i = NULL;
+PFNVBOXVHWA_UNIFORM4I vboxglUniform4i = NULL;
+
+PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers = NULL;
+PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers = NULL;
+PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer = NULL;
+PFNVBOXVHWA_BUFFER_DATA vboxglBufferData = NULL;
+PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer = NULL;
+PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer = NULL;
+
+#if 0
+#if defined Q_WS_WIN
+#define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)wglGetProcAddress(_n)
+#elif defined Q_WS_X11
+#include <GL/glx.h>
+#define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)glXGetProcAddress((const GLubyte *)(_n))
+#else
+#error "Port me!!!"
+#endif
+#endif
+
+#define VBOXVHWA_GETPROCADDRESS(_c, _t, _n) ((_t)(_c).getProcAddress(QString(_n)))
+
+#define VBOXVHWA_PFNINIT_SAME(_c, _t, _v, _rc) \
+    do { \
+        if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v)) == NULL) \
+        { \
+            VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v));\
+            AssertBreakpoint(); \
+            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
+            { \
+                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
+                AssertBreakpoint(); \
+                if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"EXT")) == NULL) \
+                { \
+                    VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"EXT"));\
+                    AssertBreakpoint(); \
+                    (_rc)++; \
+                } \
+            } \
+        } \
+    }while(0)
+
+#define VBOXVHWA_PFNINIT(_c, _t, _v, _f,_rc) \
+    do { \
+        if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_f)) == NULL) \
+        { \
+            VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_f));\
+            AssertBreakpoint(); \
+            (_rc)++; \
+        } \
+    }while(0)
+
+//#define VBOXVHWA_PFNINIT_OBJECT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ObjectARB" ,_rc)
+#define VBOXVHWA_PFNINIT_OBJECT_ARB(_c, _t, _v, _rc) \
+        do { \
+            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ObjectARB")) == NULL) \
+            { \
+                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ObjectARB"));\
+                AssertBreakpoint(); \
+                (_rc)++; \
+            } \
+        }while(0)
+
+//#define VBOXVHWA_PFNINIT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ARB" ,_rc)
+#define VBOXVHWA_PFNINIT_ARB(_c, _t, _v, _rc) \
+        do { \
+            if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
+            { \
+                VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
+                AssertBreakpoint(); \
+                (_rc)++; \
+            } \
+        }while(0)
+
+static int vboxVHWAGlParseSubver(const GLubyte * ver, const GLubyte ** pNext, bool bSpacePrefixAllowed)
+{
+    int val = 0;
+
+    for(;;++ver)
+    {
+        if(*ver >= '0' && *ver <= '9')
+        {
+            if(!val)
+            {
+                if(*ver == '0')
+                    continue;
+            }
+            else
+            {
+                val *= 10;
+            }
+            val += *ver - '0';
+        }
+        else if(*ver == '.')
+        {
+            *pNext = ver+1;
+            break;
+        }
+        else if(*ver == '\0')
+        {
+            *pNext = NULL;
+            break;
+        }
+        else if(*ver == ' ' || *ver == '\t' ||  *ver == 0x0d || *ver == 0x0a)
+        {
+            if(bSpacePrefixAllowed)
+            {
+                if(!val)
+                {
+                    continue;
+                }
+            }
+
+            /* treat this as the end ov version string */
+            *pNext = NULL;
+            break;
+        }
+        else
+        {
+            Assert(0);
+            val = -1;
+            break;
+        }
+    }
+
+    return val;
+}
+
+/* static */
+int VBoxGLInfo::parseVersion(const GLubyte * ver)
+{
+    int iVer = vboxVHWAGlParseSubver(ver, &ver, true);
+    if(iVer)
+    {
+        iVer <<= 16;
+        if(ver)
+        {
+            int tmp = vboxVHWAGlParseSubver(ver, &ver, false);
+            if(tmp >= 0)
+            {
+                iVer |= tmp << 8;
+                if(ver)
+                {
+                    tmp = vboxVHWAGlParseSubver(ver, &ver, false);
+                    if(tmp >= 0)
+                    {
+                        iVer |= tmp;
+                    }
+                    else
+                    {
+                        Assert(0);
+                        iVer = -1;
+                    }
+                }
+            }
+            else
+            {
+                Assert(0);
+                iVer = -1;
+            }
+        }
+    }
+    return iVer;
+}
+
+void VBoxGLInfo::init(const QGLContext * pContext)
+{
+    if(mInitialized)
+        return;
+
+    mInitialized = true;
+
+    if (!QGLFormat::hasOpenGL())
+    {
+        VBOXQGLLOGREL (("no gl support available\n"));
+        return;
+    }
+
+//    pContext->makeCurrent();
+
+    const GLubyte * str;
+    VBOXQGL_CHECKERR(
+            str = glGetString(GL_VERSION);
+            );
+
+    if(str)
+    {
+        VBOXQGLLOGREL (("gl version string: 0%s\n", str));
+
+        mGLVersion = parseVersion(str);
+        Assert(mGLVersion > 0);
+        if(mGLVersion < 0)
+        {
+            mGLVersion = 0;
+        }
+        else
+        {
+            VBOXQGLLOGREL (("gl version: 0x%x\n", mGLVersion));
+            VBOXQGL_CHECKERR(
+                    str = glGetString(GL_EXTENSIONS);
+                    );
+
+            const char * pos = strstr((const char *)str, "GL_ARB_multitexture");
+            m_GL_ARB_multitexture = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_multitexture: %d\n", m_GL_ARB_multitexture));
+
+            pos = strstr((const char *)str, "GL_ARB_shader_objects");
+            m_GL_ARB_shader_objects = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_shader_objects: %d\n", m_GL_ARB_shader_objects));
+
+            pos = strstr((const char *)str, "GL_ARB_fragment_shader");
+            m_GL_ARB_fragment_shader = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_fragment_shader: %d\n", m_GL_ARB_fragment_shader));
+
+            pos = strstr((const char *)str, "GL_ARB_pixel_buffer_object");
+            m_GL_ARB_pixel_buffer_object = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_pixel_buffer_object: %d\n", m_GL_ARB_pixel_buffer_object));
+
+            pos = strstr((const char *)str, "GL_ARB_texture_rectangle");
+            m_GL_ARB_texture_rectangle = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_texture_rectangle: %d\n", m_GL_ARB_texture_rectangle));
+
+            pos = strstr((const char *)str, "GL_EXT_texture_rectangle");
+            m_GL_EXT_texture_rectangle = pos != NULL;
+            VBOXQGLLOGREL (("GL_EXT_texture_rectangle: %d\n", m_GL_EXT_texture_rectangle));
+
+            pos = strstr((const char *)str, "GL_NV_texture_rectangle");
+            m_GL_NV_texture_rectangle = pos != NULL;
+            VBOXQGLLOGREL (("GL_NV_texture_rectangle: %d\n", m_GL_NV_texture_rectangle));
+
+            pos = strstr((const char *)str, "GL_ARB_texture_non_power_of_two");
+            m_GL_ARB_texture_non_power_of_two = pos != NULL;
+            VBOXQGLLOGREL (("GL_ARB_texture_non_power_of_two: %d\n", m_GL_ARB_texture_non_power_of_two));
+
+            initExtSupport(*pContext);
+        }
+    }
+    else
+    {
+        VBOXQGLLOGREL (("failed to make the context current, treating as unsupported\n"));
+    }
+}
+
+void VBoxGLInfo::initExtSupport(const QGLContext & context)
+{
+    int rc = 0;
+    do
+    {
+        rc = 0;
+        mMultiTexNumSupported = 1; /* default, 1 means not supported */
+        if(mGLVersion >= 0x010201) /* ogl >= 1.2.1 */
+        {
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
+        }
+        else if(m_GL_ARB_multitexture)
+        {
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
+        }
+        else
+        {
+            break;
+        }
+
+        if(RT_FAILURE(rc))
+            break;
+
+        GLint maxCoords, maxUnits;
+        glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxCoords);
+        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits);
+
+        VBOXQGLLOGREL(("Max Tex Coords (%d), Img Units (%d)\n", maxCoords, maxUnits));
+        /* take the minimum of those */
+        if(maxUnits < maxCoords)
+            maxCoords = maxUnits;
+        if(maxUnits < 2)
+        {
+            VBOXQGLLOGREL(("Max Tex Coord or Img Units < 2 disabling MultiTex support\n"));
+            break;
+        }
+
+        mMultiTexNumSupported = maxUnits;
+    }while(0);
+
+
+    do
+    {
+        rc = 0;
+        mPBOSupported = false;
+
+        if(m_GL_ARB_pixel_buffer_object)
+        {
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GEN_BUFFERS, GenBuffers, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_DELETE_BUFFERS, DeleteBuffers, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BIND_BUFFER, BindBuffer, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BUFFER_DATA, BufferData, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MAP_BUFFER, MapBuffer, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNMAP_BUFFER, UnmapBuffer, rc);
+        }
+        else
+        {
+            break;
+        }
+
+        if(RT_FAILURE(rc))
+            break;
+
+        mPBOSupported = true;
+    } while(0);
+
+    do
+    {
+        rc = 0;
+        mFragmentShaderSupported = false;
+
+        if(mGLVersion >= 0x020000)  /* if ogl >= 2.0*/
+        {
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, rc);
+
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, rc);
+
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_SHADER, IsShader, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders,  rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, rc);
+
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
+
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
+
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
+            VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
+        }
+        else if(m_GL_ARB_shader_objects && m_GL_ARB_fragment_shader)
+        {
+            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, DeleteObjectARB, rc);
+
+            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, AttachObjectARB, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, DetachObjectARB, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
+            VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, DeleteObjectARB, rc);
+
+        //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_SHADER, IsShader, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, GetObjectParameterivARB, rc);
+        //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, GetObjectParameterivARB, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders, GetAttachedObjectsARB, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, GetInfoLogARB, rc);
+            VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, GetInfoLogARB, rc);
+
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
+
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
+
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
+            VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
+        }
+        else
+        {
+            break;
+        }
+
+        if(RT_FAILURE(rc))
+            break;
+
+        mFragmentShaderSupported = true;
+    } while(0);
+
+    if(m_GL_ARB_texture_rectangle || m_GL_EXT_texture_rectangle || m_GL_NV_texture_rectangle)
+    {
+        mTextureRectangleSupported = true;
+    }
+    else
+    {
+        mTextureRectangleSupported = false;
+    }
+
+    mTextureNP2Supported = m_GL_ARB_texture_non_power_of_two;
+}
+
+void VBoxVHWAInfo::init(const QGLContext * pContext)
+{
+    if(mInitialized)
+        return;
+
+    mInitialized = true;
+
+    mglInfo.init(pContext);
+
+    if(mglInfo.isFragmentShaderSupported() && mglInfo.isTextureRectangleSupported())
+    {
+        uint32_t num = 0;
+        mFourccSupportedList[num++] = FOURCC_AYUV;
+        mFourccSupportedList[num++] = FOURCC_UYVY;
+        mFourccSupportedList[num++] = FOURCC_YUY2;
+        if(mglInfo.getMultiTexNumSupported() >= 4)
+        {
+            /* YV12 currently requires 3 units (for each color component)
+             * + 1 unit for dst texture for color-keying + 3 units for each color component
+             * TODO: we could store YV12 data in one texture to eliminate this requirement*/
+            mFourccSupportedList[num++] = FOURCC_YV12;
+        }
+
+        Assert(num <= VBOXVHWA_NUMFOURCC);
+        mFourccSupportedCount = num;
+    }
+    else
+    {
+        mFourccSupportedCount = 0;
+    }
+}
+
+bool VBoxVHWAInfo::isVHWASupported() const
+{
+    if(mglInfo.getGLVersion() <= 0)
+    {
+        /* error occurred while gl info initialization */
+        return false;
+    }
+
+#ifndef DEBUGVHWASTRICT
+    /* in case we do not support shaders & multitexturing we can not supprt dst colorkey,
+     * no sense to report Video Acceleration supported */
+    if(!mglInfo.isFragmentShaderSupported())
+        return false;
+#endif
+    if(mglInfo.getMultiTexNumSupported() < 2)
+        return false;
+
+    /* color conversion now supported only GL_TEXTURE_RECTANGLE
+     * in this case only stretching is accelerated
+     * report as unsupported, TODO: probably should report as supported for stretch acceleration */
+    if(!mglInfo.isTextureRectangleSupported())
+        return false;
+
+    return true;
+}
+
+/* static */
+bool VBoxVHWAInfo::checkVHWASupport()
+{
+#if defined(RT_OS_WINDOWS)
+    static char pszVBoxPath[RTPATH_MAX];
+    const char *papszArgs[3] = { NULL, "-test", NULL};
+    int rc;
+    RTPROCESS Process;
+    RTPROCSTATUS ProcStatus;
+    uint64_t StartTS;
+
+    rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX); AssertRCReturn(rc, false);
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+    rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL2D.exe");
+#else
+    rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL2D");
+#endif
+    AssertRCReturn(rc, false);
+    papszArgs[0] = pszVBoxPath;         /* argv[0] */
+
+    rc = RTProcCreate(pszVBoxPath, papszArgs, RTENV_DEFAULT, 0, &Process);
+    if (RT_FAILURE(rc))
+        return false;
+
+    StartTS = RTTimeMilliTS();
+
+    while (1)
+    {
+        rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
+        if (rc != VERR_PROCESS_RUNNING)
+            break;
+
+        if (RTTimeMilliTS() - StartTS > 30*1000 /* 30 sec */)
+        {
+            RTProcTerminate(Process);
+            RTThreadSleep(100);
+            RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
+            return false;
+        }
+        RTThreadSleep(100);
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        if ((ProcStatus.enmReason==RTPROCEXITREASON_NORMAL) && (ProcStatus.iStatus==0))
+        {
+            return true;
+        }
+    }
+
+    return false;
+#else
+    /* @todo: test & enable external app approach*/
+    VBoxGLTmpContext ctx;
+    const QGLContext *pContext = ctx.makeCurrent();
+    Assert(pContext);
+    if(pContext)
+    {
+        VBoxVHWAInfo info;
+        info.init(pContext);
+        return info.isVHWASupported();
+    }
+    return false;
+#endif
+}
+
+VBoxGLTmpContext::VBoxGLTmpContext()
+{
+    if(QGLFormat::hasOpenGL())
+    {
+        mWidget = new QGLWidget();
+    }
+    else
+    {
+        mWidget = NULL;
+    }
+}
+
+VBoxGLTmpContext::~VBoxGLTmpContext()
+{
+    if(mWidget)
+        delete mWidget;
+}
+
+const class QGLContext * VBoxGLTmpContext::makeCurrent()
+{
+    if(mWidget)
+    {
+        mWidget->makeCurrent();
+        return mWidget->context();
+    }
+    return NULL;
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxTestQGLApp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxTestQGLApp.cpp	(revision 23732)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxTestQGLApp.cpp	(revision 23732)
@@ -0,0 +1,62 @@
+/* $Id: $ */
+/** @file
+ * VBox host opengl support test application.
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifdef RT_OS_WINDOWS
+#include <Windows.h>
+#endif
+
+#include <iprt/initterm.h>
+//#include <iprt/assert.h>
+
+#include "VBoxGLSupportInfo.h"
+
+#include <QApplication>
+
+#ifndef RT_OS_WINDOWS
+int main(int argc, char **argv)
+{
+#else
+extern "C" int WINAPI WinMain(HINSTANCE hInstance,
+    HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nShowCmd*/)
+{
+    int argc = __argc;
+    char **argv =  __argv;
+#endif
+
+    RTR3Init();
+
+    int rc=1;
+
+    QApplication app (argc, argv);
+
+    VBoxGLTmpContext ctx;
+    const QGLContext *pContext = ctx.makeCurrent();
+    if(pContext)
+    {
+        VBoxVHWAInfo supportInfo;
+        supportInfo.init(pContext);
+        if(supportInfo.isVHWASupported())
+            rc = 0;
+    }
+
+    return rc;
+}
+
