VirtualBox

Changeset 20242 in vbox


Ignore:
Timestamp:
Jun 3, 2009 8:23:06 PM (16 years ago)
Author:
vboxsync
Message:

View HW Accel: OpenGL framebuffer

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm.h

    r19762 r20242  
    64546454DECLINLINE(unsigned) ASMBitLastSetS32(int32_t i32)
    64556455{
    6456     return ASMBitLastSetS32((uint32_t)i32);
     6456    return ASMBitLastSetU32((uint32_t)i32);
    64576457}
    64586458
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c

    r20009 r20242  
    711711}
    712712
    713 static void vboxVHWACommandCompletionCallbackEvent(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
     713static DECLCALLBACK(void) vboxVHWACommandCompletionCallbackEvent(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
    714714{
    715715    PEVENT pEvent = (PEVENT)pContext;
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r20078 r20242  
    186186endif
    187187ifdef VBOX_WITH_VIDEOHWACCEL
    188  VirtualBox_DEFS        += VBOX_WITH_VIDEOHWACCEL
     188 VirtualBox_DEFS        += VBOX_WITH_VIDEOHWACCEL \
     189            VBOX_GUI_USE_QGL
    189190endif
    190191
     
    223224ifeq ($(filter-out freebsd linux netbsd openbsd solaris,$(KBUILD_TARGET)),) # X11
    224225 VirtualBox_LIBS         += $(PATH_DLL)/VBoxKeyboard$(VBOX_SUFF_DLL)
     226endif
     227
     228ifdef VBOX_WITH_VIDEOHWACCEL
     229 VirtualBox_LIBS.win     += $(PATH_SDK_WINPSDK_LIB)/Opengl32.lib
    225230endif
    226231
     
    449454VirtualBox_QT_MODULES = Core Gui Network
    450455
     456ifdef VBOX_WITH_VIDEOHWACCEL
     457VirtualBox_QT_MODULES += OpenGL
     458endif
     459
    451460# Import QDesigner UI sources and translations from VBoxUI.pro.
    452461ifndef VBOX_WITH_REGISTRATION
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h

    r20139 r20242  
    8383    {
    8484        InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
     85#ifdef VBOX_WITH_VIDEOHWACCEL
     86        , QGLMode
     87#endif
    8588    };
    8689
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h

    r19844 r20242  
    3333#include <QPaintEvent>
    3434#include <QMoveEvent>
     35#if defined (VBOX_GUI_USE_QGL)
     36#include <QGLWidget>
     37#endif
    3538
    3639#if defined (VBOX_GUI_USE_SDL)
     
    313316/////////////////////////////////////////////////////////////////////////////
    314317
     318#if defined (VBOX_GUI_USE_QGL)
     319
     320#ifdef DEBUG
     321#define VBOXQGL_ASSERTNOERR() \
     322    do { GLenum err = glGetError(); \
     323        Assert(err == GL_NO_ERROR); \
     324    }while(0)
     325
     326#define VBOXQGL_CHECKERR(_op) \
     327    do { \
     328        glGetError(); \
     329        _op \
     330        VBOXQGL_ASSERTNOERR(); \
     331    }while(0)
     332#else
     333#define VBOXQGL_ASSERTNOERR() \
     334    do {}while(0)
     335
     336#define VBOXQGL_CHECKERR(_op) \
     337    do { \
     338        _op \
     339    }while(0)
     340#endif
     341class VBoxGLWidget : public QGLWidget
     342{
     343public:
     344    VBoxGLWidget (QWidget *aParent)
     345        : QGLWidget (aParent),
     346        mRe(NULL),
     347        mpIntersectionRect(NULL),
     348        mDisplay(0),
     349        mDisplayInitialized(false),
     350        mAddress(NULL),
     351        mTexture(0),
     352        mFormat(0),
     353        mInternalFormat(0),
     354        mType(0),
     355        mBitsPerPixel(0),
     356        mBytesPerPixel(0),
     357        mBytesPerLine(0),
     358        mPixelFormat(0),
     359        mUsesGuestVRAM(false),
     360        mDisplayWidth(0),
     361        mDisplayHeight(0)
     362    {
     363//        Assert(0);
     364        /* No need for background drawing */
     365//        setAttribute (Qt::WA_OpaquePaintEvent);
     366    }
     367
     368    ulong vboxPixelFormat() { return mPixelFormat; }
     369    bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
     370
     371    uchar *vboxAddress() { return mAddress; }
     372    ulong vboxBitsPerPixel() { return mBitsPerPixel; }
     373    ulong vboxBytesPerLine() { return mBytesPerLine; }
     374
     375    void vboxPaintEvent (QPaintEvent *pe);
     376    void vboxResizeEvent (VBoxResizeEvent *re);
     377
     378protected:
     379//    void resizeGL (int height, int width);
     380
     381    void paintGL();
     382
     383    void initializeGL();
     384
     385private:
     386    void vboxDoInitDisplay();
     387    void vboxDoDeleteDisplay();
     388    void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
     389
     390    void vboxDoResize(VBoxResizeEvent *re);
     391    void vboxDoPaint(const QRect *rec);
     392
     393    VBoxResizeEvent *mRe;
     394    const QRect *mpIntersectionRect;
     395    GLuint mDisplay;
     396    bool mDisplayInitialized;
     397    uchar * mAddress;
     398    GLuint mTexture;
     399
     400    GLenum mFormat;
     401    GLint  mInternalFormat;
     402    GLenum mType;
     403    ulong  mDisplayWidth;
     404    ulong  mDisplayHeight;
     405    ulong  mBitsPerPixel;
     406    ulong  mBytesPerPixel;
     407    ulong  mBytesPerLine;
     408    ulong  mPixelFormat;
     409    bool   mUsesGuestVRAM;
     410};
     411
     412
     413class VBoxQGLFrameBuffer : public VBoxFrameBuffer
     414{
     415public:
     416
     417    VBoxQGLFrameBuffer (VBoxConsoleView *aView);
     418
     419    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
     420                             ULONG aW, ULONG aH);
     421
     422    ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
     423    bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
     424
     425    uchar *address() { /*Assert(0); */return vboxWidget()->vboxAddress(); }
     426    ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
     427    ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
     428
     429    void paintEvent (QPaintEvent *pe);
     430    void resizeEvent (VBoxResizeEvent *re);
     431private:
     432    void vboxMakeCurrent();
     433    VBoxGLWidget * vboxWidget();
     434};
     435
     436
     437#endif
     438
     439/////////////////////////////////////////////////////////////////////////////
     440
    315441#if defined (VBOX_GUI_USE_SDL)
    316442
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r20200 r20242  
    789789    setFrameStyle (QFrame::NoFrame);
    790790
     791#ifndef VBOX_WITH_VIDEOHWACCEL
    791792    VBoxViewport *pViewport = new VBoxViewport (this);
     793#else
     794//    /* TODO: temporary always use VBoxGLWidget for debugging */
     795    VBoxGLWidget *pViewport = new VBoxGLWidget (this);
     796#endif
    792797    setViewport (pViewport);
     798//    pViewport->vboxDoInit();
    793799
    794800    /* enable MouseMove events */
     
    825831    switch (mode)
    826832    {
     833#if defined (VBOX_GUI_USE_QGL)
     834        case VBoxDefs::QGLMode:
     835            mFrameBuf = new VBoxQGLFrameBuffer (this);
     836            break;
     837#endif
    827838#if defined (VBOX_GUI_USE_QIMAGE)
    828839        case VBoxDefs::QImageMode:
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp

    r20080 r20242  
    2929/* Qt includes */
    3030#include <QPainter>
     31#if defined (VBOX_GUI_USE_QGL)
     32#include <QGLWidget>
     33
     34#include <iprt/asm.h>
     35#endif
    3136
    3237//
     
    430435        (new RemindEvent (re->bitsPerPixel()))->post();
    431436    }
     437}
     438
     439#endif
     440
     441//
     442// VBoxQGLFrameBuffer class
     443/////////////////////////////////////////////////////////////////////////////
     444
     445#if defined (VBOX_GUI_USE_QGL)
     446
     447#define VBOXQGLLOG(_m)
     448
     449/** @class VBoxQGLFrameBuffer
     450 *
     451 *  The VBoxQImageFrameBuffer class is a class that implements the IFrameBuffer
     452 *  interface and uses QImage as the direct storage for VM display data. QImage
     453 *  is then converted to QPixmap and blitted to the console view widget.
     454 */
     455
     456VBoxQGLFrameBuffer::VBoxQGLFrameBuffer (VBoxConsoleView *aView) :
     457    VBoxFrameBuffer (aView)
     458{
     459//    mWidget = new GLWidget(aView->viewport());
     460    resizeEvent (new VBoxResizeEvent (FramebufferPixelFormat_Opaque,
     461                                      NULL, 0, 0, 640, 480));
     462}
     463
     464/** @note This method is called on EMT from under this object's lock */
     465STDMETHODIMP VBoxQGLFrameBuffer::NotifyUpdate (ULONG aX, ULONG aY,
     466                                                  ULONG aW, ULONG aH)
     467{
     468    /* We're not on the GUI thread and update() isn't thread safe in
     469     * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
     470     * on Linux (didn't check Qt 4.x there) and probably on other
     471     * non-DOS platforms, so post the event instead. */
     472    QApplication::postEvent (mView,
     473                             new VBoxRepaintEvent (aX, aY, aW, aH));
     474
     475    return S_OK;
     476}
     477
     478void VBoxQGLFrameBuffer::vboxMakeCurrent()
     479{
     480    ((QGLWidget*)mView->viewport())->makeCurrent();
     481}
     482
     483VBoxGLWidget* VBoxQGLFrameBuffer::vboxWidget()
     484{
     485    return (VBoxGLWidget*)mView->viewport();
     486}
     487
     488void VBoxQGLFrameBuffer::paintEvent (QPaintEvent *pe)
     489{
     490    vboxWidget()->vboxPaintEvent(pe);
     491}
     492
     493static GLsizei  makePowerOf2(GLsizei val)
     494{
     495    int last = ASMBitLastSetS32(val);
     496    if(last>1)
     497    {
     498        last--;
     499        if((1 << last) != val)
     500        {
     501            Assert((1 << last) < val);
     502            val = (1 << (last+1));
     503        }
     504    }
     505    return val;
     506}
     507
     508void VBoxGLWidget::vboxResizeEvent (VBoxResizeEvent *re)
     509{
     510    VBOXQGLLOG(("-->resizing:  pixelFormat(%d), VRAM(0x%x), bitsPerPixel(%d), bytesPerLine(%d), width(%d),  height(%d)\n",
     511            re->pixelFormat(),
     512            re->VRAM(),
     513            re->bitsPerPixel(),
     514            re->bytesPerLine(),
     515            re->width(),
     516            re->height()));
     517    mRe = re;
     518    updateGL();
     519    mRe = NULL;
     520}
     521
     522void VBoxGLWidget::vboxPaintEvent (QPaintEvent *pe)
     523{
     524    mpIntersectionRect = &pe->rect();
     525    updateGL();
     526    mpIntersectionRect = NULL;
     527}
     528
     529void VBoxGLWidget::paintGL()
     530{
     531    if(mRe)
     532    {
     533        vboxDoResize(mRe);
     534    }
     535    else
     536    {
     537        vboxDoPaint(mpIntersectionRect);
     538    }
     539}
     540
     541void VBoxGLWidget::initializeGL()
     542{
     543    glEnable(GL_TEXTURE_2D);
     544    glGenTextures(1, &mTexture);
     545    VBOXQGL_ASSERTNOERR();
     546
     547    glBindTexture(GL_TEXTURE_2D, mTexture);
     548    VBOXQGL_ASSERTNOERR();
     549
     550    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     551    VBOXQGL_ASSERTNOERR();
     552    glPixelStorei(GL_PACK_ALIGNMENT, 1);
     553    VBOXQGL_ASSERTNOERR();
     554    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     555    VBOXQGL_ASSERTNOERR();
     556    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     557    VBOXQGL_ASSERTNOERR();
     558    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     559    VBOXQGL_ASSERTNOERR();
     560
     561    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
     562    VBOXQGL_ASSERTNOERR();
     563
     564    vboxDoInitDisplay();
     565}
     566
     567void VBoxGLWidget::vboxDoPaint(const QRect *rec)
     568{
     569    Assert(glIsTexture(mTexture));
     570    glBindTexture(GL_TEXTURE_2D, mTexture);
     571
     572    int x = rec->x();
     573    int y = rec->y();
     574    int width = rec->width();
     575    int height = rec->height();
     576
     577    VBOXQGLLOG(("x(%d), y(%d), width(%d), height(%d)\n", x, y, width, height));
     578    uchar * address = mAddress + y*mBytesPerLine + x*mBytesPerPixel;
     579
     580    VBOXQGL_CHECKERR(
     581            glPixelStorei(GL_PACK_ROW_LENGTH, mDisplayWidth);
     582            );
     583    VBOXQGL_CHECKERR(
     584            glPixelStorei(GL_UNPACK_ROW_LENGTH, mDisplayWidth);
     585            );
     586    VBOXQGL_CHECKERR(
     587            glTexSubImage2D(GL_TEXTURE_2D,
     588                0,
     589                x, y, width, height,
     590                mFormat,
     591                mType,
     592                address);
     593            );
     594
     595    vboxDoPerformDisplay();
     596}
     597
     598void VBoxGLWidget::vboxDoResize(VBoxResizeEvent *re)
     599{
     600    bool remind = false;
     601    bool fallback = false;
     602
     603    /* clean the old values first */
     604    if(mAddress)
     605    {
     606        if(!mUsesGuestVRAM)
     607        {
     608            if(mAddress)
     609            {
     610                free(mAddress);
     611            }
     612        }
     613    }
     614
     615    GLenum type;
     616    GLint internalformat;
     617    GLenum format;
     618
     619    /* check if we support the pixel format and can use the guest VRAM directly */
     620    if (re->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
     621    {
     622        mBitsPerPixel = re->bitsPerPixel();
     623        mBytesPerLine = re->bytesPerLine();
     624        ulong bitsPerLine = mBytesPerLine * 8;
     625
     626        switch (mBitsPerPixel)
     627        {
     628            case 32:
     629                internalformat = 3;//GL_RGB;
     630                format = GL_BGRA_EXT;//GL_RGBA;
     631                type = GL_UNSIGNED_BYTE;
     632                break;
     633            case 24:
     634                Assert(0);
     635                internalformat = 3;//GL_RGB;
     636                format = GL_BGR_EXT;
     637                type = GL_UNSIGNED_BYTE;
     638                remind = true;
     639                break;
     640            case 8:
     641                Assert(0);
     642                internalformat = 1;//GL_RGB;
     643                format = GL_BLUE;//GL_RGB;
     644                type = GL_UNSIGNED_BYTE;
     645                remind = true;
     646                break;
     647            case 1:
     648                Assert(0);
     649                internalformat = 1;
     650                format = GL_COLOR_INDEX;
     651                type = GL_BITMAP;
     652                remind = true;
     653                break;
     654            default:
     655                Assert(0);
     656                remind = true;
     657                fallback = true;
     658                break;
     659        }
     660
     661        if (!fallback)
     662        {
     663            /* QImage only supports 32-bit aligned scan lines... */
     664            Assert ((re->bytesPerLine() & 3) == 0);
     665            fallback = ((re->bytesPerLine() & 3) != 0);
     666        }
     667        if (!fallback)
     668        {
     669            /* ...and the scan lines ought to be a whole number of pixels. */
     670            Assert ((bitsPerLine & (re->bitsPerPixel() - 1)) == 0);
     671            fallback = ((bitsPerLine & (re->bitsPerPixel() - 1)) != 0);
     672        }
     673        if (!fallback)
     674        {
     675            ulong virtWdt = bitsPerLine / re->bitsPerPixel();
     676            mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
     677            mUsesGuestVRAM = true;
     678        }
     679    }
     680    else
     681    {
     682        fallback = true;
     683    }
     684
     685    if (fallback)
     686    {
     687        /* we don't support either the pixel format or the color depth,
     688         * fallback to a self-provided 32bpp RGB buffer */
     689        mBitsPerPixel = 32;
     690        mBytesPerLine = re->width()*mBitsPerPixel/8;
     691        mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
     692        internalformat = 3;//GL_RGB;
     693        format = GL_BGRA_EXT;//GL_RGBA;
     694        type = GL_UNSIGNED_BYTE;
     695        mUsesGuestVRAM = false;
     696    }
     697
     698    mFormat = format;
     699    mType = type;
     700    mInternalFormat = internalformat;
     701    mBytesPerPixel = mBitsPerPixel/8;
     702    mDisplayWidth = mBytesPerLine/mBytesPerPixel;
     703    mDisplayHeight = re->height();
     704
     705    GLsizei wdt = makePowerOf2(mDisplayWidth);
     706    GLsizei hgt = makePowerOf2(mDisplayHeight);
     707    Assert(wdt >= (GLsizei)mDisplayWidth);
     708    Assert(hgt >= (GLsizei)mDisplayHeight);
     709
     710    int size = wdt * hgt * (mBitsPerPixel/8);
     711    uchar * address = (uchar *)malloc(size);
     712    memset(address, 0, size);
     713
     714    glBindTexture(GL_TEXTURE_2D, mTexture);
     715    VBOXQGL_CHECKERR(
     716        glTexImage2D(GL_TEXTURE_2D,
     717                0,
     718                  internalformat,
     719                  wdt,
     720                  hgt,
     721                  0,
     722                  format,
     723                  type,
     724                  (GLvoid *)address);
     725        );
     726    glMatrixMode(GL_TEXTURE);
     727    glLoadIdentity();
     728    glScalef(((double)mDisplayWidth)/wdt, ((double)mDisplayHeight)/hgt, 1.0f);
     729    glMatrixMode(GL_MODELVIEW);
     730
     731    if(mUsesGuestVRAM)
     732    {
     733        mAddress = re->VRAM();
     734        free(address);
     735    }
     736    else
     737    {
     738        mAddress = address;
     739    }
     740
     741    glViewport(0, 0, mDisplayWidth, mDisplayHeight);
     742    glMatrixMode(GL_PROJECTION);
     743    glLoadIdentity();
     744    glFrustum(0., (GLdouble)mDisplayWidth, 0., (GLdouble)mDisplayHeight, 0., 0.);
     745    glMatrixMode(GL_MODELVIEW);
     746    glLoadIdentity();
     747
     748    if (remind)
     749    {
     750        class RemindEvent : public VBoxAsyncEvent
     751        {
     752            ulong mRealBPP;
     753        public:
     754            RemindEvent (ulong aRealBPP)
     755                : mRealBPP (aRealBPP) {}
     756            void handle()
     757            {
     758                vboxProblem().remindAboutWrongColorDepth (mRealBPP, 32);
     759            }
     760        };
     761        (new RemindEvent (re->bitsPerPixel()))->post();
     762    }
     763}
     764
     765void VBoxGLWidget::vboxDoInitDisplay()
     766{
     767    vboxDoDeleteDisplay();
     768    VBOXQGL_ASSERTNOERR();
     769
     770    mDisplay = glGenLists(1);
     771    VBOXQGL_ASSERTNOERR();
     772    glNewList(mDisplay, GL_COMPILE);
     773
     774    glBindTexture(GL_TEXTURE_2D, mTexture);
     775
     776    glBegin(GL_QUADS);
     777    glTexCoord2d(0, 0);
     778    glVertex2d(-1.0, 1.0);
     779    glTexCoord2d(0, 1);
     780    glVertex2d(-1.0, -1.0);
     781    glTexCoord2d(1, 1);
     782    glVertex2d(1.0, -1.0);
     783    glTexCoord2d(1, 0);
     784    glVertex2d(1.0, 1.0);
     785    glEnd();
     786
     787    glEndList();
     788    VBOXQGL_ASSERTNOERR();
     789    mDisplayInitialized = true;
     790}
     791
     792void VBoxGLWidget::vboxDoDeleteDisplay()
     793{
     794    if(mDisplayInitialized)
     795    {
     796        glDeleteLists(mDisplay, 1);
     797        mDisplayInitialized = false;
     798    }
     799}
     800
     801void VBoxQGLFrameBuffer::resizeEvent (VBoxResizeEvent *re)
     802{
     803    mWdt = re->width();
     804    mHgt = re->height();
     805
     806    vboxWidget()->vboxResizeEvent(re);
    432807}
    433808
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

    r20139 r20242  
    553553#endif
    554554    }
    555 
     555#ifdef VBOX_WITH_VIDEOHWACCEL
     556    /* temporary hack to enable QGL mode */
     557    mode = VBoxDefs::QGLMode;
     558#endif
    556559    return mode;
     560
    557561}
    558562
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette