Index: /trunk/include/iprt/asm.h
===================================================================
--- /trunk/include/iprt/asm.h	(revision 20241)
+++ /trunk/include/iprt/asm.h	(revision 20242)
@@ -6454,5 +6454,5 @@
 DECLINLINE(unsigned) ASMBitLastSetS32(int32_t i32)
 {
-    return ASMBitLastSetS32((uint32_t)i32);
+    return ASMBitLastSetU32((uint32_t)i32);
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 20241)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 20242)
@@ -711,5 +711,5 @@
 }
 
-static void vboxVHWACommandCompletionCallbackEvent(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
+static DECLCALLBACK(void) vboxVHWACommandCompletionCallbackEvent(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
 {
     PEVENT pEvent = (PEVENT)pContext;
Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 20242)
@@ -186,5 +186,6 @@
 endif
 ifdef VBOX_WITH_VIDEOHWACCEL
- VirtualBox_DEFS        += VBOX_WITH_VIDEOHWACCEL
+ VirtualBox_DEFS        += VBOX_WITH_VIDEOHWACCEL \
+            VBOX_GUI_USE_QGL
 endif
 
@@ -223,4 +224,8 @@
 ifeq ($(filter-out freebsd linux netbsd openbsd solaris,$(KBUILD_TARGET)),) # X11
  VirtualBox_LIBS         += $(PATH_DLL)/VBoxKeyboard$(VBOX_SUFF_DLL)
+endif
+
+ifdef VBOX_WITH_VIDEOHWACCEL
+ VirtualBox_LIBS.win     += $(PATH_SDK_WINPSDK_LIB)/Opengl32.lib
 endif
 
@@ -449,4 +454,8 @@
 VirtualBox_QT_MODULES = Core Gui Network
 
+ifdef VBOX_WITH_VIDEOHWACCEL
+VirtualBox_QT_MODULES += OpenGL
+endif
+
 # Import QDesigner UI sources and translations from VBoxUI.pro.
 ifndef VBOX_WITH_REGISTRATION
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 20242)
@@ -83,4 +83,7 @@
     {
         InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+        , QGLMode
+#endif
     };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 20242)
@@ -33,4 +33,7 @@
 #include <QPaintEvent>
 #include <QMoveEvent>
+#if defined (VBOX_GUI_USE_QGL)
+#include <QGLWidget>
+#endif
 
 #if defined (VBOX_GUI_USE_SDL)
@@ -313,4 +316,127 @@
 /////////////////////////////////////////////////////////////////////////////
 
+#if defined (VBOX_GUI_USE_QGL)
+
+#ifdef DEBUG
+#define VBOXQGL_ASSERTNOERR() \
+    do { GLenum err = glGetError(); \
+        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
+class VBoxGLWidget : public QGLWidget
+{
+public:
+    VBoxGLWidget (QWidget *aParent)
+        : QGLWidget (aParent),
+        mRe(NULL),
+        mpIntersectionRect(NULL),
+        mDisplay(0),
+        mDisplayInitialized(false),
+        mAddress(NULL),
+        mTexture(0),
+        mFormat(0),
+        mInternalFormat(0),
+        mType(0),
+        mBitsPerPixel(0),
+        mBytesPerPixel(0),
+        mBytesPerLine(0),
+        mPixelFormat(0),
+        mUsesGuestVRAM(false),
+        mDisplayWidth(0),
+        mDisplayHeight(0)
+    {
+//        Assert(0);
+        /* No need for background drawing */
+//        setAttribute (Qt::WA_OpaquePaintEvent);
+    }
+
+    ulong vboxPixelFormat() { return mPixelFormat; }
+    bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
+
+    uchar *vboxAddress() { return mAddress; }
+    ulong vboxBitsPerPixel() { return mBitsPerPixel; }
+    ulong vboxBytesPerLine() { return mBytesPerLine; }
+
+    void vboxPaintEvent (QPaintEvent *pe);
+    void vboxResizeEvent (VBoxResizeEvent *re);
+
+protected:
+//    void resizeGL (int height, int width);
+
+    void paintGL();
+
+    void initializeGL();
+
+private:
+    void vboxDoInitDisplay();
+    void vboxDoDeleteDisplay();
+    void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
+
+    void vboxDoResize(VBoxResizeEvent *re);
+    void vboxDoPaint(const QRect *rec);
+
+    VBoxResizeEvent *mRe;
+    const QRect *mpIntersectionRect;
+    GLuint mDisplay;
+    bool mDisplayInitialized;
+    uchar * mAddress;
+    GLuint mTexture;
+
+    GLenum mFormat;
+    GLint  mInternalFormat;
+    GLenum mType;
+    ulong  mDisplayWidth;
+    ulong  mDisplayHeight;
+    ulong  mBitsPerPixel;
+    ulong  mBytesPerPixel;
+    ulong  mBytesPerLine;
+    ulong  mPixelFormat;
+    bool   mUsesGuestVRAM;
+};
+
+
+class VBoxQGLFrameBuffer : public VBoxFrameBuffer
+{
+public:
+
+    VBoxQGLFrameBuffer (VBoxConsoleView *aView);
+
+    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
+                             ULONG aW, ULONG aH);
+
+    ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
+    bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
+
+    uchar *address() { /*Assert(0); */return vboxWidget()->vboxAddress(); }
+    ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
+    ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
+
+    void paintEvent (QPaintEvent *pe);
+    void resizeEvent (VBoxResizeEvent *re);
+private:
+    void vboxMakeCurrent();
+    VBoxGLWidget * vboxWidget();
+};
+
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
 #if defined (VBOX_GUI_USE_SDL)
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 20242)
@@ -789,6 +789,12 @@
     setFrameStyle (QFrame::NoFrame);
 
+#ifndef VBOX_WITH_VIDEOHWACCEL
     VBoxViewport *pViewport = new VBoxViewport (this);
+#else
+//    /* TODO: temporary always use VBoxGLWidget for debugging */
+    VBoxGLWidget *pViewport = new VBoxGLWidget (this);
+#endif
     setViewport (pViewport);
+//    pViewport->vboxDoInit();
 
     /* enable MouseMove events */
@@ -825,4 +831,9 @@
     switch (mode)
     {
+#if defined (VBOX_GUI_USE_QGL)
+        case VBoxDefs::QGLMode:
+            mFrameBuf = new VBoxQGLFrameBuffer (this);
+            break;
+#endif
 #if defined (VBOX_GUI_USE_QIMAGE)
         case VBoxDefs::QImageMode:
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 20242)
@@ -29,4 +29,9 @@
 /* Qt includes */
 #include <QPainter>
+#if defined (VBOX_GUI_USE_QGL)
+#include <QGLWidget>
+
+#include <iprt/asm.h>
+#endif
 
 //
@@ -430,4 +435,374 @@
         (new RemindEvent (re->bitsPerPixel()))->post();
     }
+}
+
+#endif
+
+//
+// VBoxQGLFrameBuffer class
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined (VBOX_GUI_USE_QGL)
+
+#define VBOXQGLLOG(_m)
+
+/** @class VBoxQGLFrameBuffer
+ *
+ *  The VBoxQImageFrameBuffer class is a class that implements the IFrameBuffer
+ *  interface and uses QImage as the direct storage for VM display data. QImage
+ *  is then converted to QPixmap and blitted to the console view widget.
+ */
+
+VBoxQGLFrameBuffer::VBoxQGLFrameBuffer (VBoxConsoleView *aView) :
+    VBoxFrameBuffer (aView)
+{
+//    mWidget = new GLWidget(aView->viewport());
+    resizeEvent (new VBoxResizeEvent (FramebufferPixelFormat_Opaque,
+                                      NULL, 0, 0, 640, 480));
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP VBoxQGLFrameBuffer::NotifyUpdate (ULONG aX, ULONG aY,
+                                                  ULONG aW, ULONG aH)
+{
+    /* We're not on the GUI thread and update() isn't thread safe in
+     * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
+     * on Linux (didn't check Qt 4.x there) and probably on other
+     * non-DOS platforms, so post the event instead. */
+    QApplication::postEvent (mView,
+                             new VBoxRepaintEvent (aX, aY, aW, aH));
+
+    return S_OK;
+}
+
+void VBoxQGLFrameBuffer::vboxMakeCurrent()
+{
+    ((QGLWidget*)mView->viewport())->makeCurrent();
+}
+
+VBoxGLWidget* VBoxQGLFrameBuffer::vboxWidget()
+{
+    return (VBoxGLWidget*)mView->viewport();
+}
+
+void VBoxQGLFrameBuffer::paintEvent (QPaintEvent *pe)
+{
+    vboxWidget()->vboxPaintEvent(pe);
+}
+
+static GLsizei  makePowerOf2(GLsizei val)
+{
+    int last = ASMBitLastSetS32(val);
+    if(last>1)
+    {
+        last--;
+        if((1 << last) != val)
+        {
+            Assert((1 << last) < val);
+            val = (1 << (last+1));
+        }
+    }
+    return val;
+}
+
+void VBoxGLWidget::vboxResizeEvent (VBoxResizeEvent *re)
+{
+    VBOXQGLLOG(("-->resizing:  pixelFormat(%d), VRAM(0x%x), bitsPerPixel(%d), bytesPerLine(%d), width(%d),  height(%d)\n",
+            re->pixelFormat(),
+            re->VRAM(),
+            re->bitsPerPixel(),
+            re->bytesPerLine(),
+            re->width(),
+            re->height()));
+    mRe = re;
+    updateGL();
+    mRe = NULL;
+}
+
+void VBoxGLWidget::vboxPaintEvent (QPaintEvent *pe)
+{
+    mpIntersectionRect = &pe->rect();
+    updateGL();
+    mpIntersectionRect = NULL;
+}
+
+void VBoxGLWidget::paintGL()
+{
+    if(mRe)
+    {
+        vboxDoResize(mRe);
+    }
+    else
+    {
+        vboxDoPaint(mpIntersectionRect);
+    }
+}
+
+void VBoxGLWidget::initializeGL()
+{
+    glEnable(GL_TEXTURE_2D);
+    glGenTextures(1, &mTexture);
+    VBOXQGL_ASSERTNOERR();
+
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+    VBOXQGL_ASSERTNOERR();
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    VBOXQGL_ASSERTNOERR();
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    VBOXQGL_ASSERTNOERR();
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    VBOXQGL_ASSERTNOERR();
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    VBOXQGL_ASSERTNOERR();
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    VBOXQGL_ASSERTNOERR();
+
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+    VBOXQGL_ASSERTNOERR();
+
+    vboxDoInitDisplay();
+}
+
+void VBoxGLWidget::vboxDoPaint(const QRect *rec)
+{
+    Assert(glIsTexture(mTexture));
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+
+    int x = rec->x();
+    int y = rec->y();
+    int width = rec->width();
+    int height = rec->height();
+
+    VBOXQGLLOG(("x(%d), y(%d), width(%d), height(%d)\n", x, y, width, height));
+    uchar * address = mAddress + y*mBytesPerLine + x*mBytesPerPixel;
+
+    VBOXQGL_CHECKERR(
+            glPixelStorei(GL_PACK_ROW_LENGTH, mDisplayWidth);
+            );
+    VBOXQGL_CHECKERR(
+            glPixelStorei(GL_UNPACK_ROW_LENGTH, mDisplayWidth);
+            );
+    VBOXQGL_CHECKERR(
+            glTexSubImage2D(GL_TEXTURE_2D,
+                0,
+                x, y, width, height,
+                mFormat,
+                mType,
+                address);
+            );
+
+    vboxDoPerformDisplay();
+}
+
+void VBoxGLWidget::vboxDoResize(VBoxResizeEvent *re)
+{
+    bool remind = false;
+    bool fallback = false;
+
+    /* clean the old values first */
+    if(mAddress)
+    {
+        if(!mUsesGuestVRAM)
+        {
+            if(mAddress)
+            {
+                free(mAddress);
+            }
+        }
+    }
+
+    GLenum type;
+    GLint internalformat;
+    GLenum format;
+
+    /* check if we support the pixel format and can use the guest VRAM directly */
+    if (re->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
+    {
+        mBitsPerPixel = re->bitsPerPixel();
+        mBytesPerLine = re->bytesPerLine();
+        ulong bitsPerLine = mBytesPerLine * 8;
+
+        switch (mBitsPerPixel)
+        {
+            case 32:
+                internalformat = 3;//GL_RGB;
+                format = GL_BGRA_EXT;//GL_RGBA;
+                type = GL_UNSIGNED_BYTE;
+                break;
+            case 24:
+                Assert(0);
+                internalformat = 3;//GL_RGB;
+                format = GL_BGR_EXT;
+                type = GL_UNSIGNED_BYTE;
+                remind = true;
+                break;
+            case 8:
+                Assert(0);
+                internalformat = 1;//GL_RGB;
+                format = GL_BLUE;//GL_RGB;
+                type = GL_UNSIGNED_BYTE;
+                remind = true;
+                break;
+            case 1:
+                Assert(0);
+                internalformat = 1;
+                format = GL_COLOR_INDEX;
+                type = GL_BITMAP;
+                remind = true;
+                break;
+            default:
+                Assert(0);
+                remind = true;
+                fallback = true;
+                break;
+        }
+
+        if (!fallback)
+        {
+            /* QImage only supports 32-bit aligned scan lines... */
+            Assert ((re->bytesPerLine() & 3) == 0);
+            fallback = ((re->bytesPerLine() & 3) != 0);
+        }
+        if (!fallback)
+        {
+            /* ...and the scan lines ought to be a whole number of pixels. */
+            Assert ((bitsPerLine & (re->bitsPerPixel() - 1)) == 0);
+            fallback = ((bitsPerLine & (re->bitsPerPixel() - 1)) != 0);
+        }
+        if (!fallback)
+        {
+            ulong virtWdt = bitsPerLine / re->bitsPerPixel();
+            mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+            mUsesGuestVRAM = true;
+        }
+    }
+    else
+    {
+        fallback = true;
+    }
+
+    if (fallback)
+    {
+        /* we don't support either the pixel format or the color depth,
+         * fallback to a self-provided 32bpp RGB buffer */
+        mBitsPerPixel = 32;
+        mBytesPerLine = re->width()*mBitsPerPixel/8;
+        mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+        internalformat = 3;//GL_RGB;
+        format = GL_BGRA_EXT;//GL_RGBA;
+        type = GL_UNSIGNED_BYTE;
+        mUsesGuestVRAM = false;
+    }
+
+    mFormat = format;
+    mType = type;
+    mInternalFormat = internalformat;
+    mBytesPerPixel = mBitsPerPixel/8;
+    mDisplayWidth = mBytesPerLine/mBytesPerPixel;
+    mDisplayHeight = re->height();
+
+    GLsizei wdt = makePowerOf2(mDisplayWidth);
+    GLsizei hgt = makePowerOf2(mDisplayHeight);
+    Assert(wdt >= (GLsizei)mDisplayWidth);
+    Assert(hgt >= (GLsizei)mDisplayHeight);
+
+    int size = wdt * hgt * (mBitsPerPixel/8);
+    uchar * address = (uchar *)malloc(size);
+    memset(address, 0, size);
+
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+    VBOXQGL_CHECKERR(
+        glTexImage2D(GL_TEXTURE_2D,
+                0,
+                  internalformat,
+                  wdt,
+                  hgt,
+                  0,
+                  format,
+                  type,
+                  (GLvoid *)address);
+        );
+    glMatrixMode(GL_TEXTURE);
+    glLoadIdentity();
+    glScalef(((double)mDisplayWidth)/wdt, ((double)mDisplayHeight)/hgt, 1.0f);
+    glMatrixMode(GL_MODELVIEW);
+
+    if(mUsesGuestVRAM)
+    {
+        mAddress = re->VRAM();
+        free(address);
+    }
+    else
+    {
+        mAddress = address;
+    }
+
+    glViewport(0, 0, mDisplayWidth, mDisplayHeight);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(0., (GLdouble)mDisplayWidth, 0., (GLdouble)mDisplayHeight, 0., 0.);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    if (remind)
+    {
+        class RemindEvent : public VBoxAsyncEvent
+        {
+            ulong mRealBPP;
+        public:
+            RemindEvent (ulong aRealBPP)
+                : mRealBPP (aRealBPP) {}
+            void handle()
+            {
+                vboxProblem().remindAboutWrongColorDepth (mRealBPP, 32);
+            }
+        };
+        (new RemindEvent (re->bitsPerPixel()))->post();
+    }
+}
+
+void VBoxGLWidget::vboxDoInitDisplay()
+{
+    vboxDoDeleteDisplay();
+    VBOXQGL_ASSERTNOERR();
+
+    mDisplay = glGenLists(1);
+    VBOXQGL_ASSERTNOERR();
+    glNewList(mDisplay, GL_COMPILE);
+
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+
+    glBegin(GL_QUADS);
+    glTexCoord2d(0, 0);
+    glVertex2d(-1.0, 1.0);
+    glTexCoord2d(0, 1);
+    glVertex2d(-1.0, -1.0);
+    glTexCoord2d(1, 1);
+    glVertex2d(1.0, -1.0);
+    glTexCoord2d(1, 0);
+    glVertex2d(1.0, 1.0);
+    glEnd();
+
+    glEndList();
+    VBOXQGL_ASSERTNOERR();
+    mDisplayInitialized = true;
+}
+
+void VBoxGLWidget::vboxDoDeleteDisplay()
+{
+    if(mDisplayInitialized)
+    {
+        glDeleteLists(mDisplay, 1);
+        mDisplayInitialized = false;
+    }
+}
+
+void VBoxQGLFrameBuffer::resizeEvent (VBoxResizeEvent *re)
+{
+    mWdt = re->width();
+    mHgt = re->height();
+
+    vboxWidget()->vboxResizeEvent(re);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 20241)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 20242)
@@ -553,6 +553,10 @@
 #endif
     }
-
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    /* temporary hack to enable QGL mode */
+    mode = VBoxDefs::QGLMode;
+#endif
     return mode;
+
 }
 
