VirtualBox

Changeset 22816 in vbox


Ignore:
Timestamp:
Sep 7, 2009 6:08:33 PM (15 years ago)
Author:
vboxsync
Message:

video 2d accel: move overlay functionality to a separate class/files, make it easy to reuse with different framebuffers

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r22629 r22816  
    484484if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_GUI_USE_QGL)
    485485 VirtualBox_SOURCES += \
    486         src/VBoxFBQGL.cpp
     486        src/VBoxFBQGL.cpp \
     487    src/VBoxFBOverlay.cpp
    487488endif
    488489# The Qt modules we're using.
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h

    r22737 r22816  
    7272                     const CConsole &console,
    7373                     VBoxDefs::RenderMode rm,
     74#ifdef VBOX_WITH_VIDEOHWACCEL
     75                     bool accelerate2DVideo,
     76#endif
    7477                     QWidget *parent = 0);
    7578    ~VBoxConsoleView();
     
    295298
    296299    VBoxDefs::RenderMode mode;
     300#ifdef VBOX_WITH_VIDEOHWACCEL
     301    bool mAccelerate2DVideo;
     302#endif
    297303
    298304    QRegion mLastVisibleRegion;
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h

    r22794 r22816  
    8484        InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
    8585#ifdef VBOX_GUI_USE_QGL
    86         , QGLMode, QGLOverlayMode
     86        , QGLMode
    8787#endif
    8888    };
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h

    r22800 r22816  
    3535#include <QMoveEvent>
    3636#if defined (VBOX_GUI_USE_QGL)
    37 #include <QGLWidget>
     37#include "VBoxFBOverlay.h"
    3838#endif
    3939
     
    296296#if defined (VBOX_GUI_USE_QGL)
    297297
    298 #ifdef DEBUG
    299 #include "iprt/stream.h"
    300 #define VBOXQGLLOG(_m) RTPrintf _m
    301 #define VBOXQGLLOGREL(_m) do { RTPrintf _m ; LogRel( _m ); } while(0)
    302 #else
    303 #define VBOXQGLLOG(_m)
    304 #define VBOXQGLLOGREL(_m) LogRel( _m )
    305 #endif
    306 #define VBOXQGLLOG_ENTER(_m)
    307 //do{VBOXQGLLOG(("==>[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
    308 #define VBOXQGLLOG_EXIT(_m)
    309 //do{VBOXQGLLOG(("<==[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
    310 #ifdef DEBUG
    311 #define VBOXQGL_ASSERTNOERR() \
    312     do { GLenum err = glGetError(); \
    313         if(err != GL_NO_ERROR) VBOXQGLLOG(("gl error ocured (0x%x)\n", err)); \
    314         Assert(err == GL_NO_ERROR); \
    315     }while(0)
    316 
    317 #define VBOXQGL_CHECKERR(_op) \
    318     do { \
    319         glGetError(); \
    320         _op \
    321         VBOXQGL_ASSERTNOERR(); \
    322     }while(0)
    323 #else
    324 #define VBOXQGL_ASSERTNOERR() \
    325     do {}while(0)
    326 
    327 #define VBOXQGL_CHECKERR(_op) \
    328     do { \
    329         _op \
    330     }while(0)
    331 #endif
    332 
    333 #ifdef DEBUG
    334 #include <iprt/time.h>
    335 
    336 #define VBOXGETTIME() RTTimeNanoTS()
    337 
    338 #define VBOXPRINTDIF(_nano, _m) do{\
    339         uint64_t cur = VBOXGETTIME(); \
    340         VBOXQGLLOG(_m); \
    341         VBOXQGLLOG(("(%Lu)\n", cur - (_nano))); \
    342     }while(0)
    343 
    344 class VBoxVHWADbgTimeCounter
    345 {
    346 public:
    347     VBoxVHWADbgTimeCounter(const char* msg) {mTime = VBOXGETTIME(); mMsg=msg;}
    348     ~VBoxVHWADbgTimeCounter() {VBOXPRINTDIF(mTime, (mMsg));}
    349 private:
    350     uint64_t mTime;
    351     const char* mMsg;
    352 };
    353 
    354 #define VBOXQGLLOG_METHODTIME(_m) VBoxVHWADbgTimeCounter _dbgTimeCounter(_m)
    355 #else
    356 #define VBOXQGLLOG_METHODTIME(_m)
    357 #endif
    358 
    359 #define VBOXQGLLOG_QRECT(_p, _pr, _s) do{\
    360     VBOXQGLLOG((_p " x(%d), y(%d), w(%d), h(%d)" _s, (_pr)->x(), (_pr)->y(), (_pr)->width(), (_pr)->height()));\
    361     }while(0)
    362 
    363 #define VBOXQGLLOG_CKEY(_p, _pck, _s) do{\
    364     VBOXQGLLOG((_p " l(0x%x), u(0x%x)" _s, (_pck)->lower(), (_pck)->upper()));\
    365     }while(0)
    366 
    367 class VBoxVHWADirtyRect
    368 {
    369 public:
    370     VBoxVHWADirtyRect() :
    371         mIsClear(true)
    372     {}
    373 
    374     VBoxVHWADirtyRect(const QRect & aRect)
    375     {
    376         if(aRect.isEmpty())
    377         {
    378             mIsClear = false;
    379             mRect = aRect;
    380         }
    381         else
    382         {
    383             mIsClear = true;
    384         }
    385     }
    386 
    387     bool isClear() const { return mIsClear; }
    388 
    389     void add(const QRect & aRect)
    390     {
    391         if(aRect.isEmpty())
    392             return;
    393 
    394         mRect = mIsClear ? aRect : mRect.united(aRect);
    395         mIsClear = false;
    396     }
    397 
    398     void add(const VBoxVHWADirtyRect & aRect)
    399     {
    400         if(aRect.isClear())
    401             return;
    402         add(aRect.rect());
    403     }
    404 
    405     void set(const QRect & aRect)
    406     {
    407         if(aRect.isEmpty())
    408         {
    409             mIsClear = true;
    410         }
    411         else
    412         {
    413             mRect = aRect;
    414             mIsClear = false;
    415         }
    416     }
    417 
    418     void clear() { mIsClear = true; }
    419 
    420     const QRect & rect() const {return mRect;}
    421 
    422     const QRect & toRect()
    423     {
    424         if(isClear())
    425         {
    426             mRect.setCoords(0, 0, -1, -1);
    427         }
    428         return mRect;
    429     }
    430 
    431     bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
    432 
    433     bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
    434 
    435     QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
    436 
    437     bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
    438 
    439     void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
    440 
    441 private:
    442     QRect mRect;
    443     bool mIsClear;
    444 };
    445 
    446 class VBoxVHWAColorKey
    447 {
    448 public:
    449     VBoxVHWAColorKey() :
    450         mUpper(0),
    451         mLower(0)
    452     {}
    453 
    454     VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
    455         mUpper(aUpper),
    456         mLower(aLower)
    457     {}
    458 
    459     uint32_t upper() const {return mUpper; }
    460     uint32_t lower() const {return mLower; }
    461 
    462     bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
    463 private:
    464     uint32_t mUpper;
    465     uint32_t mLower;
    466 };
    467 
    468 class VBoxVHWAColorComponent
    469 {
    470 public:
    471     VBoxVHWAColorComponent() :
    472         mMask(0),
    473         mRange(0),
    474         mOffset(32),
    475         mcBits(0)
    476     {}
    477 
    478     VBoxVHWAColorComponent(uint32_t aMask);
    479 
    480     uint32_t mask() const { return mMask; }
    481     uint32_t range() const { return mRange; }
    482     uint32_t offset() const { return mOffset; }
    483     uint32_t cBits() const { return mcBits; }
    484     uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
    485     float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
    486 private:
    487     uint32_t mMask;
    488     uint32_t mRange;
    489     uint32_t mOffset;
    490     uint32_t mcBits;
    491 };
    492 
    493 class VBoxVHWAColorFormat
    494 {
    495 public:
    496 
    497 //    VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
    498     VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
    499     VBoxVHWAColorFormat(uint32_t fourcc);
    500     VBoxVHWAColorFormat(){}
    501     GLint internalFormat() const {return mInternalFormat; }
    502     GLenum format() const {return mFormat; }
    503     GLenum type() const {return mType; }
    504     bool isValid() const {return mBitsPerPixel != 0; }
    505     uint32_t fourcc() const {return mDataFormat;}
    506     uint32_t bitsPerPixel() const { return mBitsPerPixel; }
    507     uint32_t bitsPerPixelTex() const { return mBitsPerPixelTex; }
    508 //    uint32_t bitsPerPixelDd() const { return mBitsPerPixelDd; }
    509     void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
    510     uint32_t widthCompression() const {return mWidthCompression;}
    511     uint32_t heightCompression() const {return mHeightCompression;}
    512     const VBoxVHWAColorComponent& r() const {return mR;}
    513     const VBoxVHWAColorComponent& g() const {return mG;}
    514     const VBoxVHWAColorComponent& b() const {return mB;}
    515     const VBoxVHWAColorComponent& a() const {return mA;}
    516 
    517     bool equals (const VBoxVHWAColorFormat & other) const;
    518 
    519 private:
    520     void init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
    521     void init(uint32_t fourcc);
    522 
    523     GLint mInternalFormat;
    524     GLenum mFormat;
    525     GLenum mType;
    526     uint32_t mDataFormat;
    527 
    528     uint32_t mBitsPerPixel;
    529     uint32_t mBitsPerPixelTex;
    530 //    uint32_t mBitsPerPixelDd;
    531     uint32_t mWidthCompression;
    532     uint32_t mHeightCompression;
    533     VBoxVHWAColorComponent mR;
    534     VBoxVHWAColorComponent mG;
    535     VBoxVHWAColorComponent mB;
    536     VBoxVHWAColorComponent mA;
    537 };
    538 
    539 class VBoxVHWATexture
    540 {
    541 public:
    542     VBoxVHWATexture() {}
    543     VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat);
    544     virtual ~VBoxVHWATexture();
    545     virtual void init(uchar *pvMem);
    546     void setAddress(uchar *pvMem) {mAddress = pvMem;}
    547     void update(const QRect * pRect) { doUpdate(mAddress, pRect);}
    548     void bind() {glBindTexture(texTarget(), mTexture);}
    549 
    550     virtual void texCoord(int x, int y);
    551     virtual void multiTexCoord(GLenum texUnit, int x, int y);
    552 
    553 //    GLuint texture() {return mTexture;}
    554     const QRect & texRect() {return mTexRect;}
    555     const QRect & rect() {return mRect;}
    556     uchar * address(){ return mAddress; }
    557     uint32_t rectSizeTex(const QRect * pRect) {return pRect->width() * pRect->height() * mBytesPerPixelTex;}
    558     uchar * pointAddress(int x, int y)
    559     {
    560         x = toXTex(x);
    561         y = toYTex(y);
    562         return pointAddressTex(x, y);
    563     }
    564     uint32_t pointOffsetTex(int x, int y) { return y*mBytesPerLine + x*mBytesPerPixelTex; }
    565     uchar * pointAddressTex(int x, int y) { return mAddress + pointOffsetTex(x, y); }
    566     int toXTex(int x) {return x/mColorFormat.widthCompression();}
    567     int toYTex(int y) {return y/mColorFormat.heightCompression();}
    568     ulong memSize(){ return mBytesPerLine * mRect.height(); }
    569     uint32_t bytesPerLine() {return mBytesPerLine; }
    570 
    571 protected:
    572     virtual void doUpdate(uchar * pAddress, const QRect * pRect);
    573     virtual void initParams();
    574     virtual void load();
    575     virtual GLenum texTarget() {return GL_TEXTURE_2D; }
    576 
    577 
    578     QRect mTexRect; /* texture size */
    579     QRect mRect; /* img size */
    580     uchar * mAddress;
    581     GLuint mTexture;
    582     uint32_t mBytesPerPixel;
    583     uint32_t mBytesPerPixelTex;
    584     uint32_t mBytesPerLine;
    585     VBoxVHWAColorFormat mColorFormat;
    586 private:
    587     void uninit();
    588 };
    589 
    590 class VBoxVHWATextureNP2 : public VBoxVHWATexture
    591 {
    592 public:
    593     VBoxVHWATextureNP2() : VBoxVHWATexture() {}
    594     VBoxVHWATextureNP2(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
    595         VBoxVHWATexture(aRect, aFormat){
    596         mTexRect = QRect(0, 0, aRect.width()/aFormat.widthCompression(), aRect.height()/aFormat.heightCompression());
    597     }
    598 };
    599 
    600 class VBoxVHWATextureNP2Rect : public VBoxVHWATextureNP2
    601 {
    602 public:
    603     VBoxVHWATextureNP2Rect() : VBoxVHWATextureNP2() {}
    604     VBoxVHWATextureNP2Rect(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
    605         VBoxVHWATextureNP2(aRect, aFormat){}
    606 
    607     virtual void texCoord(int x, int y);
    608     virtual void multiTexCoord(GLenum texUnit, int x, int y);
    609 protected:
    610     virtual GLenum texTarget();
    611 };
    612 
    613 class VBoxVHWATextureNP2RectPBO : public VBoxVHWATextureNP2Rect
    614 {
    615 public:
    616         VBoxVHWATextureNP2RectPBO() : VBoxVHWATextureNP2Rect() {}
    617         VBoxVHWATextureNP2RectPBO(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
    618                 VBoxVHWATextureNP2Rect(aRect, aFormat){}
    619     virtual ~VBoxVHWATextureNP2RectPBO();
    620 
    621     virtual void init(uchar *pvMem);
    622 protected:
    623     virtual void load();
    624     virtual void doUpdate(uchar * pAddress, const QRect * pRect);
    625 private:
    626     GLuint mPBO;
    627 };
    628 
    629 class VBoxVHWAHandleTable
    630 {
    631 public:
    632     VBoxVHWAHandleTable(uint32_t initialSize);
    633     ~VBoxVHWAHandleTable();
    634     uint32_t put(void * data);
    635     bool mapPut(uint32_t h, void * data);
    636     void* get(uint32_t h);
    637     void* remove(uint32_t h);
    638 private:
    639     void doPut(uint32_t h, void * data);
    640     void doRemove(uint32_t h);
    641     void** mTable;
    642     uint32_t mcSize;
    643     uint32_t mcUsage;
    644     uint32_t mCursor;
    645 };
    646 
    647 /* data flow:
    648  * I. NON-Yinverted surface:
    649  * 1.direct memory update (paint, lock/unlock):
    650  *  mem->tex->fb
    651  * 2.blt
    652  *  srcTex->invFB->tex->fb
    653  *              |->mem
    654  *
    655  * II. Yinverted surface:
    656  * 1.direct memory update (paint, lock/unlock):
    657  *  mem->tex->fb
    658  * 2.blt
    659  *  srcTex->fb->tex
    660  *           |->mem
    661  *
    662  * III. flip support:
    663  * 1. Yinverted<->NON-YInverted conversion :
    664  *  mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
    665  *  fb-->|                                                           |->mem
    666  * */
    667 class VBoxVHWASurfaceBase
    668 {
    669 public:
    670     VBoxVHWASurfaceBase(
    671             class VBoxGLWidget *mWidget,
    672 #if 0
    673             class VBoxVHWAGlContextState *aState,
    674             bool aIsYInverted,
    675 #endif
    676             const QSize & aSize,
    677             const QRect & aTargRect,
    678             const QRect & aSrcRect,
    679             const QRect & aVisTargRect,
    680             VBoxVHWAColorFormat & aColorFormat,
    681             VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
    682             VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
    683             bool bVGA);
    684 
    685     virtual ~VBoxVHWASurfaceBase();
    686 
    687     void init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
    688 
    689     void uninit();
    690 
    691     static void globalInit();
    692 
    693 //    int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
    694 
    695     int lock(const QRect * pRect, uint32_t flags);
    696 
    697     int unlock();
    698 
    699     void updatedMem(const QRect * aRect);
    700 
    701     void performDisplay(VBoxVHWASurfaceBase *pPrimary);
    702 
    703     void setRects(VBoxVHWASurfaceBase *pPrimary, const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisibleTargRect, bool bForceReinit);
    704     void setTargRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint & aPoint, const QRect & aVisibleTargRect);
    705     void updateVisibleTargRect(VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect);
    706 
    707     static ulong calcBytesPerPixel(GLenum format, GLenum type);
    708 
    709     static GLsizei makePowerOf2(GLsizei val);
    710 
    711     bool    addressAlocated() const { return mFreeAddress; }
    712     uchar * address(){ return mAddress; }
    713 
    714     ulong   memSize();
    715 
    716     ulong width()  { return mRect.width();  }
    717     ulong height() { return mRect.height(); }
    718     const QSize size() {return mRect.size();}
    719 
    720     GLenum format() {return mColorFormat.format(); }
    721     GLint  internalFormat() { return mColorFormat.internalFormat(); }
    722     GLenum type() { return mColorFormat.type(); }
    723     uint32_t fourcc() {return mColorFormat.fourcc(); }
    724 
    725 //    ulong  bytesPerPixel() { return mpTex[0]->bytesPerPixel(); }
    726     ulong  bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
    727 //    ulong  bitsPerPixelDd() { return mColorFormat.bitsPerPixelDd(); }
    728     ulong  bytesPerLine() { return mpTex[0]->bytesPerLine(); }
    729 
    730     const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
    731     const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
    732     const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
    733     const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
    734     const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
    735     const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
    736     void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
    737     void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
    738 
    739     void setDstBltCKey(const VBoxVHWAColorKey * ckey)
    740     {
    741         if(ckey)
    742         {
    743             mDstBltCKey = *ckey;
    744             mpDstBltCKey = &mDstBltCKey;
    745         }
    746         else
    747         {
    748             mpDstBltCKey = NULL;
    749         }
    750     }
    751 
    752     void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
    753     {
    754         if(ckey)
    755         {
    756             mSrcBltCKey = *ckey;
    757             mpSrcBltCKey = &mSrcBltCKey;
    758         }
    759         else
    760         {
    761             mpSrcBltCKey = NULL;
    762         }
    763     }
    764 
    765     void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
    766     {
    767         if(ckey)
    768         {
    769             mDefaultDstOverlayCKey = *ckey;
    770             mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
    771         }
    772         else
    773         {
    774             mpDefaultDstOverlayCKey = NULL;
    775         }
    776     }
    777 
    778     void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
    779     {
    780         if(ckey)
    781         {
    782             mDefaultSrcOverlayCKey = *ckey;
    783             mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
    784         }
    785         else
    786         {
    787             mpDefaultSrcOverlayCKey = NULL;
    788         }
    789     }
    790 
    791     void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
    792     {
    793         if(ckey)
    794         {
    795             mOverriddenDstOverlayCKey = *ckey;
    796             mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
    797         }
    798         else
    799         {
    800             mpDstOverlayCKey = NULL;
    801         }
    802     }
    803 
    804     void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
    805     {
    806         if(ckey)
    807         {
    808             mOverriddenSrcOverlayCKey = *ckey;
    809             mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
    810         }
    811         else
    812         {
    813             mpSrcOverlayCKey = NULL;
    814         }
    815     }
    816 
    817     const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
    818     {
    819         return mpSrcOverlayCKey;
    820     }
    821 
    822     const VBoxVHWAColorKey * getActiveDstOverlayCKey(VBoxVHWASurfaceBase * pPrimary)
    823     {
    824         return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : pPrimary->mpDstOverlayCKey;
    825     }
    826 
    827     const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
    828 
    829     void setAddress(uchar * addr);
    830 
    831     const QRect& rect() const {return mRect;}
    832     const QRect& srcRect() const {return mSrcRect; }
    833     const QRect& targRect() const {return mTargRect; }
    834     class VBoxVHWASurfList * getComplexList() {return mComplexList; }
    835 
    836     class VBoxVHWAGlProgramMngr * getGlProgramMngr();
    837     static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
    838 
    839     uint32_t handle() const {return mHGHandle;}
    840     void setHandle(uint32_t h) {mHGHandle = h;}
    841 
    842 private:
    843     void doSetRectValuesInternal(const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect);
    844 
    845     void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
    846     void initDisplay(VBoxVHWASurfaceBase *pPrimary);
    847     void deleteDisplay();
    848 
    849     GLuint createDisplay(VBoxVHWASurfaceBase *pPrimary);
    850     void doDisplay(VBoxVHWASurfaceBase *pPrimary, VBoxVHWAGlProgramVHWA * pProgram, bool bBindDst);
    851     void synchTexMem(const QRect * aRect);
    852 
    853     int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
    854 
    855     void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
    856     void doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex);
    857     void doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex);
    858 
    859     QRect mRect; /* == Inv FB size */
    860 
    861     QRect mSrcRect;
    862     QRect mTargRect; /* == Vis FB size */
    863 
    864     QRect mVisibleTargRect;
    865     QRect mVisibleSrcRect;
    866 
    867     GLuint mVisibleDisplay;
    868 
    869     bool mVisibleDisplayInitialized;
    870 
    871     uchar * mAddress;
    872     VBoxVHWATexture *mpTex[3];
    873 
    874     VBoxVHWAColorFormat mColorFormat;
    875 
    876     VBoxVHWAColorKey *mpSrcBltCKey;
    877     VBoxVHWAColorKey *mpDstBltCKey;
    878     VBoxVHWAColorKey *mpSrcOverlayCKey;
    879     VBoxVHWAColorKey *mpDstOverlayCKey;
    880 
    881     VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
    882     VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
    883 
    884     VBoxVHWAColorKey mSrcBltCKey;
    885     VBoxVHWAColorKey mDstBltCKey;
    886     VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
    887     VBoxVHWAColorKey mOverriddenDstOverlayCKey;
    888     VBoxVHWAColorKey mDefaultDstOverlayCKey;
    889     VBoxVHWAColorKey mDefaultSrcOverlayCKey;
    890 
    891     int mLockCount;
    892     /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock  */
    893     VBoxVHWADirtyRect mUpdateMem2TexRect;
    894 
    895     bool mFreeAddress;
    896 
    897     class VBoxVHWASurfList *mComplexList;
    898 
    899     class VBoxGLWidget *mWidget;
    900 
    901     uint32_t mHGHandle;
    902 
    903 #ifdef DEBUG
    904 public:
    905     uint64_t cFlipsCurr;
    906     uint64_t cFlipsTarg;
    907 #endif
    908     friend class VBoxVHWASurfList;
    909 };
    910 
    911 typedef std::list <VBoxVHWASurfaceBase*> SurfList;
    912 typedef std::list <VBoxVHWASurfList*> OverlayList;
    913 typedef std::list <struct _VBOXVHWACMD *> VHWACommandList;
    914 
    915 class VBoxVHWASurfList
    916 {
    917 public:
    918 
    919     VBoxVHWASurfList() : mCurrent(NULL) {}
    920     void add(VBoxVHWASurfaceBase *pSurf)
    921     {
    922         VBoxVHWASurfList * pOld = pSurf->getComplexList();
    923         if(pOld)
    924         {
    925             pOld->remove(pSurf);
    926         }
    927         mSurfaces.push_back(pSurf);
    928         pSurf->setComplexList(this);
    929     }
    930 
    931     void clear()
    932     {
    933         for (SurfList::iterator it = mSurfaces.begin();
    934              it != mSurfaces.end(); ++ it)
    935         {
    936             (*it)->setComplexList(NULL);
    937         }
    938         mSurfaces.clear();
    939         mCurrent = NULL;
    940     }
    941 
    942     size_t size() const {return mSurfaces.size(); }
    943 
    944     void remove(VBoxVHWASurfaceBase *pSurf)
    945     {
    946         mSurfaces.remove(pSurf);
    947         pSurf->setComplexList(NULL);
    948         if(mCurrent == pSurf)
    949             mCurrent = NULL;
    950     }
    951 
    952     bool empty() { return mSurfaces.empty(); }
    953 
    954     void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
    955     {
    956         mCurrent = pSurf;
    957     }
    958 
    959     VBoxVHWASurfaceBase * current() { return mCurrent; }
    960     const SurfList & surfaces() const {return mSurfaces;}
    961 
    962 private:
    963 
    964     SurfList mSurfaces;
    965     VBoxVHWASurfaceBase* mCurrent;
    966 };
    967 
    968 class VBoxVHWADisplay
    969 {
    970 public:
    971     VBoxVHWADisplay() :
    972         mSurfVGA(NULL)
    973 //        ,
    974 //        mSurfPrimary(NULL)
    975     {}
    976 
    977     VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
    978     {
    979         VBoxVHWASurfaceBase * old = mSurfVGA;
    980         mSurfVGA = pVga;
    981         mPrimary.clear();
    982         if(pVga)
    983         {
    984             Assert(!pVga->getComplexList());
    985             mPrimary.add(pVga);
    986             mPrimary.setCurrentVisible(pVga);
    987         }
    988 //        mSurfPrimary = pVga;
    989         mOverlays.clear();
    990         return old;
    991     }
    992 
    993     VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
    994     {
    995         VBoxVHWASurfaceBase * old = mSurfVGA;
    996         Assert(old);
    997         mSurfVGA = pVga;
    998         return old;
    999     }
    1000 
    1001     VBoxVHWASurfaceBase * getVGA() const
    1002     {
    1003         return mSurfVGA;
    1004     }
    1005 
    1006     VBoxVHWASurfaceBase * getPrimary()
    1007     {
    1008         return mPrimary.current();
    1009     }
    1010 
    1011     void addOverlay(VBoxVHWASurfList * pSurf)
    1012     {
    1013         mOverlays.push_back(pSurf);
    1014     }
    1015 
    1016     void checkAddOverlay(VBoxVHWASurfList * pSurf)
    1017     {
    1018         if(!hasOverlay(pSurf))
    1019             addOverlay(pSurf);
    1020     }
    1021 
    1022     bool hasOverlay(VBoxVHWASurfList * pSurf)
    1023     {
    1024         for (OverlayList::iterator it = mOverlays.begin();
    1025              it != mOverlays.end(); ++ it)
    1026         {
    1027             if((*it) == pSurf)
    1028             {
    1029                 return true;
    1030             }
    1031         }
    1032         return false;
    1033     }
    1034 
    1035     void removeOverlay(VBoxVHWASurfList * pSurf)
    1036     {
    1037         mOverlays.remove(pSurf);
    1038     }
    1039 
    1040     void performDisplay()
    1041     {
    1042         VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
    1043         pPrimary->performDisplay(NULL);
    1044 
    1045         for (OverlayList::const_iterator it = mOverlays.begin();
    1046              it != mOverlays.end(); ++ it)
    1047         {
    1048             VBoxVHWASurfaceBase * pOverlay = (*it)->current();
    1049             if(pOverlay)
    1050             {
    1051                 pOverlay->performDisplay(pPrimary);
    1052             }
    1053         }
    1054     }
    1055 
    1056     const OverlayList & overlays() const {return mOverlays;}
    1057     const VBoxVHWASurfList & primaries() const { return mPrimary; }
    1058 
    1059 private:
    1060     VBoxVHWASurfaceBase *mSurfVGA;
    1061     VBoxVHWASurfList mPrimary;
    1062 
    1063     OverlayList mOverlays;
    1064 };
    1065 
    1066 typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
    1067 
    1068 typedef void (*PFNVBOXQGLFUNC)(void*, void*);
    1069 
    1070 typedef enum
    1071 {
    1072     VBOXVHWA_PIPECMD_PAINT = 1,
    1073     VBOXVHWA_PIPECMD_VHWA,
    1074     VBOXVHWA_PIPECMD_OP,
    1075     VBOXVHWA_PIPECMD_FUNC,
    1076 }VBOXVHWA_PIPECMD_TYPE;
    1077 
    1078 typedef struct VBOXVHWACALLBACKINFO
    1079 {
    1080     VBoxGLWidget *pThis;
    1081     PFNVBOXQGLOP pfnCallback;
    1082     void * pContext;
    1083 }VBOXVHWACALLBACKINFO;
    1084 
    1085 typedef struct VBOXVHWAFUNCCALLBACKINFO
    1086 {
    1087     PFNVBOXQGLFUNC pfnCallback;
    1088     void * pContext1;
    1089     void * pContext2;
    1090 }VBOXVHWAFUNCCALLBACKINFO;
    1091 
    1092 class VBoxVHWACommandElement
    1093 {
    1094 public:
    1095     void setVHWACmd(struct _VBOXVHWACMD * pCmd)
    1096     {
    1097         mType = VBOXVHWA_PIPECMD_VHWA;
    1098         u.mpCmd = pCmd;
    1099     }
    1100 
    1101     void setPaintCmd(const QRect & aRect)
    1102     {
    1103         mType = VBOXVHWA_PIPECMD_PAINT;
    1104         mRect = aRect;
    1105     }
    1106 
    1107     void setOp(const VBOXVHWACALLBACKINFO & aOp)
    1108     {
    1109         mType = VBOXVHWA_PIPECMD_OP;
    1110         u.mCallback = aOp;
    1111     }
    1112 
    1113     void setFunc(const VBOXVHWAFUNCCALLBACKINFO & aOp)
    1114     {
    1115         mType = VBOXVHWA_PIPECMD_FUNC;
    1116         u.mFuncCallback = aOp;
    1117     }
    1118 
    1119     void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
    1120     {
    1121         switch(aType)
    1122         {
    1123         case VBOXVHWA_PIPECMD_PAINT:
    1124             setPaintCmd(*((QRect*)pvData));
    1125             break;
    1126         case VBOXVHWA_PIPECMD_VHWA:
    1127             setVHWACmd((struct _VBOXVHWACMD *)pvData);
    1128             break;
    1129         case VBOXVHWA_PIPECMD_OP:
    1130             setOp(*((VBOXVHWACALLBACKINFO *)pvData));
    1131             break;
    1132         case VBOXVHWA_PIPECMD_FUNC:
    1133             setFunc(*((VBOXVHWAFUNCCALLBACKINFO *)pvData));
    1134             break;
    1135         default:
    1136             Assert(0);
    1137             break;
    1138         }
    1139     }
    1140 
    1141     VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
    1142     const QRect & rect() const {return mRect;}
    1143     struct _VBOXVHWACMD * vhwaCmd() const {return u.mpCmd;}
    1144     const VBOXVHWACALLBACKINFO & op() const {return u.mCallback; }
    1145     const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
    1146 
    1147     VBoxVHWACommandElement * mpNext;
    1148 private:
    1149     VBOXVHWA_PIPECMD_TYPE mType;
    1150     union
    1151     {
    1152         struct _VBOXVHWACMD * mpCmd;
    1153         VBOXVHWACALLBACKINFO mCallback;
    1154         VBOXVHWAFUNCCALLBACKINFO mFuncCallback;
    1155     }u;
    1156     QRect                 mRect;
    1157 };
    1158 
    1159 class VBoxVHWACommandElementPipe
    1160 {
    1161 public:
    1162     VBoxVHWACommandElementPipe() :
    1163         mpFirst(NULL),
    1164         mpLast(NULL)
    1165     {}
    1166 
    1167     void put(VBoxVHWACommandElement *pCmd)
    1168     {
    1169         if(mpLast)
    1170         {
    1171             Assert(mpFirst);
    1172             mpLast->mpNext = pCmd;
    1173             mpLast = pCmd;
    1174         }
    1175         else
    1176         {
    1177             Assert(!mpFirst);
    1178             mpFirst = pCmd;
    1179             mpLast = pCmd;
    1180         }
    1181         pCmd->mpNext= NULL;
    1182 
    1183     }
    1184 
    1185     VBoxVHWACommandElement * detachList()
    1186     {
    1187         if(mpLast)
    1188         {
    1189             VBoxVHWACommandElement * pHead = mpFirst;
    1190             mpFirst = NULL;
    1191             mpLast = NULL;
    1192             return pHead;
    1193         }
    1194         return NULL;
    1195     }
    1196 private:
    1197     VBoxVHWACommandElement *mpFirst;
    1198     VBoxVHWACommandElement *mpLast;
    1199 };
    1200 
    1201 class VBoxVHWACommandElementStack
    1202 {
    1203 public:
    1204     VBoxVHWACommandElementStack() :
    1205         mpFirst(NULL) {}
    1206 
    1207     void push(VBoxVHWACommandElement *pCmd)
    1208     {
    1209         pCmd->mpNext = mpFirst;
    1210         mpFirst = pCmd;
    1211     }
    1212 
    1213     void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
    1214     {
    1215         pLast->mpNext = mpFirst;
    1216         mpFirst = pFirst;
    1217     }
    1218 
    1219     VBoxVHWACommandElement * pop()
    1220     {
    1221         if(mpFirst)
    1222         {
    1223             VBoxVHWACommandElement * ret = mpFirst;
    1224             mpFirst = ret->mpNext;
    1225             return ret;
    1226         }
    1227         return NULL;
    1228     }
    1229 private:
    1230     VBoxVHWACommandElement *mpFirst;
    1231 };
    1232 
    1233 class VBoxVHWACommandElementProcessor
    1234 {
    1235 public:
    1236     VBoxVHWACommandElementProcessor(VBoxConsoleView *aView);
    1237     ~VBoxVHWACommandElementProcessor();
    1238     void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
    1239     class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
    1240 
    1241 private:
    1242     RTCRITSECT mCritSect;
    1243     class VBoxVHWACommandProcessEvent *mpFirstEvent;
    1244     class VBoxVHWACommandProcessEvent *mpLastEvent;
    1245     VBoxConsoleView *mView;
    1246     bool mbNewEvent;
    1247     VBoxVHWACommandElementStack mFreeElements;
    1248     VBoxVHWACommandElement mElementsBuffer[2048];
    1249 };
    1250 
    1251 class VBoxVHWACommandsQueue
    1252 {
    1253 public:
    1254     void enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2);
    1255 
    1256     VBoxVHWACommandElement * detachList();
    1257 
    1258     void freeList(VBoxVHWACommandElement * pList);
    1259 
    1260 private:
    1261     VBoxVHWACommandElementPipe mCmds;
    1262 };
    1263 
    1264 class VBoxGLWidget : public QGLWidget
    1265 {
    1266 public:
    1267     VBoxGLWidget (VBoxConsoleView *aView, QWidget *aParent);
    1268     ~VBoxGLWidget();
    1269 
    1270     ulong vboxPixelFormat() { return mPixelFormat; }
    1271     bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
    1272 
    1273     uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
    1274 
    1275 #ifdef VBOX_WITH_VIDEOHWACCEL
    1276     uchar *vboxVRAMAddressFromOffset(uint64_t offset);
    1277     uint64_t vboxVRAMOffsetFromAddress(uchar* addr);
    1278     uint64_t vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf);
    1279 
    1280     void vhwaSaveExec(struct SSMHANDLE * pSSM);
    1281     int vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
    1282 
    1283     int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
    1284     int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
    1285     int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
    1286     int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
    1287     int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
    1288     int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
    1289     int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
    1290     int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
    1291     int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
    1292     int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
    1293     int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
    1294     int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
    1295     int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
    1296 
    1297     bool hasSurfaces() const;
    1298     bool hasVisibleOverlays();
    1299     const QRect & overlaysRectUnion();
    1300 #endif
    1301 
    1302     ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
    1303     ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
    1304     int vboxFbWidth() {return mDisplay.getVGA()->width(); }
    1305     int vboxFbHeight() {return mDisplay.getVGA()->height(); }
    1306     bool vboxIsInitialized() {return mDisplay.getVGA() != NULL; }
    1307 
    1308 //    void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
    1309     void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
    1310 
    1311     void vboxProcessVHWACommands(class VBoxVHWACommandElementProcessor * pPipe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pPipe);}
    1312 #ifdef VBOX_WITH_VIDEOHWACCEL
    1313     void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
    1314 #endif
    1315     class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
    1316 
    1317     VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
    1318 
    1319     static void doSetupMatrix(const QSize & aSize, bool bInverted);
    1320 
    1321     void vboxDoUpdateViewport(const QRect & aRect);
    1322     void vboxDoUpdateRect(const QRect * pRect);
    1323 
    1324     const QRect & vboxViewport() const {return mViewport;}
    1325 
    1326     void performDisplay() { mDisplay.performDisplay(); }
    1327 protected:
    1328 
    1329     void paintGL()
    1330     {
    1331         if(mpfnOp)
    1332         {
    1333             (this->*mpfnOp)(mOpContext);
    1334             mpfnOp = NULL;
    1335         }
    1336 //        else
    1337 //        {
    1338             mDisplay.performDisplay();
    1339 //        }
    1340     }
    1341 
    1342     void initializeGL();
    1343 
    1344 private:
    1345     static void setupMatricies(const QSize &display);
    1346     static void adjustViewport(const QSize &display, const QRect &viewport);
    1347     void vboxDoResize(void *re);
    1348 //    void vboxDoPaint(void *rec);
    1349 
    1350 
    1351 #ifdef VBOXQGL_DBG_SURF
    1352     void vboxDoTestSurfaces(void *context);
    1353 #endif
    1354 #ifdef VBOX_WITH_VIDEOHWACCEL
    1355     void vboxDoVHWACmdExec(void *cmd);
    1356     void vboxDoVHWACmdAndFree(void *cmd);
    1357     void vboxDoVHWACmd(void *cmd);
    1358 
    1359     void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
    1360     {
    1361         if (pSurface->addressAlocated())
    1362         {
    1363             uchar * addr = vboxVRAMAddressFromOffset(offset);
    1364             if(addr)
    1365             {
    1366                 pSurface->setAddress(addr);
    1367             }
    1368         }
    1369     }
    1370 
    1371     int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
    1372     int vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
    1373     int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
    1374     int vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
    1375     void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
    1376 #endif
    1377     static const QGLFormat & vboxGLFormat();
    1378 
    1379     VBoxVHWADisplay mDisplay;
    1380 
    1381 
    1382     /* we do all opengl stuff in the paintGL context,
    1383      * submit the operation to be performed
    1384      * @todo: could be moved outside the updateGL */
    1385     void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext)
    1386     {
    1387         mpfnOp = pfn;
    1388         mOpContext = pContext;
    1389         updateGL();
    1390     }
    1391 
    1392 //    /* posts op to UI thread */
    1393 //    int vboxExecOpSynch(PFNVBOXQGLOP pfn, void* pContext);
    1394 //    void vboxExecOnResize(PFNVBOXQGLOP pfn, void* pContext);
    1395 
    1396     void vboxDoProcessVHWACommands(void *pContext);
    1397 
    1398     class VBoxVHWACommandElement * processCmdList(class VBoxVHWACommandElement * pCmd);
    1399 
    1400     VBoxVHWASurfaceBase* handle2Surface(uint32_t h)
    1401     {
    1402         VBoxVHWASurfaceBase* pSurf = (VBoxVHWASurfaceBase*)mSurfHandleTable.get(h);
    1403         Assert(pSurf);
    1404         return pSurf;
    1405     }
    1406 
    1407     VBoxVHWAHandleTable mSurfHandleTable;
    1408 
    1409     PFNVBOXQGLOP mpfnOp;
    1410     void *mOpContext;
    1411 
    1412     ulong  mPixelFormat;
    1413     bool   mUsesGuestVRAM;
    1414 //    bool   mbVGASurfCreated;
    1415     QRect mViewport;
    1416 
    1417     VBoxConsoleView *mView;
    1418 
    1419     VBoxVHWASurfList *mConstructingList;
    1420     int32_t mcRemaining2Contruct;
    1421 
    1422     /* this is used in saved state restore to postpone surface restoration
    1423      * till the framebuffer size is restored */
    1424     VHWACommandList mOnResizeCmdList;
    1425 
    1426     class VBoxVHWAGlProgramMngr *mpMngr;
    1427 };
    1428 
    1429 
    1430298class VBoxQGLFrameBuffer : public VBoxFrameBuffer
    1431299{
     
    1445313#ifdef VBOX_WITH_VIDEOHWACCEL
    1446314    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
    1447 
    1448 
    1449     static bool isAcceleration2DVideoAvailable();
    1450315#endif
    1451316
     
    1463328private:
    1464329//    void vboxMakeCurrent();
    1465     VBoxGLWidget * vboxWidget();
    1466 
    1467     VBoxVHWACommandElementProcessor mCmdPipe;
     330    class VBoxGLWidget * vboxWidget();
     331
     332    class VBoxVHWACommandElementProcessor mCmdPipe;
    1468333};
    1469334
    1470335#ifdef VBOX_WITH_VIDEOHWACCEL
    1471 class VBoxQGLOverlayFrameBuffer : public VBoxQImageFrameBuffer
    1472 {
    1473 public:
    1474     VBoxQGLOverlayFrameBuffer (VBoxConsoleView *aView);
     336class VBoxQImageOverlayFrameBuffer : public VBoxQImageFrameBuffer
     337{
     338public:
     339    VBoxQImageOverlayFrameBuffer (VBoxConsoleView *aView);
    1475340
    1476341
     
    1484349    void paintEvent (QPaintEvent *pe);
    1485350    void resizeEvent (VBoxResizeEvent *re);
    1486 
    1487     void vboxUpdateRect(const QRect * pRect);
    1488 
    1489     int vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version);
    1490     void vhwaSaveExec(struct SSMHANDLE * pSSM);
    1491 private:
    1492     void makeCurrent()
    1493     {
    1494         if(!mGlCurrent)
    1495         {
    1496             mGlCurrent = true;
    1497             mpOverlayWidget->makeCurrent();
    1498         }
    1499     }
    1500 
    1501     void performDisplayOverlay()
    1502     {
    1503         if(mOverlayVisible)
    1504         {
    1505 #if 0
    1506             mpOverlayWidget->updateGL();
    1507 #else
    1508             makeCurrent();
    1509             mpOverlayWidget->performDisplay();
    1510             mpOverlayWidget->swapBuffers();
    1511 #endif
    1512         }
    1513     }
    1514 
    1515     void vboxOpExit()
    1516     {
    1517         performDisplayOverlay();
    1518         mGlCurrent = false;
    1519     }
    1520 
    1521 
    1522     void vboxSetGlOn(bool on);
    1523     bool vboxGetGlOn() { return mGlOn; }
    1524     void vboxSynchGl();
    1525     void vboxDoVHWACmdExec(void *cmd);
    1526     void vboxShowOverlay(bool show);
    1527     void vboxDoCheckUpdateViewport();
    1528     void vboxDoVHWACmd(void *cmd);
    1529     void vboxDoUpdateRect(const QRect * pRect);
    1530 //    void vboxUpdateOverlayPosition(const QPoint & pos);
    1531     void vboxCheckUpdateOverlay(const QRect & rect);
    1532     VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
    1533 
    1534     int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
    1535 
    1536     VBoxGLWidget *mpOverlayWidget;
    1537     bool mGlOn;
    1538     bool mOverlayWidgetVisible;
    1539     bool mOverlayVisible;
    1540     bool mGlCurrent;
    1541     bool mProcessingCommands;
    1542     QRect mOverlayViewport;
    1543     VBoxVHWADirtyRect mMainDirtyRect;
    1544 
    1545     VBoxVHWACommandElementProcessor mCmdPipe;
    1546 
    1547     /* this is used in saved state restore to postpone surface restoration
    1548      * till the framebuffer size is restored */
    1549     VHWACommandList mOnResizeCmdList;
     351private:
     352    VBoxQGLOverlay mOverlay;
    1550353};
    1551354#endif
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h

    r22794 r22816  
    750750#ifdef VBOX_WITH_VIDEOHWACCEL
    751751    static bool isAcceleration2DVideoAvailable();
    752     VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() {
    753 #if 0
    754         return VBoxDefs::QGLOverlayMode;
    755 #else
    756         return VBoxDefs::QGLMode;
    757 #endif
    758         }
     752//    VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() {
     753//#if 0
     754//        return VBoxDefs::QGLOverlayMode;
     755//#else
     756//        return VBoxDefs::QGLMode;
     757//#endif
     758//        }
    759759#endif
    760760
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r22810 r22816  
    696696                                  const CConsole &console,
    697697                                  VBoxDefs::RenderMode rm,
     698#ifdef VBOX_WITH_VIDEOHWACCEL
     699                                  bool accelerate2DVideo,
     700#endif
    698701                                  QWidget *parent)
    699702    : QAbstractScrollArea (parent)
     
    720723    , muCapsLockAdaptionCnt (2)
    721724    , mode (rm)
     725#ifdef VBOX_WITH_VIDEOHWACCEL
     726    , mAccelerate2DVideo(accelerate2DVideo)
     727#endif
    722728#if defined(Q_WS_WIN)
    723729    , mAlphaCursor (NULL)
     
    826832            mFrameBuf = new VBoxQGLFrameBuffer (this);
    827833            break;
    828         case VBoxDefs::QGLOverlayMode:
    829             mFrameBuf = new VBoxQGLOverlayFrameBuffer (this);
    830             break;
     834//        case VBoxDefs::QGLOverlayMode:
     835//            mFrameBuf = new VBoxQGLOverlayFrameBuffer (this);
     836//            break;
    831837#endif
    832838#if defined (VBOX_GUI_USE_QIMAGE)
    833839        case VBoxDefs::QImageMode:
    834             mFrameBuf = new VBoxQImageFrameBuffer (this);
     840            mFrameBuf =
     841#ifdef VBOX_WITH_VIDEOHWACCEL
     842                    mAccelerate2DVideo ? new VBoxQImageOverlayFrameBuffer (this) :
     843#endif
     844                    new VBoxQImageFrameBuffer (this);
    835845            break;
    836846#endif
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r22703 r22816  
    811811#ifdef VBOX_WITH_VIDEOHWACCEL
    812812    /* Need to force the QGL framebuffer in case 2D Video Acceleration is supported & enabled */
    813     if (cmachine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable())
    814         mode = vboxGlobal().vmAcceleration2DVideoRenderMode();
    815 #endif
    816 
    817     console = new VBoxConsoleView (this, cconsole, mode, centralWidget());
     813    bool bAccelerate2DVideo = cmachine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable();
     814#endif
     815
     816    console = new VBoxConsoleView (this, cconsole, mode,
     817#ifdef VBOX_WITH_VIDEOHWACCEL
     818                    bAccelerate2DVideo,
     819#endif
     820                    centralWidget());
    818821    static_cast <QGridLayout*> (centralWidget()->layout())->addWidget (console, 1, 1, Qt::AlignVCenter | Qt::AlignHCenter);
    819822
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp

    r22800 r22816  
    2626
    2727#include "VBoxConsoleView.h"
    28 #include "VBoxProblemReporter.h"
    29 #include "VBoxGlobal.h"
     28//#include "VBoxProblemReporter.h"
     29//#include "VBoxGlobal.h"
    3030
    3131/* Qt includes */
    3232#include <QGLWidget>
    3333
    34 #include <iprt/asm.h>
    35 
     34//#include <iprt/asm.h>
     35//
    3636#ifdef VBOX_WITH_VIDEOHWACCEL
    3737#include <VBox/VBoxVideo.h>
    38 #include <VBox/types.h>
    39 #include <VBox/ssm.h>
    40 #endif
    41 #include <iprt/semaphore.h>
    42 
    43 #include <QFile>
    44 #include <QTextStream>
    45 
    46 #ifdef VBOXQGL_PROF_BASE
    47 # ifdef VBOXQGL_DBG_SURF
    48 #  define VBOXQGL_PROF_WIDTH 1400
    49 #  define VBOXQGL_PROF_HEIGHT 1050
    50 # else
    51 # define VBOXQGL_PROF_WIDTH 1400
    52 # define VBOXQGL_PROF_HEIGHT 1050
    53 //#define VBOXQGL_PROF_WIDTH 720
    54 //#define VBOXQGL_PROF_HEIGHT 480
    55 # endif
    56 #endif
    57 
    58 #define VBOXQGL_STATE_NAMEBASE "QGLVHWAData"
    59 #define VBOXQGL_STATE_VERSION 1
    60 
    61 //#define VBOXQGLOVERLAY_STATE_NAMEBASE "QGLOverlayVHWAData"
    62 //#define VBOXQGLOVERLAY_STATE_VERSION 1
    63 
    64 #ifdef DEBUG_misha
    65 # define VBOXQGL_STATE_DEBUG
    66 #endif
    67 
    68 #ifdef VBOXQGL_STATE_DEBUG
    69 #define VBOXQGL_STATE_START_MAGIC        0x12345678
    70 #define VBOXQGL_STATE_STOP_MAGIC         0x87654321
    71 
    72 #define VBOXQGL_STATE_SURFSTART_MAGIC    0x9abcdef1
    73 #define VBOXQGL_STATE_SURFSTOP_MAGIC     0x1fedcba9
    74 
    75 #define VBOXQGL_STATE_OVERLAYSTART_MAGIC 0x13579bdf
    76 #define VBOXQGL_STATE_OVERLAYSTOP_MAGIC  0xfdb97531
    77 
    78 #define VBOXQGL_SAVE_START(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_START_MAGIC); AssertRC(rc);}while(0)
    79 #define VBOXQGL_SAVE_STOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_STOP_MAGIC); AssertRC(rc);}while(0)
    80 
    81 #define VBOXQGL_SAVE_SURFSTART(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_SURFSTART_MAGIC); AssertRC(rc);}while(0)
    82 #define VBOXQGL_SAVE_SURFSTOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_SURFSTOP_MAGIC); AssertRC(rc);}while(0)
    83 
    84 #define VBOXQGL_SAVE_OVERLAYSTART(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_OVERLAYSTART_MAGIC); AssertRC(rc);}while(0)
    85 #define VBOXQGL_SAVE_OVERLAYSTOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_OVERLAYSTOP_MAGIC); AssertRC(rc);}while(0)
    86 
    87 #define VBOXQGL_LOAD_CHECK(_pSSM, _v) \
    88     do{ \
    89         uint32_t _u32; \
    90         int rc = SSMR3GetU32(_pSSM, &_u32); AssertRC(rc); \
    91         if(_u32 != (_v)) \
    92         { \
    93             VBOXQGLLOG(("load error: expected magic (0x%x), but was (0x%x)\n", (_v), _u32));\
    94         }\
    95         Assert(_u32 == (_v)); \
    96     }while(0)
    97 
    98 #define VBOXQGL_LOAD_START(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_START_MAGIC)
    99 #define VBOXQGL_LOAD_STOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_STOP_MAGIC)
    100 
    101 #define VBOXQGL_LOAD_SURFSTART(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_SURFSTART_MAGIC)
    102 #define VBOXQGL_LOAD_SURFSTOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_SURFSTOP_MAGIC)
    103 
    104 #define VBOXQGL_LOAD_OVERLAYSTART(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_OVERLAYSTART_MAGIC)
    105 #define VBOXQGL_LOAD_OVERLAYSTOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_OVERLAYSTOP_MAGIC)
    106 
    107 #else
    108 
    109 #define VBOXQGL_SAVE_START(_pSSM) do{}while(0)
    110 #define VBOXQGL_SAVE_STOP(_pSSM) do{}while(0)
    111 
    112 #define VBOXQGL_SAVE_SURFSTART(_pSSM) do{}while(0)
    113 #define VBOXQGL_SAVE_SURFSTOP(_pSSM) do{}while(0)
    114 
    115 #define VBOXQGL_SAVE_OVERLAYSTART(_pSSM) do{}while(0)
    116 #define VBOXQGL_SAVE_OVERLAYSTOP(_pSSM) do{}while(0)
    117 
    118 #define VBOXQGL_LOAD_START(_pSSM) do{}while(0)
    119 #define VBOXQGL_LOAD_STOP(_pSSM) do{}while(0)
    120 
    121 #define VBOXQGL_LOAD_SURFSTART(_pSSM) do{}while(0)
    122 #define VBOXQGL_LOAD_SURFSTOP(_pSSM) do{}while(0)
    123 
    124 #define VBOXQGL_LOAD_OVERLAYSTART(_pSSM) do{}while(0)
    125 #define VBOXQGL_LOAD_OVERLAYSTOP(_pSSM) do{}while(0)
    126 
    127 #endif
    128 
    129 #define VBOXQGL_MAKEFOURCC(ch0, ch1, ch2, ch3)                              \
    130                 ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) |       \
    131                 ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
    132 
    133 #define FOURCC_AYUV VBOXQGL_MAKEFOURCC('A', 'Y', 'U', 'V')
    134 #define FOURCC_UYVY VBOXQGL_MAKEFOURCC('U', 'Y', 'V', 'Y')
    135 #define FOURCC_YUY2 VBOXQGL_MAKEFOURCC('Y', 'U', 'Y', '2')
    136 #define FOURCC_YV12 VBOXQGL_MAKEFOURCC('Y', 'V', '1', '2')
    137 #define VBOXVHWA_NUMFOURCC 4
    138 
    139 typedef char GLchar;
    140 
    141 #ifndef GL_COMPILE_STATUS
    142 # define GL_COMPILE_STATUS 0x8b81
    143 #endif
    144 #ifndef GL_LINK_STATUS
    145 # define GL_LINK_STATUS    0x8b82
    146 #endif
    147 #ifndef GL_FRAGMENT_SHADER
    148 # define GL_FRAGMENT_SHADER 0x8b30
    149 #endif
    150 #ifndef GL_VERTEX_SHADER
    151 # define GL_VERTEX_SHADER 0x8b31
    152 #endif
    153 
    154 /* GL_ARB_multitexture */
    155 #ifndef GL_TEXTURE0
    156 # define GL_TEXTURE0                    0x84c0
    157 #endif
    158 #ifndef GL_TEXTURE1
    159 # define GL_TEXTURE1                    0x84c1
    160 #endif
    161 #ifndef GL_MAX_TEXTURE_COORDS
    162 # define GL_MAX_TEXTURE_COORDS          0x8871
    163 #endif
    164 #ifndef GL_MAX_TEXTURE_IMAGE_UNITS
    165 # define GL_MAX_TEXTURE_IMAGE_UNITS     0x8872
    166 #endif
    167 
    168 #ifndef APIENTRY
    169 # define APIENTRY
    170 #endif
    171 
    172 typedef GLvoid (APIENTRY *PFNVBOXVHWA_ACTIVE_TEXTURE) (GLenum texture);
    173 typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2I) (GLenum texture, GLint v0, GLint v1);
    174 typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2F) (GLenum texture, GLfloat v0, GLfloat v1);
    175 typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2D) (GLenum texture, GLdouble v0, GLdouble v1);
    176 
    177 /* GL_ARB_texture_rectangle */
    178 #ifndef GL_TEXTURE_RECTANGLE
    179 # define GL_TEXTURE_RECTANGLE 0x84F5
    180 #endif
    181 
    182 /* GL_ARB_shader_objects */
    183 /* GL_ARB_fragment_shader */
    184 
    185 typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_SHADER)  (GLenum type);
    186 typedef GLvoid (APIENTRY *PFNVBOXVHWA_SHADER_SOURCE)  (GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
    187 typedef GLvoid (APIENTRY *PFNVBOXVHWA_COMPILE_SHADER) (GLuint shader);
    188 typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_SHADER)  (GLuint shader);
    189 
    190 typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_PROGRAM) ();
    191 typedef GLvoid (APIENTRY *PFNVBOXVHWA_ATTACH_SHADER)  (GLuint program, GLuint shader);
    192 typedef GLvoid (APIENTRY *PFNVBOXVHWA_DETACH_SHADER)  (GLuint program, GLuint shader);
    193 typedef GLvoid (APIENTRY *PFNVBOXVHWA_LINK_PROGRAM)   (GLuint program);
    194 typedef GLvoid (APIENTRY *PFNVBOXVHWA_USE_PROGRAM)    (GLuint program);
    195 typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_PROGRAM) (GLuint program);
    196 
    197 typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_SHADER)   (GLuint shader);
    198 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADERIV)   (GLuint shader, GLenum pname, GLint *params);
    199 typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_PROGRAM)  (GLuint program);
    200 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAMIV)  (GLuint program, GLenum pname, GLint *params);
    201 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_ATTACHED_SHADERS) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
    202 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADER_INFO_LOG)  (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
    203 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAM_INFO_LOG) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
    204 typedef GLint (APIENTRY *PFNVBOXVHWA_GET_UNIFORM_LOCATION) (GLint programObj, const GLchar *name);
    205 
    206 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1F)(GLint location, GLfloat v0);
    207 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2F)(GLint location, GLfloat v0, GLfloat v1);
    208 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
    209 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
    210 
    211 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1I)(GLint location, GLint v0);
    212 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2I)(GLint location, GLint v0, GLint v1);
    213 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3I)(GLint location, GLint v0, GLint v1, GLint v2);
    214 typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4I)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
    215 
    216 /* GL_ARB_pixel_buffer_object*/
    217 #ifndef Q_WS_MAC
    218 /* apears to be defined on mac */
    219 typedef ptrdiff_t GLsizeiptr;
    220 #endif
    221 
    222 #ifndef GL_READ_ONLY
    223 # define GL_READ_ONLY                   0x88B8
    224 #endif
    225 #ifndef GL_WRITE_ONLY
    226 # define GL_WRITE_ONLY                  0x88B9
    227 #endif
    228 #ifndef GL_READ_WRITE
    229 # define GL_READ_WRITE                  0x88BA
    230 #endif
    231 #ifndef GL_STREAM_DRAW
    232 # define GL_STREAM_DRAW                 0x88E0
    233 #endif
    234 #ifndef GL_STREAM_READ
    235 # define GL_STREAM_READ                 0x88E1
    236 #endif
    237 #ifndef GL_STREAM_COPY
    238 # define GL_STREAM_COPY                 0x88E2
    239 #endif
    240 
    241 #ifndef GL_PIXEL_PACK_BUFFER
    242 # define GL_PIXEL_PACK_BUFFER           0x88EB
    243 #endif
    244 #ifndef GL_PIXEL_UNPACK_BUFFER
    245 # define GL_PIXEL_UNPACK_BUFFER         0x88EC
    246 #endif
    247 #ifndef GL_PIXEL_PACK_BUFFER_BINDING
    248 # define GL_PIXEL_PACK_BUFFER_BINDING   0x88ED
    249 #endif
    250 #ifndef GL_PIXEL_UNPACK_BUFFER_BINDING
    251 # define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
    252 #endif
    253 
    254 typedef GLvoid (APIENTRY *PFNVBOXVHWA_GEN_BUFFERS)(GLsizei n, GLuint *buffers);
    255 typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_BUFFERS)(GLsizei n, const GLuint *buffers);
    256 typedef GLvoid (APIENTRY *PFNVBOXVHWA_BIND_BUFFER)(GLenum target, GLuint buffer);
    257 typedef GLvoid (APIENTRY *PFNVBOXVHWA_BUFFER_DATA)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
    258 typedef GLvoid* (APIENTRY *PFNVBOXVHWA_MAP_BUFFER)(GLenum target, GLenum access);
    259 typedef GLboolean (APIENTRY *PFNVBOXVHWA_UNMAP_BUFFER)(GLenum target);
    260 
    261 /*****************/
    262 
    263 /* functions */
    264 
    265 PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture = NULL;
    266 PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i = NULL;
    267 PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d = NULL;
    268 PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f = NULL;
    269 
    270 
    271 PFNVBOXVHWA_CREATE_SHADER   vboxglCreateShader  = NULL;
    272 PFNVBOXVHWA_SHADER_SOURCE   vboxglShaderSource  = NULL;
    273 PFNVBOXVHWA_COMPILE_SHADER  vboxglCompileShader = NULL;
    274 PFNVBOXVHWA_DELETE_SHADER   vboxglDeleteShader  = NULL;
    275 
    276 PFNVBOXVHWA_CREATE_PROGRAM  vboxglCreateProgram = NULL;
    277 PFNVBOXVHWA_ATTACH_SHADER   vboxglAttachShader  = NULL;
    278 PFNVBOXVHWA_DETACH_SHADER   vboxglDetachShader  = NULL;
    279 PFNVBOXVHWA_LINK_PROGRAM    vboxglLinkProgram   = NULL;
    280 PFNVBOXVHWA_USE_PROGRAM     vboxglUseProgram    = NULL;
    281 PFNVBOXVHWA_DELETE_PROGRAM  vboxglDeleteProgram = NULL;
    282 
    283 PFNVBOXVHWA_IS_SHADER       vboxglIsShader      = NULL;
    284 PFNVBOXVHWA_GET_SHADERIV    vboxglGetShaderiv   = NULL;
    285 PFNVBOXVHWA_IS_PROGRAM      vboxglIsProgram     = NULL;
    286 PFNVBOXVHWA_GET_PROGRAMIV   vboxglGetProgramiv  = NULL;
    287 PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders = NULL;
    288 PFNVBOXVHWA_GET_SHADER_INFO_LOG  vboxglGetShaderInfoLog   = NULL;
    289 PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog  = NULL;
    290 
    291 PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation = NULL;
    292 
    293 PFNVBOXVHWA_UNIFORM1F vboxglUniform1f;
    294 PFNVBOXVHWA_UNIFORM2F vboxglUniform2f;
    295 PFNVBOXVHWA_UNIFORM3F vboxglUniform3f;
    296 PFNVBOXVHWA_UNIFORM4F vboxglUniform4f;
    297 
    298 PFNVBOXVHWA_UNIFORM1I vboxglUniform1i;
    299 PFNVBOXVHWA_UNIFORM2I vboxglUniform2i;
    300 PFNVBOXVHWA_UNIFORM3I vboxglUniform3i;
    301 PFNVBOXVHWA_UNIFORM4I vboxglUniform4i;
    302 
    303 PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers = NULL;
    304 PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers = NULL;
    305 PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer = NULL;
    306 PFNVBOXVHWA_BUFFER_DATA vboxglBufferData = NULL;
    307 PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer = NULL;
    308 PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer = NULL;
    309 
    310 #if 0
    311 #if defined Q_WS_WIN
    312 #define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)wglGetProcAddress(_n)
    313 #elif defined Q_WS_X11
    314 #include <GL/glx.h>
    315 #define VBOXVHWA_GETPROCADDRESS(_t, _n) (_t)glXGetProcAddress((const GLubyte *)(_n))
    316 #else
    317 #error "Port me!!!"
    318 #endif
    319 #endif
    320 
    321 #define VBOXVHWA_GETPROCADDRESS(_c, _t, _n) ((_t)(_c).getProcAddress(QString(_n)))
    322 
    323 #define VBOXVHWA_PFNINIT_SAME(_c, _t, _v, _rc) \
    324     do { \
    325         if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v)) == NULL) \
    326         { \
    327             VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v));\
    328             AssertBreakpoint(); \
    329             if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
    330             { \
    331                 VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
    332                 AssertBreakpoint(); \
    333                 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"EXT")) == NULL) \
    334                 { \
    335                     VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"EXT"));\
    336                     AssertBreakpoint(); \
    337                     (_rc)++; \
    338                 } \
    339             } \
    340         } \
    341     }while(0)
    342 
    343 #define VBOXVHWA_PFNINIT(_c, _t, _v, _f,_rc) \
    344     do { \
    345         if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_f)) == NULL) \
    346         { \
    347             VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_f));\
    348             AssertBreakpoint(); \
    349             (_rc)++; \
    350         } \
    351     }while(0)
    352 
    353 //#define VBOXVHWA_PFNINIT_OBJECT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ObjectARB" ,_rc)
    354 #define VBOXVHWA_PFNINIT_OBJECT_ARB(_c, _t, _v, _rc) \
    355             do { \
    356                 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ObjectARB")) == NULL) \
    357                 { \
    358                     VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ObjectARB"));\
    359                     AssertBreakpoint(); \
    360                     (_rc)++; \
    361                 } \
    362             }while(0)
    363 
    364 //#define VBOXVHWA_PFNINIT_ARB(_t, _v, _rc) VBOXVHWA_PFNINIT(_t, _v, #_v"ARB" ,_rc)
    365 #define VBOXVHWA_PFNINIT_ARB(_c, _t, _v, _rc) \
    366             do { \
    367                 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
    368                 { \
    369                 VBOXQGLLOG(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
    370                     AssertBreakpoint(); \
    371                     (_rc)++; \
    372                 } \
    373             }while(0)
    374 
    375 
    376 static bool g_vboxVHWAGlSupportInitialized = false;
    377 /* vbox version in the format 0x00mjmnbl
    378  * in case of a failure contains -1 (0xffffffff) */
    379 static int g_vboxVHWAGlVersion = 0;
    380 
    381 static bool g_GL_ARB_multitexture        = false;
    382 static bool g_GL_ARB_shader_objects      = false;
    383 static bool g_GL_ARB_fragment_shader     = false;
    384 static bool g_GL_ARB_pixel_buffer_object = false;
    385 static bool g_GL_ARB_texture_rectangle   = false;
    386 static bool g_GL_EXT_texture_rectangle   = false;
    387 static bool g_GL_NV_texture_rectangle         = false;
    388 static bool g_GL_ARB_texture_non_power_of_two = false;
    389 
    390 /* gl features supported */
    391 static bool g_vboxVHWAGlShaderSupported = false;
    392 static bool g_vboxVHWAGlTextureRectangleSupported = false;
    393 static bool g_vboxVHWAGlTextureNP2Supported = false;
    394 static bool g_vboxVHWAGlPBOSupported = false;
    395 static int g_vboxVHWAGlMultiTexNumSupported = 1; /* 1 would mean it is not supported */
    396 
    397 /* vhwa features supported */
    398 static uint32_t g_vboxVHWAFourccSupportedList[VBOXVHWA_NUMFOURCC];
    399 static uint32_t g_vboxVHWAFourccSupportedCount = 0;
    400 
    401 
    402 static int vboxVHWAGlParseSubver(const GLubyte * ver, const GLubyte ** pNext, bool bSpacePrefixAllowed)
    403 {
    404     int val = 0;
    405 
    406     for(;;++ver)
    407     {
    408         if(*ver >= '0' && *ver < '9')
    409         {
    410             if(!val)
    411             {
    412                 if(*ver == '0')
    413                     continue;
    414             }
    415             else
    416             {
    417                 val *= 10;
    418             }
    419             val += *ver - '0';
    420         }
    421         else if(*ver == '.')
    422         {
    423             *pNext = ver+1;
    424             break;
    425         }
    426         else if(*ver == '\0')
    427         {
    428             *pNext = NULL;
    429             break;
    430         }
    431         else if(*ver == ' ' || *ver == '\t' ||  *ver == 0x0d || *ver == 0x0a)
    432         {
    433                 if(bSpacePrefixAllowed)
    434                 {
    435                         if(!val)
    436                         {
    437                                 continue;
    438                         }
    439                 }
    440 
    441                 /* treat this as the end ov version string */
    442                 *pNext = NULL;
    443             break;
    444         }
    445         else
    446         {
    447             Assert(0);
    448             val = -1;
    449             break;
    450         }
    451     }
    452 
    453     return val;
    454 }
    455 
    456 static int vboxVHWAGlParseVersion(const GLubyte * ver)
    457 {
    458     int iVer = vboxVHWAGlParseSubver(ver, &ver, true);
    459     if(iVer)
    460     {
    461         iVer <<= 16;
    462         if(ver)
    463         {
    464             int tmp = vboxVHWAGlParseSubver(ver, &ver, false);
    465             if(tmp >= 0)
    466             {
    467                 iVer |= tmp << 8;
    468                 if(ver)
    469                 {
    470                     tmp = vboxVHWAGlParseSubver(ver, &ver, false);
    471                     if(tmp >= 0)
    472                     {
    473                         iVer |= tmp;
    474                     }
    475                     else
    476                     {
    477                         Assert(0);
    478                         iVer = -1;
    479                     }
    480                 }
    481             }
    482             else
    483             {
    484                 Assert(0);
    485                 iVer = -1;
    486             }
    487         }
    488     }
    489     return iVer;
    490 }
    491 
    492 static void vboxVHWAGlInitExtSupport(const QGLContext & context)
    493 {
    494     int rc = 0;
    495     do
    496     {
    497         rc = 0;
    498         g_vboxVHWAGlMultiTexNumSupported = 1; /* default, 1 means not supported */
    499                 if(g_vboxVHWAGlVersion >= 0x010201) /* ogl >= 1.2.1 */
    500                 {
    501                         VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
    502                         VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
    503                         VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
    504                         VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
    505                 }
    506                 else if(g_GL_ARB_multitexture)
    507                 {
    508                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
    509                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
    510                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
    511                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
    512                 }
    513                 else
    514                 {
    515                         break;
    516                 }
    517 
    518                 if(RT_FAILURE(rc))
    519                     break;
    520 
    521         GLint maxCoords, maxUnits;
    522         glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxCoords);
    523         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits);
    524 
    525         VBOXQGLLOGREL(("Max Tex Coords (%d), Img Units (%d)\n", maxCoords, maxUnits));
    526         /* take the minimum of those */
    527         if(maxUnits < maxCoords)
    528                 maxCoords = maxUnits;
    529         if(maxUnits < 2)
    530         {
    531             VBOXQGLLOGREL(("Max Tex Coord or Img Units < 2 disabling MultiTex support\n"));
    532                 break;
    533         }
    534 
    535         g_vboxVHWAGlMultiTexNumSupported = maxUnits;
    536     }while(0);
    537 
    538 
    539     do
    540     {
    541         rc = 0;
    542         g_vboxVHWAGlPBOSupported = false;
    543 
    544                 if(g_GL_ARB_pixel_buffer_object)
    545                 {
    546                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GEN_BUFFERS, GenBuffers, rc);
    547                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_DELETE_BUFFERS, DeleteBuffers, rc);
    548                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BIND_BUFFER, BindBuffer, rc);
    549                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BUFFER_DATA, BufferData, rc);
    550                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MAP_BUFFER, MapBuffer, rc);
    551                         VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNMAP_BUFFER, UnmapBuffer, rc);
    552                 }
    553                 else
    554                 {
    555                     break;
    556                 }
    557 
    558                 if(RT_FAILURE(rc))
    559                     break;
    560 
    561                 g_vboxVHWAGlPBOSupported = true;
    562     } while(0);
    563 
    564     do
    565     {
    566         rc = 0;
    567         g_vboxVHWAGlShaderSupported = false;
    568 
    569         if(g_vboxVHWAGlVersion >= 0x020000)  /* if ogl >= 2.0*/
    570         {
    571             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
    572             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
    573             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
    574             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, rc);
    575 
    576             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
    577             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, rc);
    578             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, rc);
    579             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
    580             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
    581             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, rc);
    582 
    583             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_SHADER, IsShader, rc);
    584             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, rc);
    585             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
    586             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, rc);
    587             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders,  rc);
    588             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, rc);
    589             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, rc);
    590 
    591             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
    592 
    593             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
    594             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
    595             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
    596             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
    597 
    598             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
    599             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
    600             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
    601             VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
    602         }
    603         else if(g_GL_ARB_shader_objects && g_GL_ARB_fragment_shader)
    604         {
    605             VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
    606             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
    607             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
    608             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, DeleteObjectARB, rc);
    609 
    610             VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
    611             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, AttachObjectARB, rc);
    612             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, DetachObjectARB, rc);
    613             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
    614             VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
    615             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, DeleteObjectARB, rc);
    616 
    617         //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_SHADER, IsShader, rc);
    618             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, GetObjectParameterivARB, rc);
    619         //TODO:    VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
    620             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, GetObjectParameterivARB, rc);
    621             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders, GetAttachedObjectsARB, rc);
    622             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, GetInfoLogARB, rc);
    623             VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, GetInfoLogARB, rc);
    624 
    625             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
    626 
    627             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
    628             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
    629             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
    630             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
    631 
    632             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
    633             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
    634             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
    635             VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
    636         }
    637         else
    638         {
    639             break;
    640         }
    641 
    642         if(RT_FAILURE(rc))
    643             break;
    644 
    645         g_vboxVHWAGlShaderSupported = true;
    646     } while(0);
    647 
    648     if(g_GL_ARB_texture_rectangle || g_GL_EXT_texture_rectangle || g_GL_NV_texture_rectangle)
    649     {
    650         g_vboxVHWAGlTextureRectangleSupported = true;
    651     }
    652     else
    653     {
    654         g_vboxVHWAGlTextureRectangleSupported = false;
    655     }
    656 
    657     g_vboxVHWAGlTextureNP2Supported = g_GL_ARB_texture_non_power_of_two;
    658 }
    659 
    660 static void vboxVHWAGlInitFeatureSupport()
    661 {
    662     if(g_vboxVHWAGlShaderSupported && g_vboxVHWAGlTextureRectangleSupported)
    663     {
    664         uint32_t num = 0;
    665         g_vboxVHWAFourccSupportedList[num++] = FOURCC_AYUV;
    666         g_vboxVHWAFourccSupportedList[num++] = FOURCC_UYVY;
    667         g_vboxVHWAFourccSupportedList[num++] = FOURCC_YUY2;
    668         if(g_vboxVHWAGlMultiTexNumSupported >= 4)
    669         {
    670             /* YV12 currently requires 3 units (for each color component)
    671              * + 1 unit for dst texture for color-keying + 3 units for each color component
    672              * TODO: we could store YV12 data in one texture to eliminate this requirement*/
    673             g_vboxVHWAFourccSupportedList[num++] = FOURCC_YV12;
    674         }
    675 
    676         Assert(num <= VBOXVHWA_NUMFOURCC);
    677         g_vboxVHWAFourccSupportedCount = num;
    678     }
    679     else
    680     {
    681         g_vboxVHWAFourccSupportedCount = 0;
    682     }
    683 }
    684 
    685 static void vboxVHWAGlInit(const QGLContext * pContext)
    686 {
    687     if(g_vboxVHWAGlSupportInitialized)
    688         return;
    689 
    690     static QGLWidget *pTmpContextHolder = NULL;
    691     const bool bHasGlContext = (pContext != NULL);
    692 
    693     if(!pContext)
    694     {
    695         if(!pTmpContextHolder)
    696         {
    697             QGLWidget *pWidget = new QGLWidget();
    698             pWidget->makeCurrent();
    699             pContext = pWidget->context();
    700             pTmpContextHolder = pWidget;
    701         }
    702 
    703 //        QGLContext * pTmpContext = new QGLContext(QGLFormat::defaultFormat());
    704 //        bool bCreated = pTmpContext->create();
    705 //        Assert(pTmpContext);
    706 //        Assert(pTmpContext->isValid());
     38//#include <VBox/types.h>
     39//#include <VBox/ssm.h>
     40#endif
     41//#include <iprt/semaphore.h>
    70742//
    708 //        pTmpContext->makeCurrent();
    709 //        pTmpContextHolder = pTmpContext;
    710     }
    711 
    712     const GLubyte * str;
    713     VBOXQGL_CHECKERR(
    714             str = glGetString(GL_VERSION);
    715             );
    716 
    717     VBOXQGLLOGREL (("gl version string: 0%s\n", str));
    718 
    719     g_vboxVHWAGlVersion = vboxVHWAGlParseVersion(str);
    720     Assert(g_vboxVHWAGlVersion > 0);
    721     if(g_vboxVHWAGlVersion < 0)
    722     {
    723         g_vboxVHWAGlVersion = 0;
    724     }
    725     else
    726     {
    727         VBOXQGLLOGREL (("gl version: 0x%x\n", g_vboxVHWAGlVersion));
    728         VBOXQGL_CHECKERR(
    729                 str = glGetString(GL_EXTENSIONS);
    730                 );
    731 
    732         const char * pos = strstr((const char *)str, "GL_ARB_multitexture");
    733         g_GL_ARB_multitexture = pos != NULL;
    734         VBOXQGLLOGREL (("GL_ARB_multitexture: %d\n", g_GL_ARB_multitexture));
    735 
    736         pos = strstr((const char *)str, "GL_ARB_shader_objects");
    737         g_GL_ARB_shader_objects = pos != NULL;
    738         VBOXQGLLOGREL (("GL_ARB_shader_objects: %d\n", g_GL_ARB_shader_objects));
    739 
    740         pos = strstr((const char *)str, "GL_ARB_fragment_shader");
    741         g_GL_ARB_fragment_shader = pos != NULL;
    742         VBOXQGLLOGREL (("GL_ARB_fragment_shader: %d\n", g_GL_ARB_fragment_shader));
    743 
    744         pos = strstr((const char *)str, "GL_ARB_pixel_buffer_object");
    745         g_GL_ARB_pixel_buffer_object = pos != NULL;
    746         VBOXQGLLOGREL (("GL_ARB_pixel_buffer_object: %d\n", g_GL_ARB_pixel_buffer_object));
    747 
    748         pos = strstr((const char *)str, "GL_ARB_texture_rectangle");
    749         g_GL_ARB_texture_rectangle = pos != NULL;
    750         VBOXQGLLOGREL (("GL_ARB_texture_rectangle: %d\n", g_GL_ARB_texture_rectangle));
    751 
    752         pos = strstr((const char *)str, "GL_EXT_texture_rectangle");
    753         g_GL_EXT_texture_rectangle = pos != NULL;
    754         VBOXQGLLOGREL (("GL_EXT_texture_rectangle: %d\n", g_GL_EXT_texture_rectangle));
    755 
    756         pos = strstr((const char *)str, "GL_NV_texture_rectangle");
    757         g_GL_NV_texture_rectangle = pos != NULL;
    758         VBOXQGLLOGREL (("GL_NV_texture_rectangle: %d\n", g_GL_NV_texture_rectangle));
    759 
    760         pos = strstr((const char *)str, "GL_ARB_texture_non_power_of_two");
    761         g_GL_ARB_texture_non_power_of_two = pos != NULL;
    762         VBOXQGLLOGREL (("GL_ARB_texture_non_power_of_two: %d\n", g_GL_ARB_texture_non_power_of_two));
    763 
    764         vboxVHWAGlInitExtSupport(*pContext);
    765 
    766         vboxVHWAGlInitFeatureSupport();
    767     }
    768 
    769     if(!bHasGlContext)
    770     {
    771         pTmpContextHolder->doneCurrent();
    772     }
    773 
    774     g_vboxVHWAGlSupportInitialized = true;
    775 }
    776 
    777 static bool vboxVHWASupportedInternal()
    778 {
    779     if(g_vboxVHWAGlVersion <= 0)
    780     {
    781         /* error occurred while gl info initialization */
    782         return false;
    783     }
    784 
    785 #ifndef DEBUG
    786     /* in case we do not support shaders & multitexturing we can not supprt dst colorkey,
    787      * no sense to report Video Acceleration supported */
    788     if(!g_vboxVHWAGlShaderSupported)
    789         return false;
    790 #endif
    791     if(g_vboxVHWAGlMultiTexNumSupported < 2)
    792         return false;
    793 
    794     /* color conversion now supported only GL_TEXTURE_RECTANGLE
    795      * in this case only stretching is accelerated
    796      * report as unsupported, TODO: probably should report as supported for stretch acceleration */
    797     if(!g_vboxVHWAGlTextureRectangleSupported)
    798         return false;
    799 
    800     return true;
    801 }
    802 
    803 class VBoxVHWACommandProcessEvent : public QEvent
    804 {
    805 public:
    806     VBoxVHWACommandProcessEvent (VBoxVHWACommandElement *pEl)
    807         : QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
    808     {
    809         mCmdPipe.put(pEl);
    810     }
    811     VBoxVHWACommandElementPipe & pipe() { return mCmdPipe; }
    812 
    813     VBoxVHWACommandProcessEvent *mpNext;
    814 private:
    815     VBoxVHWACommandElementPipe mCmdPipe;
    816 };
    817 
    818 
    819 
    820 VBoxVHWAHandleTable::VBoxVHWAHandleTable(uint32_t initialSize)
    821 {
    822     mTable = new void*[initialSize];
    823     memset(mTable, 0, initialSize*sizeof(void*));
    824     mcSize = initialSize;
    825     mcUsage = 0;
    826     mCursor = 1; /* 0 is treated as invalid */
    827 }
    828 
    829 VBoxVHWAHandleTable::~VBoxVHWAHandleTable()
    830 {
    831     delete[] mTable;
    832 }
    833 
    834 uint32_t VBoxVHWAHandleTable::put(void * data)
    835 {
    836     Assert(data);
    837     if(!data)
    838         return VBOXVHWA_SURFHANDLE_INVALID;
    839 
    840     if(mcUsage == mcSize)
    841     {
    842         /* @todo: resize */
    843         Assert(0);
    844     }
    845 
    846     Assert(mcUsage < mcSize);
    847     if(mcUsage >= mcSize)
    848         return VBOXVHWA_SURFHANDLE_INVALID;
    849 
    850     for(int k = 0; k < 2; ++k)
    851     {
    852         Assert(mCursor != 0);
    853         for(uint32_t i = mCursor; i < mcSize; ++i)
    854         {
    855             if(!mTable[i])
    856             {
    857                 doPut(i, data);
    858                 mCursor = i+1;
    859                 return i;
    860             }
    861         }
    862         mCursor = 1; /* 0 is treated as invalid */
    863     }
    864 
    865     Assert(0);
    866     return VBOXVHWA_SURFHANDLE_INVALID;
    867 }
    868 
    869 bool VBoxVHWAHandleTable::mapPut(uint32_t h, void * data)
    870 {
    871     if(mcSize <= h)
    872         return false;
    873     if(h == 0)
    874         return false;
    875     if(mTable[h])
    876         return false;
    877 
    878     doPut(h, data);
    879     return true;
    880 }
    881 
    882 void* VBoxVHWAHandleTable::get(uint32_t h)
    883 {
    884     Assert(h < mcSize);
    885     Assert(h > 0);
    886     return mTable[h];
    887 }
    888 
    889 void* VBoxVHWAHandleTable::remove(uint32_t h)
    890 {
    891     Assert(mcUsage);
    892     Assert(h < mcSize);
    893     void* val = mTable[h];
    894     Assert(val);
    895     if(val)
    896     {
    897         doRemove(h);
    898     }
    899     return val;
    900 }
    901 
    902 void VBoxVHWAHandleTable::doPut(uint32_t h, void * data)
    903 {
    904     ++mcUsage;
    905     mTable[h] = data;
    906 }
    907 
    908 void VBoxVHWAHandleTable::doRemove(uint32_t h)
    909 {
    910     mTable[h] = 0;
    911     --mcUsage;
    912 }
    913 
    914 static VBoxVHWATexture* vboxVHWATextureCreate(const QRect & aRect, const VBoxVHWAColorFormat & aFormat, bool bVGA)
    915 {
    916         if(!bVGA && g_GL_ARB_pixel_buffer_object)
    917         {
    918                 VBOXQGLLOG(("VBoxVHWATextureNP2RectPBO\n"));
    919                 return new VBoxVHWATextureNP2RectPBO(aRect, aFormat);
    920         }
    921         else if(g_vboxVHWAGlTextureRectangleSupported)
    922         {
    923                 VBOXQGLLOG(("VBoxVHWATextureNP2Rect\n"));
    924                 return new VBoxVHWATextureNP2Rect(aRect, aFormat);
    925         }
    926         else if(g_GL_ARB_texture_non_power_of_two)
    927         {
    928                 VBOXQGLLOG(("VBoxVHWATextureNP2\n"));
    929                 return new VBoxVHWATextureNP2(aRect, aFormat);
    930         }
    931         VBOXQGLLOG(("VBoxVHWATexture\n"));
    932         return new VBoxVHWATexture(aRect, aFormat);
    933 }
    934 
    935 class VBoxVHWAGlShader
    936 {
    937 public:
    938     VBoxVHWAGlShader(const char *aRcName, GLenum aType) :
    939         mShader(0),
    940         mRcName(aRcName),
    941         mType(aType)
    942     {}
    943 
    944 //    virtual ~VBoxVHWAGlShader();
    945 
    946     int init();
    947 //    virtual int initUniforms(class VBoxVHWAGlProgram * pProgram){}
    948     void uninit();
    949     bool isInitialized() { return mShader; }
    950     GLuint shader() {return mShader;}
    951 private:
    952     GLuint mShader;
    953     const char *mRcName;
    954     GLenum mType;
    955 };
    956 
    957 int VBoxVHWAGlShader::init()
    958 {
    959 //    Assert(!isInitialized());
    960     if(isInitialized())
    961         return VINF_ALREADY_INITIALIZED;
    962 
    963     QFile fi(mRcName);
    964     if (!fi.open(QIODevice::ReadOnly))
    965     {
    966         Assert(0);
    967         return VERR_GENERAL_FAILURE;
    968     }
    969 
    970     QTextStream is(&fi);
    971     QString program = is.readAll();
    972 
    973     mShader = vboxglCreateShader(mType);
    974     Assert(mShader);
    975     if(!mShader)
    976         return VERR_GENERAL_FAILURE;
    977 
    978  //   int length = program.length();
    979     QByteArray asciiStr = program.toAscii();
    980     const char * contents = asciiStr.constData();
    981     GLint length = -1;
    982 
    983     VBOXQGL_CHECKERR(
    984             vboxglShaderSource(mShader, 1, &contents, &length);
    985             );
    986 
    987     VBOXQGL_CHECKERR(
    988             vboxglCompileShader(mShader);
    989             );
    990 
    991     GLint compiled;
    992     VBOXQGL_CHECKERR(
    993             vboxglGetShaderiv(mShader, GL_COMPILE_STATUS, &compiled);
    994             );
    995 
    996 #ifdef DEBUG
    997     GLchar * pBuf = new GLchar[16300];
    998     vboxglGetShaderInfoLog(mShader, 16300, NULL, pBuf);
    999     VBOXQGLLOG(("compile log for shader:\n-----------\n%s\n---------\n", contents));
    1000     VBOXQGLLOG(("%s\n**********\n", pBuf));
    1001     delete pBuf;
    1002 #endif
    1003 
    1004     Assert(compiled);
    1005     if(compiled)
    1006     {
    1007         return VINF_SUCCESS;
    1008     }
    1009 
    1010 
    1011 
    1012     VBOXQGL_CHECKERR(
    1013             vboxglDeleteShader(mShader);
    1014             );
    1015     mShader = 0;
    1016     return VERR_GENERAL_FAILURE;
    1017 }
    1018 
    1019 void VBoxVHWAGlShader::uninit()
    1020 {
    1021     if(!isInitialized())
    1022         return;
    1023 
    1024     VBOXQGL_CHECKERR(
    1025             vboxglDeleteShader(mShader);
    1026             );
    1027     mShader = 0;
    1028 }
    1029 
    1030 class VBoxVHWAGlProgram
    1031 {
    1032 public:
    1033     VBoxVHWAGlProgram(VBoxVHWAGlShader ** apShaders, int acShaders);
    1034 
    1035     ~VBoxVHWAGlProgram();
    1036 
    1037     virtual int init();
    1038     virtual void uninit();
    1039     virtual int start();
    1040     virtual int stop();
    1041     bool isInitialized() { return mProgram; }
    1042     GLuint program() {return mProgram;}
    1043 private:
    1044     GLuint mProgram;
    1045     VBoxVHWAGlShader ** mpShaders;
    1046     int mcShaders;
    1047 };
    1048 
    1049 VBoxVHWAGlProgram::VBoxVHWAGlProgram(VBoxVHWAGlShader ** apShaders, int acShaders) :
    1050        mProgram(0),
    1051        mpShaders(NULL),
    1052        mcShaders(0)
    1053 {
    1054     Assert(acShaders);
    1055     if(acShaders)
    1056     {
    1057         mpShaders = (VBoxVHWAGlShader **)malloc(sizeof(VBoxVHWAGlShader *) * acShaders);
    1058         memcpy(mpShaders, apShaders, sizeof(VBoxVHWAGlShader *) * acShaders);
    1059         mcShaders = acShaders;
    1060     }
    1061 }
    1062 
    1063 VBoxVHWAGlProgram::~VBoxVHWAGlProgram()
    1064 {
    1065     uninit();
    1066 
    1067     if(mpShaders)
    1068     {
    1069         free(mpShaders);
    1070     }
    1071 }
    1072 
    1073 int VBoxVHWAGlProgram::init()
    1074 {
    1075     Assert(!isInitialized());
    1076     if(isInitialized())
    1077         return VINF_ALREADY_INITIALIZED;
    1078 
    1079     Assert(mcShaders);
    1080     if(!mcShaders)
    1081         return VERR_GENERAL_FAILURE;
    1082 
    1083     int rc = VINF_SUCCESS;
    1084     for(int i = 0; i < mcShaders; i++)
    1085     {
    1086         int rc = mpShaders[i]->init();
    1087         Assert(RT_SUCCESS(rc));
    1088         if(RT_FAILURE(rc))
    1089         {
    1090             break;
    1091         }
    1092     }
    1093     if(RT_FAILURE(rc))
    1094     {
    1095         return rc;
    1096     }
    1097 
    1098     mProgram = vboxglCreateProgram();
    1099     Assert(mProgram);
    1100     if(mProgram)
    1101     {
    1102         for(int i = 0; i < mcShaders; i++)
    1103         {
    1104             VBOXQGL_CHECKERR(
    1105                     vboxglAttachShader(mProgram, mpShaders[i]->shader());
    1106                     );
    1107         }
    1108 
    1109         VBOXQGL_CHECKERR(
    1110                 vboxglLinkProgram(mProgram);
    1111                 );
    1112 
    1113 
    1114         GLint linked;
    1115         vboxglGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
    1116 
    1117 #ifdef DEBUG
    1118         GLchar * pBuf = new GLchar[16300];
    1119         vboxglGetProgramInfoLog(mProgram, 16300, NULL, pBuf);
    1120         VBOXQGLLOG(("link log: %s\n", pBuf));
    1121         Assert(linked);
    1122         delete pBuf;
    1123 #endif
    1124 
    1125         if(linked)
    1126         {
    1127             return VINF_SUCCESS;
    1128         }
    1129 
    1130         VBOXQGL_CHECKERR(
    1131                 vboxglDeleteProgram(mProgram);
    1132                 );
    1133         mProgram = 0;
    1134     }
    1135     return VERR_GENERAL_FAILURE;
    1136 }
    1137 
    1138 void VBoxVHWAGlProgram::uninit()
    1139 {
    1140     if(!isInitialized())
    1141         return;
    1142 
    1143     VBOXQGL_CHECKERR(
    1144             vboxglDeleteProgram(mProgram);
    1145             );
    1146     mProgram = 0;
    1147 }
    1148 
    1149 int VBoxVHWAGlProgram::start()
    1150 {
    1151     VBOXQGL_CHECKERR(
    1152             vboxglUseProgram(mProgram);
    1153             );
    1154     return VINF_SUCCESS;
    1155 }
    1156 
    1157 int VBoxVHWAGlProgram::stop()
    1158 {
    1159     VBOXQGL_CHECKERR(
    1160             vboxglUseProgram(0);
    1161             );
    1162     return VINF_SUCCESS;
    1163 }
    1164 
    1165 #define VBOXVHWA_PROGRAM_DSTCOLORKEY  0x00000001
    1166 #define VBOXVHWA_PROGRAM_SRCCOLORKEY  0x00000002
    1167 #define VBOXVHWA_PROGRAM_COLORCONV    0x00000004
    1168 
    1169 class VBoxVHWAGlProgramVHWA : public VBoxVHWAGlProgram
    1170 {
    1171 public:
    1172     VBoxVHWAGlProgramVHWA(/*class VBoxVHWAGlProgramMngr *aMngr, */uint32_t type, uint32_t fourcc, VBoxVHWAGlShader ** apShaders, int acShaders);
    1173 
    1174     uint32_t type() const {return mType;}
    1175     uint32_t fourcc() const {return mFourcc;}
    1176 
    1177     int setDstCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b);
    1178 
    1179     int setDstCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b);
    1180 
    1181     int setSrcCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b);
    1182 
    1183     int setSrcCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b);
    1184 
    1185 
    1186     virtual int init();
    1187 
    1188     bool matches(uint32_t type, uint32_t fourcc)
    1189     {
    1190         return mType == type && mFourcc == fourcc;
    1191     }
    1192 
    1193     bool equals(const VBoxVHWAGlProgramVHWA & other)
    1194     {
    1195         return matches(other.mType, other.mFourcc);
    1196     }
    1197 
    1198 private:
    1199     uint32_t mType;
    1200     uint32_t mFourcc;
    1201 
    1202     GLfloat mDstUpperR, mDstUpperG, mDstUpperB;
    1203     GLint mUniDstUpperColor;
    1204 
    1205     GLfloat mDstLowerR, mDstLowerG, mDstLowerB;
    1206     GLint mUniDstLowerColor;
    1207 
    1208     GLfloat mSrcUpperR, mSrcUpperG, mSrcUpperB;
    1209     GLint mUniSrcUpperColor;
    1210 
    1211     GLfloat mSrcLowerR, mSrcLowerG, mSrcLowerB;
    1212     GLint mUniSrcLowerColor;
    1213 
    1214     GLint mDstTex;
    1215     GLint mUniDstTex;
    1216 
    1217     GLint mSrcTex;
    1218     GLint mUniSrcTex;
    1219 
    1220     GLint mVTex;
    1221     GLint mUniVTex;
    1222 
    1223     GLint mUTex;
    1224     GLint mUniUTex;
    1225 
    1226 //    VBoxVHWAGlProgram *mpProgram;
    1227 //
    1228 //    class VBoxVHWAGlProgramMngr *mpMngr;
    1229 };
    1230 
    1231 VBoxVHWAGlProgramVHWA::VBoxVHWAGlProgramVHWA(/*VBoxVHWAGlProgramMngr *aMngr, */uint32_t type, uint32_t fourcc, VBoxVHWAGlShader ** apShaders, int acShaders) :
    1232     VBoxVHWAGlProgram(apShaders, acShaders),
    1233     mType(type),
    1234     mFourcc(fourcc),
    1235     mDstUpperR(0.0), mDstUpperG(0.0), mDstUpperB(0.0),
    1236     mUniDstUpperColor(-1),
    1237     mDstLowerR(0.0), mDstLowerG(0.0), mDstLowerB(0.0),
    1238     mUniDstLowerColor(-1),
    1239     mSrcUpperR(0.0), mSrcUpperG(0.0), mSrcUpperB(0.0),
    1240     mUniSrcUpperColor(-1),
    1241     mSrcLowerR(0.0), mSrcLowerG(0.0), mSrcLowerB(0.0),
    1242     mUniSrcLowerColor(-1),
    1243 //    mpMngr(aMngr),
    1244     mDstTex(-1),
    1245     mUniDstTex(-1),
    1246     mSrcTex(-1),
    1247     mUniSrcTex(-1),
    1248     mVTex(-1),
    1249     mUniVTex(-1),
    1250     mUTex(-1),
    1251     mUniUTex(-1)
    1252 {}
    1253 
    1254 int VBoxVHWAGlProgramVHWA::init()
    1255 {
    1256     int rc = VBoxVHWAGlProgram::init();
    1257     if(RT_FAILURE(rc))
    1258         return rc;
    1259     if(rc == VINF_ALREADY_INITIALIZED)
    1260         return rc;
    1261 
    1262     start();
    1263 
    1264     rc = VERR_GENERAL_FAILURE;
    1265 
    1266     do
    1267     {
    1268         mUniSrcTex = vboxglGetUniformLocation(program(), "uSrcTex");
    1269         Assert(mUniSrcTex != -1);
    1270         if(mUniSrcTex == -1)
    1271             break;
    1272         if(type() & VBOXVHWA_PROGRAM_DSTCOLORKEY)
    1273         {
    1274             VBOXQGL_CHECKERR(
    1275                     vboxglUniform1i(mUniSrcTex, 1);
    1276                     );
    1277             mSrcTex = 1;
    1278 
    1279             mUniDstTex = vboxglGetUniformLocation(program(), "uDstTex");
    1280             Assert(mUniDstTex != -1);
    1281             if(mUniDstTex == -1)
    1282                 break;
    1283             VBOXQGL_CHECKERR(
    1284                     vboxglUniform1i(mUniDstTex, 0);
    1285                     );
    1286             mDstTex = 0;
    1287             mUniDstLowerColor = vboxglGetUniformLocation(program(), "uDstClr");
    1288             Assert(mUniDstLowerColor != -1);
    1289             if(mUniDstLowerColor == -1)
    1290                 break;
    1291 
    1292             mDstLowerR = 0.0; mDstLowerG = 0.0; mDstLowerB = 0.0;
    1293 
    1294             VBOXQGL_CHECKERR(
    1295                     vboxglUniform4f(mUniDstLowerColor, 0.0, 0.0, 0.0, 0.0);
    1296                     );
    1297         }
    1298         else
    1299         {
    1300             VBOXQGL_CHECKERR(
    1301                     vboxglUniform1i(mUniSrcTex, 1);
    1302                     );
    1303             mSrcTex = 0;
    1304         }
    1305 
    1306         if(type() & VBOXVHWA_PROGRAM_SRCCOLORKEY)
    1307         {
    1308             mUniSrcLowerColor = vboxglGetUniformLocation(program(), "uSrcClr");
    1309             Assert(mUniSrcLowerColor != -1);
    1310             if(mUniSrcLowerColor == -1)
    1311                 break;
    1312 
    1313             mSrcLowerR = 0.0; mSrcLowerG = 0.0; mSrcLowerB = 0.0;
    1314             VBOXQGL_CHECKERR(
    1315                     vboxglUniform4f(mUniSrcLowerColor, 0.0, 0.0, 0.0, 0.0);
    1316                     );
    1317         }
    1318 
    1319         if(type() & VBOXVHWA_PROGRAM_COLORCONV)
    1320         {
    1321             switch(fourcc())
    1322             {
    1323                 case FOURCC_YV12:
    1324                 {
    1325                     GLint tex = mSrcTex + 1;
    1326 
    1327                     mUniVTex = vboxglGetUniformLocation(program(), "uVTex");
    1328 
    1329                     Assert(mUniVTex != -1);
    1330                     if(mUniVTex == -1)
    1331                         break;
    1332 
    1333                     VBOXQGL_CHECKERR(
    1334                             vboxglUniform1i(mUniVTex, tex);
    1335                             );
    1336                     mVTex = tex;
    1337 
    1338                     tex++;
    1339 
    1340                     mUniUTex = vboxglGetUniformLocation(program(), "uUTex");
    1341                     Assert(mUniUTex != -1);
    1342                     if(mUniUTex == -1)
    1343                         break;
    1344 
    1345                     VBOXQGL_CHECKERR(
    1346                             vboxglUniform1i(mUniUTex, tex);
    1347                             );
    1348                     mUTex = tex;
    1349 
    1350                     break;
    1351                 }
    1352                 case FOURCC_UYVY:
    1353                 case FOURCC_YUY2:
    1354                 case FOURCC_AYUV:
    1355                     break;
    1356                 default:
    1357                     Assert(0);
    1358                     break;
    1359             }
    1360         }
    1361 
    1362         rc = VINF_SUCCESS;
    1363     } while(0);
    1364 
    1365 
    1366     stop();
    1367     if(rc == VINF_SUCCESS)
    1368         return VINF_SUCCESS;
    1369 
    1370     Assert(0);
    1371     VBoxVHWAGlProgram::uninit();
    1372     return VERR_GENERAL_FAILURE;
    1373 }
    1374 
    1375 int VBoxVHWAGlProgramVHWA::setDstCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b)
    1376 {
    1377     Assert(isInitialized());
    1378     if(!isInitialized())
    1379         return VERR_GENERAL_FAILURE;
    1380     if(mDstUpperR == r && mDstUpperG == g && mDstUpperB == b)
    1381         return VINF_ALREADY_INITIALIZED;
    1382     vboxglUniform4f(mUniDstUpperColor, r, g, b, 0.0);
    1383     mDstUpperR = r;
    1384     mDstUpperG = g;
    1385     mDstUpperB = b;
    1386     return VINF_SUCCESS;
    1387 }
    1388 
    1389 int VBoxVHWAGlProgramVHWA::setDstCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b)
    1390 {
    1391     Assert(isInitialized());
    1392     if(!isInitialized())
    1393         return VERR_GENERAL_FAILURE;
    1394     if(mDstLowerR == r && mDstLowerG == g && mDstLowerB == b)
    1395         return VINF_ALREADY_INITIALIZED;
    1396 
    1397 //    VBOXQGLLOG(("setDstCKeyLowerRange: r(%f), g(%f), b(%f)\n", r, g, b));
    1398     VBOXQGL_CHECKERR(
    1399             vboxglUniform4f(mUniDstLowerColor, r, g, b, 0.0);
    1400             );
    1401 
    1402     mDstLowerR = r;
    1403     mDstLowerG = g;
    1404     mDstLowerB = b;
    1405     return VINF_SUCCESS;
    1406 }
    1407 
    1408 int VBoxVHWAGlProgramVHWA::setSrcCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b)
    1409 {
    1410     Assert(isInitialized());
    1411     if(!isInitialized())
    1412         return VERR_GENERAL_FAILURE;
    1413     if(mSrcUpperR == r && mSrcUpperG == g && mSrcUpperB == b)
    1414         return VINF_ALREADY_INITIALIZED;
    1415     vboxglUniform4f(mUniSrcUpperColor, r, g, b, 0.0);
    1416     mSrcUpperR = r;
    1417     mSrcUpperG = g;
    1418     mSrcUpperB = b;
    1419     return VINF_SUCCESS;
    1420 }
    1421 
    1422 int VBoxVHWAGlProgramVHWA::setSrcCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b)
    1423 {
    1424     Assert(isInitialized());
    1425     if(!isInitialized())
    1426         return VERR_GENERAL_FAILURE;
    1427     if(mSrcLowerR == r && mSrcLowerG == g && mSrcLowerB == b)
    1428         return VINF_ALREADY_INITIALIZED;
    1429     VBOXQGL_CHECKERR(
    1430             vboxglUniform4f(mUniSrcLowerColor, r, g, b, 0.0);
    1431             );
    1432     mSrcLowerR = r;
    1433     mSrcLowerG = g;
    1434     mSrcLowerB = b;
    1435     return VINF_SUCCESS;
    1436 }
    1437 
    1438 class VBoxVHWAGlProgramMngr
    1439 {
    1440 public:
    1441     VBoxVHWAGlProgramMngr() :
    1442         mShaderCConvApplyAYUV(":/cconvApplyAYUV.c", GL_FRAGMENT_SHADER),
    1443         mShaderCConvAYUV(":/cconvAYUV.c", GL_FRAGMENT_SHADER),
    1444 //        mShaderCConvAYUVVoid(":/cconvAYUV_void.c", GL_FRAGMENT_SHADER),
    1445         mShaderCConvBGR(":/cconvBGR.c", GL_FRAGMENT_SHADER),
    1446 //        mShaderCConvBGRVoid(":/cconvBGR_void.c", GL_FRAGMENT_SHADER),
    1447         mShaderCConvUYVY(":/cconvUYVY.c", GL_FRAGMENT_SHADER),
    1448 //        mShaderCConvUYVYVoid(":/cconvUYVY_void.c", GL_FRAGMENT_SHADER),
    1449         mShaderCConvYUY2(":/cconvYUY2.c", GL_FRAGMENT_SHADER),
    1450 //        mShaderCConvYUY2Void(":/cconvYUY2_void.c", GL_FRAGMENT_SHADER),
    1451         mShaderCConvYV12(":/cconvYV12.c", GL_FRAGMENT_SHADER),
    1452 //        mShaderCConvYV12Void(":/cconvYV12_void.c", GL_FRAGMENT_SHADER),
    1453         mShaderSplitBGRA(":/splitBGRA.c", GL_FRAGMENT_SHADER),
    1454         mShaderCKeyDst(":/ckeyDst.c", GL_FRAGMENT_SHADER),
    1455 //        mShaderCKeyDstVoid(":/ckeyDst_void.c", GL_FRAGMENT_SHADER),
    1456     //  mShaderCKeySrc;
    1457     //  mShaderCKeySrcVoid;
    1458         mShaderMainOverlay(":/mainOverlay.c", GL_FRAGMENT_SHADER),
    1459         mShaderMainOverlayNoCKey(":/mainOverlayNoCKey.c", GL_FRAGMENT_SHADER)
    1460     {}
    1461 
    1462     VBoxVHWAGlProgramVHWA * getProgram(bool bDstCKey, bool bSrcCKey, const VBoxVHWAColorFormat * pFrom, const VBoxVHWAColorFormat * pTo);
    1463 
    1464     void stopCurrentProgram()
    1465     {
    1466         VBOXQGL_CHECKERR(
    1467             vboxglUseProgram(0);
    1468             );
    1469     }
    1470 private:
    1471     VBoxVHWAGlProgramVHWA * searchProgram(uint32_t type, uint32_t fourcc, bool bCreate);
    1472 
    1473     VBoxVHWAGlProgramVHWA * createProgram(uint32_t type, uint32_t fourcc);
    1474 
    1475 //    int startProgram(VBoxVHWAGlProgramVHWA * pProgram) {mCurrentProgram = pProgram; return pProgram->start();}
    1476 
    1477     typedef std::list <VBoxVHWAGlProgramVHWA*> ProgramList;
    1478 
    1479 //    VBoxVHWAGlProgramVHWA * mCurrentProgram;
    1480     ProgramList mPrograms;
    1481 
    1482     VBoxVHWAGlShader mShaderCConvApplyAYUV;
    1483 
    1484     VBoxVHWAGlShader mShaderCConvAYUV;
    1485 //    VBoxVHWAGlShader mShaderCConvAYUVVoid;
    1486     VBoxVHWAGlShader mShaderCConvBGR;
    1487 //    VBoxVHWAGlShader mShaderCConvBGRVoid;
    1488     VBoxVHWAGlShader mShaderCConvUYVY;
    1489 //    VBoxVHWAGlShader mShaderCConvUYVYVoid;
    1490     VBoxVHWAGlShader mShaderCConvYUY2;
    1491 //    VBoxVHWAGlShader mShaderCConvYUY2Void;
    1492     VBoxVHWAGlShader mShaderCConvYV12;
    1493 //    VBoxVHWAGlShader mShaderCConvYV12Void;
    1494     VBoxVHWAGlShader mShaderSplitBGRA;
    1495 
    1496     VBoxVHWAGlShader mShaderCKeyDst;
    1497 //    VBoxVHWAGlShader mShaderCKeyDstVoid;
    1498 //    VBoxVHWAGlShader mShaderCKeySrc;
    1499 //    VBoxVHWAGlShader mShaderCKeySrcVoid;
    1500 
    1501     VBoxVHWAGlShader mShaderMainOverlay;
    1502     VBoxVHWAGlShader mShaderMainOverlayNoCKey;
    1503 
    1504     friend class VBoxVHWAGlProgramVHWA;
    1505 };
    1506 
    1507 VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::createProgram(uint32_t type, uint32_t fourcc)
    1508 {
    1509     VBoxVHWAGlShader * apShaders[16];
    1510     uint32_t cShaders = 0;
    1511 
    1512     /* workaround for NVIDIA driver bug: ensure we attach the shader before those it is used in */
    1513     /* reserve a slot for the mShaderCConvApplyAYUV,
    1514      * in case it is not used the slot will be occupied by mShaderCConvBGR , which is ok */
    1515     cShaders++;
    1516 
    1517     if(type &  VBOXVHWA_PROGRAM_DSTCOLORKEY)
    1518     {
    1519         apShaders[cShaders++] = &mShaderCKeyDst;
    1520     }
    1521 // ensure we don't have empty functions /* paranoya for for ATI on linux */
    1522 //    else
    1523 //    {
    1524 //        apShaders[cShaders++] = &mShaderCKeyDstVoid;
    1525 //    }
    1526 
    1527     if(type & VBOXVHWA_PROGRAM_SRCCOLORKEY)
    1528     {
    1529         Assert(0);
    1530         /* disabled for now, not really necessary for video overlaying */
    1531     }
    1532 
    1533     bool bFound = false;
    1534 
    1535 //    if(type & VBOXVHWA_PROGRAM_COLORCONV)
    1536     {
    1537         if(fourcc == FOURCC_UYVY)
    1538         {
    1539             apShaders[cShaders++] = &mShaderCConvUYVY;
    1540             bFound = true;
    1541         }
    1542         else if(fourcc == FOURCC_YUY2)
    1543         {
    1544             apShaders[cShaders++] = &mShaderCConvYUY2;
    1545             bFound = true;
    1546         }
    1547         else if(fourcc == FOURCC_YV12)
    1548         {
    1549             apShaders[cShaders++] = &mShaderSplitBGRA;
    1550             apShaders[cShaders++] = &mShaderCConvYV12;
    1551             bFound = true;
    1552         }
    1553         else if(fourcc == FOURCC_AYUV)
    1554         {
    1555             apShaders[cShaders++] = &mShaderCConvAYUV;
    1556             bFound = true;
    1557         }
    1558     }
    1559 
    1560     if(bFound)
    1561     {
    1562         type |= VBOXVHWA_PROGRAM_COLORCONV;
    1563         apShaders[0] = &mShaderCConvApplyAYUV;
    1564     }
    1565     else
    1566     {
    1567         type &= (~VBOXVHWA_PROGRAM_COLORCONV);
    1568         apShaders[0] = &mShaderCConvBGR;
    1569     }
    1570 
    1571     if(type &  VBOXVHWA_PROGRAM_DSTCOLORKEY)
    1572     {
    1573         apShaders[cShaders++] = &mShaderMainOverlay;
    1574     }
    1575     else
    1576     {
    1577         // ensure we don't have empty functions /* paranoya for for ATI on linux */
    1578         apShaders[cShaders++] = &mShaderMainOverlayNoCKey;
    1579     }
    1580 
    1581     Assert(cShaders <= RT_ELEMENTS(apShaders));
    1582 
    1583     VBoxVHWAGlProgramVHWA *pProgram =  new VBoxVHWAGlProgramVHWA(/*this, */type, fourcc, apShaders, cShaders);
    1584     pProgram->init();
    1585 
    1586     return pProgram;
    1587 }
    1588 
    1589 VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::getProgram(bool bDstCKey, bool bSrcCKey, const VBoxVHWAColorFormat * pFrom, const VBoxVHWAColorFormat * pTo)
    1590 {
    1591         Q_UNUSED(pTo);
    1592     uint32_t type = 0;
    1593     uint32_t fourcc = 0;
    1594     if(bDstCKey)
    1595     {
    1596         type |= VBOXVHWA_PROGRAM_DSTCOLORKEY;
    1597     }
    1598     if(bSrcCKey)
    1599     {
    1600         type |= VBOXVHWA_PROGRAM_SRCCOLORKEY;
    1601     }
    1602     if(pFrom && pFrom->fourcc())
    1603     {
    1604         fourcc = pFrom->fourcc();
    1605         type |= VBOXVHWA_PROGRAM_COLORCONV;
    1606     }
    1607     if(type)
    1608         return searchProgram(type, fourcc, true);
    1609     return NULL;
    1610 }
    1611 
    1612 VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::searchProgram(uint32_t type, uint32_t fourcc, bool bCreate)
    1613 {
    1614 //    if(mCurrentProgram && mCurrentProgram->matches(type))
    1615 //        return mCurrentProgram;
    1616 
    1617     for (ProgramList::const_iterator it = mPrograms.begin();
    1618          it != mPrograms.end(); ++ it)
    1619     {
    1620         if (!(*it)->matches(type, fourcc))
    1621         {
    1622             continue;
    1623         }
    1624         return *it;
    1625     }
    1626     if(bCreate)
    1627     {
    1628         VBoxVHWAGlProgramVHWA *pProgram = createProgram(type, fourcc);
    1629         if(pProgram)
    1630         {
    1631             mPrograms.push_back(pProgram);
    1632             return pProgram;
    1633         }
    1634     }
    1635     return NULL;
    1636 }
    1637 
    1638 int VBoxVHWASurfaceBase::setCKey(VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst)
    1639 {
    1640     float r,g,b;
    1641 //    pProgram->start();
    1642 //    pFormat->pixel2Normalized(pCKey->upper(), &r, &g, &b);
    1643 //    int rcU = pProgram->setCKeyUpperRange(r, g, b);
    1644 //    Assert(RT_SUCCESS(rcU));
    1645     pFormat->pixel2Normalized(pCKey->lower(), &r, &g, &b);
    1646     int rcL = bDst ? pProgram->setDstCKeyLowerRange(r, g, b) : pProgram->setSrcCKeyLowerRange(r, g, b);
    1647     Assert(RT_SUCCESS(rcL));
    1648 //    pProgram->stop();
    1649 
    1650     return RT_SUCCESS(rcL) /*&& RT_SUCCESS(rcU)*/ ? VINF_SUCCESS: VERR_GENERAL_FAILURE;
    1651 }
    1652 
    1653 
    1654 
    1655 void VBoxVHWASurfaceBase::setAddress(uchar * addr)
    1656 {
    1657     Assert(addr);
    1658     if(!addr) return;
    1659     if(addr == mAddress) return;
    1660 
    1661     if(mFreeAddress)
    1662     {
    1663         free(mAddress);
    1664     }
    1665 
    1666     mAddress = addr;
    1667     mFreeAddress = false;
    1668 
    1669     mpTex[0]->setAddress(mAddress);
    1670     if(fourcc() == FOURCC_YV12)
    1671     {
    1672         uchar *pTexAddr = mAddress+mpTex[0]->memSize();
    1673         mpTex[1]->setAddress(pTexAddr);
    1674         pTexAddr = pTexAddr+mpTex[1]->memSize();
    1675         mpTex[2]->setAddress(pTexAddr);
    1676     }
    1677 
    1678 //    makeCurrent();
    1679 //    updateTexture(&mRect);
    1680     mUpdateMem2TexRect.set(mRect);
    1681     Assert(!mUpdateMem2TexRect.isClear());
    1682     Assert(mRect.contains(mUpdateMem2TexRect.rect()));
    1683 //    mUpdateTex2FBRect.clear();
    1684 //    Assert(mUpdateTex2FBRect.isClear());
    1685 }
    1686 
    1687 void VBoxVHWASurfaceBase::globalInit()
    1688 {
    1689     VBOXQGLLOG(("globalInit\n"));
    1690 
    1691 //    glEnable(GL_TEXTURE_2D);
    1692     glEnable(GL_TEXTURE_RECTANGLE);
    1693 
    1694     VBOXQGL_CHECKERR(
    1695             glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    1696             );
    1697     VBOXQGL_CHECKERR(
    1698             glPixelStorei(GL_PACK_ALIGNMENT, 1);
    1699             );
    1700 //
    1701 //    VBOXQGL_CHECKERR(
    1702 //            vboxglActiveTexture(GL_TEXTURE1);
    1703 //        );
    1704 //    VBOXQGL_CHECKERR(
    1705 //            glEnable(GL_TEXTURE_2D);
    1706 //            );
    1707 //    VBOXQGL_CHECKERR(
    1708 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    1709 //            );
    1710 //    VBOXQGL_CHECKERR(
    1711 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    1712 //            );
    1713 //    VBOXQGL_CHECKERR(
    1714 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    1715 //            );
    1716 //    VBOXQGL_CHECKERR(
    1717 //            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    1718 //            );
    1719 //
    1720 //    VBOXQGL_CHECKERR(
    1721 //            vboxglActiveTexture(GL_TEXTURE0);
    1722 //        );
    1723 //    VBOXQGL_CHECKERR(
    1724 //            glEnable(GL_TEXTURE_2D);
    1725 //            );
    1726 //    VBOXQGL_CHECKERR(
    1727 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    1728 //            );
    1729 //    VBOXQGL_CHECKERR(
    1730 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    1731 //            );
    1732 //    VBOXQGL_CHECKERR(
    1733 //            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    1734 //            );
    1735 //    VBOXQGL_CHECKERR(
    1736 //            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    1737 //            );
    1738 }
    1739 
    1740 VBoxVHWASurfaceBase::VBoxVHWASurfaceBase(class VBoxGLWidget *aWidget,
    1741         const QSize & aSize,
    1742         const QRect & aTargRect,
    1743         const QRect & aSrcRect,
    1744         const QRect & aVisTargRect,
    1745         VBoxVHWAColorFormat & aColorFormat,
    1746         VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
    1747                     VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
    1748                     bool bVGA) :
    1749                 mRect(0,0,aSize.width(),aSize.height()),
    1750                 mVisibleDisplayInitialized(false),
    1751                 mAddress(NULL),
    1752                 mColorFormat(aColorFormat),
    1753                 mpSrcBltCKey(NULL),
    1754                 mpDstBltCKey(NULL),
    1755                 mpSrcOverlayCKey(NULL),
    1756                 mpDstOverlayCKey(NULL),
    1757                 mpDefaultDstOverlayCKey(NULL),
    1758                 mpDefaultSrcOverlayCKey(NULL),
    1759                 mLockCount(0),
    1760                 mFreeAddress(false),
    1761                 mComplexList(NULL),
    1762                 mWidget(aWidget),
    1763                 mHGHandle(VBOXVHWA_SURFHANDLE_INVALID)
    1764 #ifdef DEBUG
    1765                 ,
    1766                 cFlipsCurr(0),
    1767                 cFlipsTarg(0)
    1768 #endif
    1769 {
    1770     setDstBltCKey(pDstBltCKey);
    1771     setSrcBltCKey(pSrcBltCKey);
    1772 
    1773     setDefaultDstOverlayCKey(pDstOverlayCKey);
    1774     resetDefaultDstOverlayCKey();
    1775 
    1776     setDefaultSrcOverlayCKey(pSrcOverlayCKey);
    1777     resetDefaultSrcOverlayCKey();
    1778 
    1779     mpTex[0] = vboxVHWATextureCreate(QRect(0,0,aSize.width(),aSize.height()), mColorFormat, bVGA);
    1780     if(mColorFormat.fourcc() == FOURCC_YV12)
    1781     {
    1782         QRect rect(0,0,aSize.width()/2,aSize.height()/2);
    1783         mpTex[1] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
    1784         mpTex[2] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
    1785     }
    1786 
    1787     doSetRectValuesInternal(aTargRect, aSrcRect, aVisTargRect);
    1788 //    mTargSize = QRect(0, 0, aTargSize->width(), aTargSize->height());
    1789 
    1790 //    mBytesPerPixel = calcBytesPerPixel(mColorFormat.format(), mColorFormat.type());
    1791 //    mBytesPerLine = mRect.width() * mBytesPerPixel;
    1792 }
    1793 
    1794 VBoxVHWASurfaceBase::~VBoxVHWASurfaceBase()
    1795 {
    1796     uninit();
    1797 }
    1798 
    1799 GLsizei VBoxVHWASurfaceBase::makePowerOf2(GLsizei val)
    1800 {
    1801     int last = ASMBitLastSetS32(val);
    1802     if(last>1)
    1803     {
    1804         last--;
    1805         if((1 << last) != val)
    1806         {
    1807             Assert((1 << last) < val);
    1808             val = (1 << (last+1));
    1809         }
    1810     }
    1811     return val;
    1812 }
    1813 
    1814 ulong VBoxVHWASurfaceBase::calcBytesPerPixel(GLenum format, GLenum type)
    1815 {
    1816     /* we now support only common byte-aligned data */
    1817     int numComponents = 0;
    1818     switch(format)
    1819     {
    1820     case GL_COLOR_INDEX:
    1821     case GL_RED:
    1822     case GL_GREEN:
    1823     case GL_BLUE:
    1824     case GL_ALPHA:
    1825     case GL_LUMINANCE:
    1826         numComponents = 1;
    1827         break;
    1828     case GL_RGB:
    1829     case GL_BGR_EXT:
    1830         numComponents = 3;
    1831         break;
    1832     case GL_RGBA:
    1833     case GL_BGRA_EXT:
    1834         numComponents = 4;
    1835         break;
    1836     case GL_LUMINANCE_ALPHA:
    1837         numComponents = 2;
    1838         break;
    1839     default:
    1840         Assert(0);
    1841         break;
    1842     }
    1843 
    1844     int componentSize = 0;
    1845     switch(type)
    1846     {
    1847     case GL_UNSIGNED_BYTE:
    1848     case GL_BYTE:
    1849         componentSize = 1;
    1850         break;
    1851     //case GL_BITMAP:
    1852     case  GL_UNSIGNED_SHORT:
    1853     case GL_SHORT:
    1854         componentSize = 2;
    1855         break;
    1856     case GL_UNSIGNED_INT:
    1857     case GL_INT:
    1858     case GL_FLOAT:
    1859         componentSize = 4;
    1860         break;
    1861     default:
    1862         Assert(0);
    1863         break;
    1864     }
    1865     return numComponents * componentSize;
    1866 }
    1867 
    1868 void VBoxVHWASurfaceBase::uninit()
    1869 {
    1870 //    mState->makeCurrent(this);
    1871 
    1872     deleteDisplay();
    1873 
    1874     delete mpTex[0];
    1875     if(fourcc() == FOURCC_YV12)
    1876     {
    1877         delete mpTex[1];
    1878         delete mpTex[2];
    1879     }
    1880 
    1881     if(mAddress && mFreeAddress)
    1882     {
    1883         free(mAddress);
    1884         mAddress = NULL;
    1885     }
    1886 }
    1887 
    1888 ulong VBoxVHWASurfaceBase::memSize()
    1889 {
    1890     ulong size = mpTex[0]->memSize();
    1891     if(fourcc() == FOURCC_YV12)
    1892     {
    1893         size += mpTex[1]->memSize() + mpTex[2]->memSize();
    1894     }
    1895     return size;
    1896 }
    1897 
    1898 void VBoxVHWASurfaceBase::init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem)
    1899 {
    1900     if(pPrimary)
    1901     {
    1902         VBOXQGL_CHECKERR(
    1903                 vboxglActiveTexture(GL_TEXTURE1);
    1904             );
    1905     }
    1906 
    1907     int size = memSize();
    1908     uchar * address = (uchar *)malloc(size);
    1909 #ifdef DEBUG_misha
    1910     int tex0Size = mpTex[0]->memSize();
    1911     if(pPrimary)
    1912     {
    1913         memset(address, 0xff, tex0Size);
    1914         Assert(size >= tex0Size);
    1915         if(size > tex0Size)
    1916         {
    1917                 memset(address + tex0Size, 0x0, size - tex0Size);
    1918         }
    1919     }
    1920     else
    1921     {
    1922         memset(address, 0x0f, tex0Size);
    1923         Assert(size >= tex0Size);
    1924         if(size > tex0Size)
    1925         {
    1926                 memset(address + tex0Size, 0x3f, size - tex0Size);
    1927         }
    1928     }
    1929 #else
    1930     memset(address, 0, size);
    1931 #endif
    1932 
    1933     mpTex[0]->init(address);
    1934     if(fourcc() == FOURCC_YV12)
    1935     {
    1936         mpTex[1]->init(address);
    1937         mpTex[2]->init(address);
    1938     }
    1939 
    1940 
    1941     if(pvMem)
    1942     {
    1943         mAddress = pvMem;
    1944         free(address);
    1945         mFreeAddress = false;
    1946 
    1947     }
    1948     else
    1949     {
    1950         mAddress = address;
    1951         mFreeAddress = true;
    1952     }
    1953 
    1954     mpTex[0]->setAddress(mAddress);
    1955     if(fourcc() == FOURCC_YV12)
    1956     {
    1957         uchar *pTexAddr = mAddress+mpTex[0]->memSize();
    1958         mpTex[1]->setAddress(pTexAddr);
    1959         pTexAddr = pTexAddr+mpTex[1]->memSize();
    1960         mpTex[2]->setAddress(pTexAddr);
    1961     }
    1962 
    1963     initDisplay(pPrimary);
    1964 
    1965     mUpdateMem2TexRect.set(mRect);
    1966     Assert(!mUpdateMem2TexRect.isClear());
    1967     Assert(mRect.contains(mUpdateMem2TexRect.rect()));
    1968 
    1969     if(pPrimary)
    1970     {
    1971         VBOXQGLLOG(("restoring to tex 0"));
    1972         VBOXQGL_CHECKERR(
    1973                 vboxglActiveTexture(GL_TEXTURE0);
    1974             );
    1975     }
    1976 
    1977 }
    1978 
    1979 #ifdef DEBUG_misha
    1980 bool g_DbgTest = false;
    1981 #endif
    1982 
    1983 void VBoxVHWATexture::doUpdate(uchar * pAddress, const QRect * pRect)
    1984 {
    1985 #ifdef DEBUG_misha
    1986         if(g_DbgTest)
    1987         {
    1988                 pAddress = (uchar*)malloc(memSize());
    1989                 uchar val = 0;
    1990                 for(uint32_t i = 0; i < memSize(); i++)
    1991                 {
    1992                         pAddress[i] = val;
    1993                         val+=64;
    1994                 }
    1995         }
    1996 #endif
    1997 
    1998     GLenum tt = texTarget();
    1999     if(pRect)
    2000     {
    2001         Assert(mRect.contains(*pRect));
    2002     }
    2003     else
    2004     {
    2005         pRect = &mRect;
    2006     }
    2007 
    2008     Assert(glIsTexture(mTexture));
    2009     VBOXQGL_CHECKERR(
    2010                 glBindTexture(tt, mTexture);
    2011                 );
    2012 
    2013     int x = pRect->x()/mColorFormat.widthCompression();
    2014     int y = pRect->y()/mColorFormat.heightCompression();
    2015     int width = pRect->width()/mColorFormat.widthCompression();
    2016     int height = pRect->height()/mColorFormat.heightCompression();
    2017 
    2018     uchar * address = pAddress + pointOffsetTex(x, y);
    2019 
    2020     VBOXQGL_CHECKERR(
    2021             glPixelStorei(GL_UNPACK_ROW_LENGTH, mRect.width()/mColorFormat.widthCompression());
    2022             );
    2023 
    2024     VBOXQGL_CHECKERR(
    2025             glTexSubImage2D(tt,
    2026                 0,
    2027                 x, y, width, height,
    2028                 mColorFormat.format(),
    2029                 mColorFormat.type(),
    2030                 address);
    2031             );
    2032 
    2033 #ifdef DEBUG_misha
    2034         if(g_DbgTest)
    2035         {
    2036                 free(pAddress);
    2037         }
    2038 #endif
    2039 }
    2040 
    2041 void VBoxVHWATexture::texCoord(int x, int y)
    2042 {
    2043     glTexCoord2f(((float)x)/mTexRect.width()/mColorFormat.widthCompression(), ((float)y)/mTexRect.height()/mColorFormat.heightCompression());
    2044 }
    2045 
    2046 void VBoxVHWATexture::multiTexCoord(GLenum texUnit, int x, int y)
    2047 {
    2048     vboxglMultiTexCoord2f(texUnit, ((float)x)/mTexRect.width()/mColorFormat.widthCompression(), ((float)y)/mTexRect.height()/mColorFormat.heightCompression());
    2049 }
    2050 
    2051 void VBoxVHWATexture::uninit()
    2052 {
    2053     if(mTexture)
    2054     {
    2055         glDeleteTextures(1,&mTexture);
    2056     }
    2057 }
    2058 
    2059 VBoxVHWATexture::VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat)
    2060                 : mAddress(0),
    2061           mTexture(0)
    2062 {
    2063     mColorFormat = aFormat;
    2064     mRect = aRect;
    2065     mBytesPerPixel = mColorFormat.bitsPerPixel()/8;
    2066     mBytesPerPixelTex = mColorFormat.bitsPerPixelTex()/8;
    2067     mBytesPerLine = mBytesPerPixel * mRect.width();
    2068     GLsizei wdt = VBoxVHWASurfaceBase::makePowerOf2(mRect.width()/mColorFormat.widthCompression());
    2069     GLsizei hgt = VBoxVHWASurfaceBase::makePowerOf2(mRect.height()/mColorFormat.heightCompression());
    2070     mTexRect = QRect(0,0,wdt,hgt);
    2071 }
    2072 
    2073 void VBoxVHWATexture::initParams()
    2074 {
    2075     GLenum tt = texTarget();
    2076 
    2077     glTexParameteri(tt, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    2078     VBOXQGL_ASSERTNOERR();
    2079     glTexParameteri(tt, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    2080     VBOXQGL_ASSERTNOERR();
    2081     glTexParameteri(tt, GL_TEXTURE_WRAP_S, GL_CLAMP);
    2082     VBOXQGL_ASSERTNOERR();
    2083 
    2084     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    2085     VBOXQGL_ASSERTNOERR();
    2086     glPixelStorei(GL_PACK_ALIGNMENT, 1);
    2087     VBOXQGL_ASSERTNOERR();
    2088 
    2089     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    2090     VBOXQGL_ASSERTNOERR();
    2091 }
    2092 
    2093 void VBoxVHWATexture::load()
    2094 {
    2095     VBOXQGL_CHECKERR(
    2096             glPixelStorei(GL_UNPACK_ROW_LENGTH, mTexRect.width());
    2097             );
    2098 
    2099     VBOXQGL_CHECKERR(
    2100         glTexImage2D(texTarget(),
    2101                 0,
    2102                   mColorFormat.internalFormat(),
    2103                   mTexRect.width(),
    2104                   mTexRect.height(),
    2105                   0,
    2106                   mColorFormat.format(),
    2107                   mColorFormat.type(),
    2108                   (GLvoid *)mAddress);
    2109         );
    2110 }
    2111 
    2112 void VBoxVHWATexture::init(uchar *pvMem)
    2113 {
    2114 //    GLsizei wdt = mTexRect.width();
    2115 //    GLsizei hgt = mTexRect.height();
    2116 
    2117     VBOXQGL_CHECKERR(
    2118             glGenTextures(1, &mTexture);
    2119         );
    2120 
    2121     VBOXQGLLOG(("tex: %d", mTexture));
    2122 
    2123     bind();
    2124 
    2125     initParams();
    2126 
    2127     setAddress(pvMem);
    2128 
    2129     load();
    2130 }
    2131 
    2132 VBoxVHWATexture::~VBoxVHWATexture()
    2133 {
    2134         uninit();
    2135 }
    2136 
    2137 void VBoxVHWATextureNP2Rect::texCoord(int x, int y)
    2138 {
    2139     glTexCoord2f(((float)x)/mColorFormat.widthCompression(), ((float)y)/mColorFormat.heightCompression());
    2140 }
    2141 
    2142 void VBoxVHWATextureNP2Rect::multiTexCoord(GLenum texUnit, int x, int y)
    2143 {
    2144     vboxglMultiTexCoord2f(texUnit, x/mColorFormat.widthCompression(), y/mColorFormat.heightCompression());
    2145 }
    2146 
    2147 GLenum VBoxVHWATextureNP2Rect::texTarget() {return GL_TEXTURE_RECTANGLE; }
    2148 
    2149 void VBoxVHWASurfaceBase::synchTexMem(const QRect * pRect)
    2150 {
    2151     if(pRect)
    2152     {
    2153         Assert(mRect.contains(*pRect));
    2154     }
    2155 
    2156     if(mUpdateMem2TexRect.isClear())
    2157         return;
    2158 
    2159     if(pRect && !mUpdateMem2TexRect.rect().intersects(*pRect))
    2160         return;
    2161 
    2162     mpTex[0]->update(&mUpdateMem2TexRect.rect());
    2163     if(fourcc() == FOURCC_YV12)
    2164     {
    2165         QRect rect(mUpdateMem2TexRect.rect().x()/2, mUpdateMem2TexRect.rect().y()/2,
    2166                 mUpdateMem2TexRect.rect().width()/2, mUpdateMem2TexRect.rect().height()/2);
    2167         mpTex[1]->update(&rect);
    2168         mpTex[2]->update(&rect);
    2169     }
    2170 
    2171 #if 0
    2172     mUpdateTex2FBRect.add(mUpdateMem2TexRect);
    2173     Assert(!mUpdateTex2FBRect.isClear());
    2174     Assert(mRect.contains(mUpdateTex2FBRect.rect()));
    2175 #endif
    2176     mUpdateMem2TexRect.clear();
    2177     Assert(mUpdateMem2TexRect.isClear());
    2178 //#ifdef DEBUG
    2179 //    VBOXPRINTDIF(dbgTime, ("texMem:"));
    2180 //#endif
    2181 }
    2182 
    2183 void VBoxVHWATextureNP2RectPBO::init(uchar *pvMem)
    2184 {
    2185         VBOXQGL_CHECKERR(
    2186                         vboxglGenBuffers(1, &mPBO);
    2187                         );
    2188         VBoxVHWATextureNP2Rect::init(pvMem);
    2189 }
    2190 
    2191 void VBoxVHWATextureNP2RectPBO::doUpdate(uchar * pAddress, const QRect * pRect)
    2192 {
    2193         Q_UNUSED(pAddress);
    2194         Q_UNUSED(pRect);
    2195 
    2196         vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
    2197 
    2198     GLvoid *buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
    2199 
    2200 //    updateBuffer((uchar*)buf, pRect);
    2201         memcpy(buf, mAddress, memSize());
    2202 
    2203         bool unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    2204         Assert(unmapped);
    2205 
    2206     VBoxVHWATextureNP2Rect::doUpdate(0, &mRect);
    2207 
    2208         vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
    2209 }
    2210 
    2211 VBoxVHWATextureNP2RectPBO::~VBoxVHWATextureNP2RectPBO()
    2212 {
    2213         VBOXQGL_CHECKERR(
    2214                         vboxglDeleteBuffers(1, &mPBO);
    2215                         );
    2216 }
    2217 
    2218 
    2219 void VBoxVHWATextureNP2RectPBO::load()
    2220 {
    2221         VBoxVHWATextureNP2Rect::load();
    2222 
    2223         vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
    2224 
    2225         vboxglBufferData(GL_PIXEL_UNPACK_BUFFER, memSize(), NULL, GL_STREAM_DRAW);
    2226 
    2227         GLvoid *buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
    2228 
    2229 //      updateBuffer((uchar*)buf, &mRect);
    2230         memcpy(buf, mAddress, memSize());
    2231 
    2232         bool unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    2233         Assert(unmapped);
    2234 
    2235         vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
    2236 }
    2237 
    2238 #if 0
    2239 void VBoxVHWASurfaceBase::synch(const QRect * aRect)
    2240 {
    2241     synchFB(aRect);
    2242     synchTex(aRect);
    2243     synchMem(aRect);
    2244 }
    2245 
    2246 void VBoxVHWASurfaceBase::synchFB(const QRect * pRect)
    2247 {
    2248     Assert(isYInverted());
    2249 
    2250     if(pRect)
    2251     {
    2252         Assert(mRect.contains(*pRect));
    2253     }
    2254 
    2255     synchTexMem(pRect);
    2256 
    2257     if(mUpdateTex2FBRect.isClear())
    2258         return;
    2259 
    2260     if(pRect && !mUpdateTex2FBRect.rect().intersects(*pRect))
    2261         return;
    2262 
    2263     mState->makeCurrent(this);
    2264 
    2265     VBOXQGL_CHECKERR(
    2266             glBindTexture(GL_TEXTURE_2D, mTexture);
    2267             );
    2268 
    2269     VBoxVHWAGlProgramMngr * pMngr = getGlProgramMngr();
    2270     pMngr->stopCurrentProgram();
    2271 
    2272     doTex2FB(&mUpdateTex2FBRect.rect(), &mUpdateTex2FBRect.rect());
    2273 
    2274     mUpdateTex2FBRect.clear();
    2275     Assert(mUpdateTex2FBRect.isClear());
    2276 }
    2277 
    2278 void VBoxVHWASurfaceBase::synchMem(const QRect * pRect)
    2279 {
    2280     if(pRect)
    2281     {
    2282         Assert(mRect.contains(*pRect));
    2283     }
    2284 
    2285     if(mUpdateFB2MemRect.isClear())
    2286         return;
    2287 
    2288     if(pRect && !mUpdateFB2MemRect.rect().intersects(*pRect))
    2289         return;
    2290 
    2291     mState->makeYInvertedCurrent(this);
    2292 //    mState->makeCurrent(this);
    2293 
    2294     uchar * address = pointAddress(mUpdateFB2MemRect.rect().x(), mUpdateFB2MemRect.rect().y());
    2295 
    2296     VBOXQGL_CHECKERR(
    2297             glPixelStorei(GL_PACK_ROW_LENGTH, mRect.width());
    2298             );
    2299     VBOXQGL_CHECKERR(
    2300             glReadPixels(
    2301                 mUpdateFB2MemRect.rect().x(),
    2302                 mUpdateFB2MemRect.rect().y(),
    2303                 mUpdateFB2MemRect.rect().width(),
    2304                 mUpdateFB2MemRect.rect().height(),
    2305                 mColorFormat.format(),
    2306                 mColorFormat.type(),
    2307                 address);
    2308             );
    2309 
    2310     mUpdateFB2MemRect.clear();
    2311     Assert(mUpdateFB2TexRect.isClear());
    2312 }
    2313 
    2314 int VBoxVHWASurfaceBase::performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt)
    2315 {
    2316 //    pDstCKey = NULL;
    2317 //    pSrcCKey = NULL;
    2318 
    2319     GLuint tex = pSrcSurface->textureSynched(pSrcRect);
    2320 
    2321     if(pDstCKey)
    2322     {
    2323         synchTex(pDstRect);
    2324     }
    2325 
    2326     mState->makeCurrent(this, blt);
    2327 
    2328     VBoxVHWAGlProgramMngr * pMngr = getGlProgramMngr();
    2329     VBoxVHWAGlProgramVHWA * pProgram = pMngr->getProgram(pSrcCKey != NULL, &pSrcSurface->colorFormat(), &colorFormat());
    2330     if(pProgram)
    2331     {
    2332         if(pSrcCKey != NULL)
    2333         {
    2334             pProgram->start();
    2335             setCKey(pProgram, &pSrcSurface->colorFormat(), pSrcCKey);
    2336 
    2337             vboxglActiveTexture(GL_TEXTURE0);
    2338         }
    2339     }
    2340     else
    2341     {
    2342         pMngr->stopCurrentProgram();
    2343     }
    2344 
    2345 //    if(blt)
    2346     {
    2347         VBOXQGL_CHECKERR(
    2348                 glBindTexture(GL_TEXTURE_2D, tex);
    2349                 );
    2350 
    2351         //TODO: setup strething params
    2352         GLsizei wdt = pSrcSurface->mTexRect.width();
    2353         GLsizei hgt = pSrcSurface->mTexRect.height();
    2354 
    2355         VBOXQGL_CHECKERR(
    2356                 glMatrixMode(GL_TEXTURE);
    2357                 );
    2358         VBOXQGL_CHECKERR(
    2359                 glPushMatrix();
    2360             );
    2361 
    2362         VBoxGLWidget::doSetupMatrix(QSize(wdt, hgt), true);
    2363         VBOXQGL_CHECKERR(
    2364                 glMatrixMode(GL_MODELVIEW);
    2365                 );
    2366 
    2367         doTex2FB(pDstRect, pSrcRect);
    2368 
    2369         VBOXQGL_CHECKERR(
    2370                 glMatrixMode(GL_TEXTURE);
    2371                 );
    2372         VBOXQGL_CHECKERR(
    2373                 glPopMatrix();
    2374                 );
    2375         VBOXQGL_CHECKERR(
    2376                 glMatrixMode(GL_MODELVIEW);
    2377                 );
    2378     }
    2379 //    else
    2380 //    {
    2381 //
    2382 //    }
    2383 
    2384     /* if dst color key */
    2385     /* setup ckey shader */
    2386     if(pDstCKey)
    2387     {
    2388         VBOXQGL_CHECKERR(
    2389                 glBindTexture(GL_TEXTURE_2D, mTexture);
    2390                 );
    2391         pProgram = pMngr->getProgram(true, NULL, NULL);
    2392         /* setup ckey values*/
    2393         setCKey(pProgram, &colorFormat(), pDstCKey);
    2394         pProgram->start();
    2395         doTex2FB(pDstRect, pDstRect);
    2396     }
    2397 
    2398     return VINF_SUCCESS;
    2399 }
    2400 
    2401 int VBoxVHWASurfaceBase::overlay(VBoxVHWASurfaceBase * pOverlaySurface)
    2402 {
    2403     VBOXQGLLOG(("overlay src(0x%x) ", pOverlaySurface));
    2404     VBOXQGLLOG_QRECT("dst: ", &pOverlaySurface->mTargRect, "\n");
    2405     VBOXQGLLOG_QRECT("src: ", &pOverlaySurface->mSrcRect,  "\n");
    2406     VBOXQGLLOG_METHODTIME("time:");
    2407 
    2408     Assert(!pOverlaySurface->isHidden());
    2409 
    2410     if(pOverlaySurface->isHidden())
    2411     {
    2412         VBOXQGLLOG(("!!!hidden!!!\n"));
    2413         return VINF_SUCCESS;
    2414     }
    2415 
    2416     const QRect * pSrcRect = &pOverlaySurface->mSrcRect;
    2417     const QRect * pDstRect = &pOverlaySurface->mTargRect;
    2418     const VBoxVHWAColorKey * pSrcCKey = pOverlaySurface->srcOverlayCKey();
    2419     /* we use src (overlay) surface to maintain overridden dst ckey info
    2420      * to allow multiple overlays have different overridden dst keys for one primary surface */
    2421     /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    2422      * dst ckey value in defaultDstOverlayCKey
    2423      * this allows the NULL to be a valid overridden value as well */
    2424     const VBoxVHWAColorKey * pDstCKey = pOverlaySurface->dstOverlayCKey() ? pOverlaySurface->defaultDstOverlayCKey() : dstOverlayCKey();
    2425 
    2426     return performBlt(pDstRect, pOverlaySurface, pSrcRect, pDstCKey, pSrcCKey, false);
    2427 }
    2428 
    2429 int VBoxVHWASurfaceBase::blt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey)
    2430 {
    2431     if(pDstRect)
    2432     {
    2433         Assert(mRect.contains(*pDstRect));
    2434     }
    2435     else
    2436     {
    2437         pDstRect = &mRect;
    2438     }
    2439 
    2440     if(pSrcRect)
    2441     {
    2442         Assert(pSrcSurface->mRect.contains(*pSrcRect));
    2443     }
    2444     else
    2445     {
    2446         pSrcRect = &pSrcSurface->mRect;
    2447     }
    2448 
    2449     if(!pSrcCKey)
    2450         pSrcCKey = pSrcSurface->srcBltCKey();
    2451     if(!pDstCKey)
    2452         pDstCKey = dstBltCKey();
    2453 
    2454     VBOXQGLLOG(("blt dst(0x%x), src(0x%x)", this, pSrcSurface));
    2455     VBOXQGLLOG_QRECT("dst: ", pDstRect, "\n");
    2456     VBOXQGLLOG_QRECT("src: ", pSrcRect, "\n");
    2457     VBOXQGLLOG_METHODTIME("time:");
    2458     int rc = performBlt(pDstRect, pSrcSurface, pSrcRect, pDstCKey, pSrcCKey, true);
    2459 
    2460     mUpdateFB2TexRect.add(*pDstRect);
    2461     Assert(!mUpdateFB2TexRect.isClear());
    2462     Assert(mRect.contains(mUpdateFB2TexRect.rect()));
    2463 //    synchTexture(pDstRect);
    2464     mUpdateFB2MemRect.add(*pDstRect);
    2465     Assert(!mUpdateFB2MemRect.isClear());
    2466     Assert(mRect.contains(mUpdateFB2MemRect.rect()));
    2467 
    2468     return rc;
    2469 }
    2470 #endif
    2471 void VBoxVHWASurfaceBase::doTex2FB(const QRect * pDstRect, const QRect * pSrcRect)
    2472 {
    2473     int tx1, ty1, tx2, ty2;
    2474     pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
    2475     int bx1, by1, bx2, by2;
    2476     pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
    2477     tx2++; ty2++;bx2++; by2++;
    2478 
    2479 #if 1
    2480 //    VBOXQGL_CHECKERR(
    2481             VBOXQGLLOG_QRECT("texRect: ", &mpTex[0]->texRect(), "\n");
    2482             glBegin(GL_QUADS);
    2483 //            glTexCoord2d(((double)tx1)/mpTex[0]->texRect().width(), ((double)ty1)/mpTex[0]->texRect().height());
    2484 //            glVertex2i(bx1, by1);
    2485 //            glTexCoord2d(((double)tx1)/mpTex[0]->texRect().width(), ((double)ty2)/mpTex[0]->texRect().height());
    2486 //            glVertex2i(bx1, by2);
    2487 //            glTexCoord2d(((double)tx2)/mpTex[0]->texRect().width(), ((double)ty2)/mpTex[0]->texRect().height());
    2488 //            glVertex2i(bx2, by2);
    2489 //            glTexCoord2d(((double)tx2)/mpTex[0]->texRect().width(), ((double)ty1)/mpTex[0]->texRect().height());
    2490 //            glVertex2i(bx2, by1);
    2491             mpTex[0]->texCoord(tx1, ty1);
    2492             glVertex2i(bx1, by1);
    2493             mpTex[0]->texCoord(tx1, ty2);
    2494             glVertex2i(bx1, by2);
    2495             mpTex[0]->texCoord(tx2, ty2);
    2496             glVertex2i(bx2, by2);
    2497             mpTex[0]->texCoord(tx2, ty1);
    2498             glVertex2i(bx2, by1);
    2499 
    2500             glEnd();
    2501 //            );
    2502 #else
    2503         glBegin(GL_QUADS);
    2504         glTexCoord2d(0.0, 0.0);
    2505         glVertex2i(0, 0);
    2506         glTexCoord2d(0.0, 1.0);
    2507         glVertex2i(0, mRect.height());
    2508         glTexCoord2d(1.0, 1.0);
    2509         glVertex2i(mRect.width(), mRect.height());
    2510         glTexCoord2d(1.0, 0.0);
    2511         glVertex2i(mRect.width(), 0);
    2512         glEnd();
    2513 #endif
    2514 }
    2515 
    2516 
    2517 void VBoxVHWASurfaceBase::doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex)
    2518 {
    2519     int tx1, ty1, tx2, ty2;
    2520     pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
    2521     int bx1, by1, bx2, by2;
    2522     pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
    2523     tx2++; ty2++;bx2++; by2++;
    2524     uint32_t t0width = mpTex[0]->rect().width();
    2525     uint32_t t0height = mpTex[0]->rect().height();
    2526 
    2527 //    VBOXQGL_CHECKERR(
    2528             glBegin(GL_QUADS);
    2529             for(int i = 0; i < cSrcTex; i++)
    2530             {
    2531 //                vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2532 //                        ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2533                 mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->texRect().width()), ty1/(t0height/mpTex[i]->rect().height()));
    2534             }
    2535             glVertex2i(bx1, by1);
    2536             for(int i = 0; i < cSrcTex; i++)
    2537             {
    2538 //                vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2539 //                        ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2540                 mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->texRect().width()), ty2/(t0height/mpTex[i]->rect().height()));
    2541             }
    2542             glVertex2i(bx1, by2);
    2543             for(int i = 0; i < cSrcTex; i++)
    2544             {
    2545 //                vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2546 //                        ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2547                 mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->texRect().width()), ty2/(t0height/mpTex[i]->rect().height()));
    2548 
    2549             }
    2550             glVertex2i(bx2, by2);
    2551             for(int i = 0; i < cSrcTex; i++)
    2552             {
    2553 //                vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2554 //                        ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2555                 mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->texRect().width()), ty1/(t0height/mpTex[i]->rect().height()));
    2556             }
    2557             glVertex2i(bx2, by1);
    2558             glEnd();
    2559 //            );
    2560 }
    2561 
    2562 void VBoxVHWASurfaceBase::doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex)
    2563 {
    2564     int tx1, ty1, tx2, ty2;
    2565     pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
    2566     int bx1, by1, bx2, by2;
    2567     pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
    2568     tx2++; ty2++;bx2++; by2++;
    2569     uint32_t t0width = mpTex[0]->rect().width();
    2570     uint32_t t0height = mpTex[0]->rect().height();
    2571 
    2572 //    VBOXQGL_CHECKERR(
    2573             glBegin(GL_QUADS);
    2574             pDstTex->multiTexCoord(GL_TEXTURE0, bx1, by1);
    2575             for(int i = 0; i < cSrcTex; i++)
    2576             {
    2577 //                vboxglMultiTexCoord2d(GL_TEXTURE1 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2578 //                        ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2579                 mpTex[i]->multiTexCoord(GL_TEXTURE1 + i, tx1/(t0width/mpTex[i]->rect().width()), ty1/(t0height/mpTex[i]->rect().height()));
    2580 
    2581             }
    2582             glVertex2i(bx1, by1);
    2583             pDstTex->multiTexCoord(GL_TEXTURE0, bx1, by2);
    2584             for(int i = 0; i < cSrcTex; i++)
    2585             {
    2586 //                vboxglMultiTexCoord2d(GL_TEXTURE1 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2587 //                        ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2588                 mpTex[i]->multiTexCoord(GL_TEXTURE1 + i, tx1/(t0width/mpTex[i]->rect().width()), ty2/(t0height/mpTex[i]->rect().height()));
    2589 
    2590             }
    2591             glVertex2i(bx1, by2);
    2592             pDstTex->multiTexCoord(GL_TEXTURE0, bx2, by2);
    2593             for(int i = 0; i < cSrcTex; i++)
    2594             {
    2595 //                vboxglMultiTexCoord2d(GL_TEXTURE1 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2596 //                        ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2597                 mpTex[i]->multiTexCoord(GL_TEXTURE1 + i, tx2/(t0width/mpTex[i]->rect().width()), ty2/(t0height/mpTex[i]->rect().height()));
    2598 
    2599             }
    2600             glVertex2i(bx2, by2);
    2601             pDstTex->multiTexCoord(GL_TEXTURE0, bx2, by1);
    2602             for(int i = 0; i < cSrcTex; i++)
    2603             {
    2604 //                vboxglMultiTexCoord2d(GL_TEXTURE1 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
    2605 //                        ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
    2606                 mpTex[i]->multiTexCoord(GL_TEXTURE1 + i, tx2/(t0width/mpTex[i]->rect().width()), ty1/(t0height/mpTex[i]->rect().height()));
    2607 
    2608             }
    2609             glVertex2i(bx2, by1);
    2610             glEnd();
    2611 //            );
    2612 
    2613 }
    2614 
    2615 int VBoxVHWASurfaceBase::lock(const QRect * pRect, uint32_t flags)
    2616 {
    2617         Q_UNUSED(flags);
    2618 
    2619     if(pRect)
    2620     {
    2621         Assert(mRect.contains(*pRect));
    2622     }
    2623 
    2624     Assert(mLockCount >= 0);
    2625     if(pRect && pRect->isEmpty())
    2626         return VERR_GENERAL_FAILURE;
    2627     if(mLockCount < 0)
    2628         return VERR_GENERAL_FAILURE;
    2629 
    2630     VBOXQGLLOG(("lock (0x%x)", this));
    2631     VBOXQGLLOG_QRECT("rect: ", pRect ? pRect : &mRect, "\n");
    2632     VBOXQGLLOG_METHODTIME("time ");
    2633 //    if(!(flags & VBOXVHWA_LOCK_DISCARDCONTENTS))
    2634 //    {
    2635 //        synchMem(pRect);
    2636 //    }
    2637 
    2638     mUpdateMem2TexRect.add(pRect ? *pRect : mRect);
    2639 
    2640     Assert(!mUpdateMem2TexRect.isClear());
    2641     Assert(mRect.contains(mUpdateMem2TexRect.rect()));
    2642     return VINF_SUCCESS;
    2643 }
    2644 
    2645 int VBoxVHWASurfaceBase::unlock()
    2646 {
    2647     VBOXQGLLOG(("unlock (0x%x)\n", this));
    2648     mLockCount = 0;
    2649     return VINF_SUCCESS;
    2650 }
    2651 
    2652 void VBoxVHWASurfaceBase::doSetRectValuesInternal(const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect)
    2653 {
    2654     mVisibleTargRect = aVisTargRect.intersected(aTargRect);
    2655     mTargRect = aTargRect;
    2656     mSrcRect = aSrcRect;
    2657     if(mVisibleTargRect.isEmpty() || mTargRect.isEmpty())
    2658     {
    2659         mVisibleSrcRect.setSize(QSize(0, 0));
    2660     }
    2661     else
    2662     {
    2663         float stretchX = float(mSrcRect.width()) / mTargRect.width();
    2664         float stretchY = float(mSrcRect.height()) / mTargRect.height();
    2665         int tx1, tx2, ty1, ty2, vtx1, vtx2, vty1, vty2;
    2666         int sx1, sx2, sy1, sy2;
    2667         mVisibleTargRect.getCoords(&vtx1, &vty1, &vtx2, &vty2);
    2668         mTargRect.getCoords(&tx1, &ty1, &tx2, &ty2);
    2669         mSrcRect.getCoords(&sx1, &sy1, &sx2, &sy2);
    2670         int dx1 = vtx1 - tx1;
    2671         int dy1 = vty1 - ty1;
    2672         int dx2 = vtx2 - tx2;
    2673         int dy2 = vty2 - ty2;
    2674         int vsx1, vsy1, vsx2, vsy2;
    2675         Assert(dx1 >= 0);
    2676         Assert(dy1 >= 0);
    2677         Assert(dx2 <= 0);
    2678         Assert(dy2 <= 0);
    2679         vsx1 = sx1 + int(dx1*stretchX);
    2680         vsy1 = sy1 + int(dy1*stretchY);
    2681         vsx2 = sx2 + int(dx2*stretchX);
    2682         vsy2 = sy2 + int(dy2*stretchY);
    2683         mVisibleSrcRect.setCoords(vsx1, vsy1, vsx2, vsy2);
    2684         Assert(!mVisibleSrcRect.isEmpty());
    2685         Assert(mSrcRect.contains(mVisibleSrcRect));
    2686     }
    2687 }
    2688 
    2689 void VBoxVHWASurfaceBase::setRects(VBoxVHWASurfaceBase *pPrimary, const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect, bool bForceReinit)
    2690 {
    2691     QRect aVisibleTargRect = aVisTargRect.intersected(mTargRect);
    2692 
    2693     if(mTargRect != aTargRect || mSrcRect != aSrcRect || mVisibleTargRect != aVisibleTargRect)
    2694     {
    2695         doSetRectValuesInternal(aTargRect, aSrcRect, aVisTargRect);
    2696         bForceReinit = true;
    2697     }
    2698 
    2699     if(bForceReinit)
    2700     {
    2701         initDisplay(pPrimary);
    2702     }
    2703 }
    2704 
    2705 void VBoxVHWASurfaceBase::setTargRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint & aPoint, const QRect & aVisibleTargRect)
    2706 {
    2707     QRect tRect = targRect();
    2708     tRect.moveTopLeft(aPoint);
    2709     setRects(pPrimary, tRect, srcRect(), aVisibleTargRect, false);
    2710 }
    2711 
    2712 void VBoxVHWASurfaceBase::updateVisibleTargRect(VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect)
    2713 {
    2714     setRects(pPrimary, targRect(), srcRect(), aVisibleTargRect, false);
    2715 }
    2716 
    2717 void VBoxVHWASurfaceBase::deleteDisplay(
    2718 //        bool bInverted
    2719         )
    2720 {
    2721     {
    2722         if(mVisibleDisplayInitialized)
    2723         {
    2724             glDeleteLists(mVisibleDisplay, 1);
    2725             mVisibleDisplayInitialized = false;
    2726         }
    2727     }
    2728 }
    2729 
    2730 void VBoxVHWASurfaceBase::doDisplay(VBoxVHWASurfaceBase *pPrimary, VBoxVHWAGlProgramVHWA * pProgram, bool bBindDst)
    2731 {
    2732     bool bInvokeMultiTex2 = false;
    2733 
    2734     if(pProgram)
    2735     {
    2736         pProgram->start();
    2737 
    2738 //            if(pSrcCKey != NULL)
    2739 //            {
    2740 //                pProgram->start();
    2741 //                setCKey(pProgram, &pSrcSurface->colorFormat(), pSrcCKey);
    2742 
    2743 //                vboxglActiveTexture(GL_TEXTURE0);
    2744 //            }
    2745 
    2746         if(bBindDst)
    2747         {
    2748             vboxglActiveTexture(GL_TEXTURE1);
    2749             mpTex[0]->bind();
    2750             if(fourcc() == FOURCC_YV12)
    2751             {
    2752                 vboxglActiveTexture(GL_TEXTURE1+1);
    2753                 mpTex[1]->bind();
    2754                 vboxglActiveTexture(GL_TEXTURE1 + 2);
    2755                 mpTex[2]->bind();
    2756             }
    2757             vboxglActiveTexture(GL_TEXTURE0);
    2758             pPrimary->mpTex[0]->bind();
    2759             bInvokeMultiTex2 = true;
    2760         }
    2761         else
    2762         {
    2763             if(fourcc() == FOURCC_YV12)
    2764             {
    2765                 vboxglActiveTexture(GL_TEXTURE1);
    2766                 mpTex[1]->bind();
    2767                 vboxglActiveTexture(GL_TEXTURE1 + 1);
    2768                 mpTex[2]->bind();
    2769                 vboxglActiveTexture(GL_TEXTURE0);
    2770             }
    2771             mpTex[0]->bind();
    2772         }
    2773     }
    2774     else
    2775     {
    2776 //        vboxglActiveTexture(GL_TEXTURE0);
    2777         mpTex[0]->bind();
    2778 //        VBOXQGLLOG(("binding (primary??) texture: %d\n", mpTex[0]->texture()));
    2779     }
    2780 
    2781     if(bInvokeMultiTex2)
    2782     {
    2783         doMultiTex2FB(&mVisibleTargRect, pPrimary->mpTex[0], &mVisibleSrcRect,
    2784                 (fourcc() == FOURCC_YV12) ? 3 : 1);
    2785     }
    2786     else
    2787     {
    2788         if(fourcc() == FOURCC_YV12)
    2789         {
    2790             doMultiTex2FB(&mVisibleTargRect, &mVisibleSrcRect, 3 );
    2791         }
    2792         else
    2793         {
    2794             VBOXQGLLOG_QRECT("mVisibleTargRect: ", &mVisibleTargRect, "\n");
    2795             VBOXQGLLOG_QRECT("mVisibleSrcRect: ", &mVisibleSrcRect, "\n");
    2796             doTex2FB(&mVisibleTargRect, &mVisibleSrcRect);
    2797         }
    2798     }
    2799 
    2800     if(pProgram)
    2801     {
    2802         pProgram->stop();
    2803     }
    2804 }
    2805 
    2806 GLuint VBoxVHWASurfaceBase::createDisplay(VBoxVHWASurfaceBase *pPrimary)
    2807 {
    2808     if(mVisibleTargRect.isEmpty())
    2809     {
    2810         Assert(mVisibleSrcRect.isEmpty());
    2811         return 0;
    2812     }
    2813     Assert(!mVisibleSrcRect.isEmpty());
    2814     /* just for the fallback */
    2815     if(mVisibleSrcRect.isEmpty())
    2816     {
    2817         return 0;
    2818     }
    2819 
    2820     VBoxVHWAGlProgramVHWA * pProgram = NULL;
    2821     const VBoxVHWAColorKey * pSrcCKey = NULL, *pDstCKey = NULL;
    2822     if(pPrimary)
    2823     {
    2824         pSrcCKey = getActiveSrcOverlayCKey();
    2825         /* we use src (overlay) surface to maintain overridden dst ckey info
    2826          * to allow multiple overlays have different overridden dst keys for one primary surface */
    2827         /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    2828          * dst ckey value in defaultDstOverlayCKey
    2829          * this allows the NULL to be a valid overridden value as well */
    2830         pDstCKey = getActiveDstOverlayCKey(pPrimary);
    2831 //        pSrcCKey = NULL;
    2832 //        pDstCKey = NULL;
    2833 
    2834         pProgram = mWidget->vboxVHWAGetGlProgramMngr()->getProgram(pDstCKey != NULL, pSrcCKey != NULL, &colorFormat(), &pPrimary->colorFormat());
    2835     }
    2836 
    2837     GLuint display = glGenLists(1);
    2838     VBOXQGL_ASSERTNOERR();
    2839     glNewList(display, GL_COMPILE);
    2840 
    2841     doDisplay(pPrimary, pProgram, pDstCKey != NULL);
    2842 
    2843     glEndList();
    2844     VBOXQGL_ASSERTNOERR();
    2845 
    2846     return display;
    2847 }
    2848 
    2849 void VBoxVHWASurfaceBase::initDisplay(VBoxVHWASurfaceBase *pPrimary)
    2850 {
    2851     deleteDisplay();
    2852 
    2853     mVisibleDisplay = createDisplay(pPrimary);
    2854     mVisibleDisplayInitialized = true;
    2855 }
    2856 
    2857 void VBoxVHWASurfaceBase::updatedMem(const QRect *rec)
    2858 {
    2859     if(rec)
    2860     {
    2861         Assert(mRect.contains(*rec));
    2862     }
    2863     mUpdateMem2TexRect.add(*rec);
    2864 }
    2865 
    2866 //void VBoxVHWASurfaceBase::setVisibleTargetRect(const QRect & aRect)
    2867 //{
    2868 //    Assert(mVisibleRect.contains(aRect));
    2869 //    mVisibleRect = mSrcRect.intersected(aRect);
    2870 //}
    2871 
    2872 void VBoxVHWASurfaceBase::performDisplay(VBoxVHWASurfaceBase *pPrimary)
    2873 {
    2874     Assert(mVisibleDisplayInitialized);
    2875     if(mVisibleDisplay == 0)
    2876     {
    2877         /* nothing to display, i.e. the surface is not visible,
    2878          * in the sense that it's located behind the viewport ranges */
    2879         Assert(mVisibleSrcRect.isEmpty());
    2880         Assert(mVisibleTargRect.isEmpty());
    2881         return;
    2882     }
    2883     else
    2884     {
    2885         Assert(!mVisibleSrcRect.isEmpty());
    2886         Assert(!mVisibleTargRect.isEmpty());
    2887     }
    2888 
    2889     synchTexMem(&mVisibleSrcRect);
    2890     if(pPrimary && getActiveDstOverlayCKey(pPrimary))
    2891     {
    2892         pPrimary->synchTexMem(&mVisibleTargRect);
    2893     }
    2894 
    2895 #ifdef DEBUG_misha
    2896     if(0)
    2897     {
    2898         VBoxVHWAGlProgramVHWA * pProgram = NULL;
    2899         const VBoxVHWAColorKey * pSrcCKey = NULL, *pDstCKey = NULL;
    2900         if(pPrimary)
    2901         {
    2902             pSrcCKey = getActiveSrcOverlayCKey();
    2903             /* we use src (overlay) surface to maintain overridden dst ckey info
    2904              * to allow multiple overlays have different overridden dst keys for one primary surface */
    2905             /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    2906              * dst ckey value in defaultDstOverlayCKey
    2907              * this allows the NULL to be a valid overridden value as well */
    2908             pDstCKey = getActiveDstOverlayCKey(pPrimary);
    2909     //        pSrcCKey = NULL;
    2910     //        pDstCKey = NULL;
    2911 
    2912             pProgram = mWidget->vboxVHWAGetGlProgramMngr()->getProgram(pDstCKey != NULL, pSrcCKey != NULL, &colorFormat(), &pPrimary->colorFormat());
    2913         }
    2914 
    2915         doDisplay(pPrimary, pProgram, pDstCKey != NULL);
    2916 
    2917 //        doDisplay(pPrimary, NULL, false);
    2918     }
    2919     else
    2920 #endif
    2921     {
    2922         VBOXQGL_CHECKERR(
    2923                 glCallList(mVisibleDisplay);
    2924                 );
    2925     }
    2926 }
     43//#include <QFile>
     44//#include <QTextStream>
     45
    292746
    292847/** @class VBoxQGLFrameBuffer
     
    3029148}
    3030149
    3031 VBoxGLWidget::VBoxGLWidget (VBoxConsoleView *aView, QWidget *aParent)
    3032     : QGLWidget (VBoxGLWidget::vboxGLFormat(), aParent),
    3033     mSurfHandleTable(128), /* 128 should be enough */
    3034     mpfnOp(NULL),
    3035     mOpContext(NULL),
    3036     mPixelFormat(0),
    3037     mUsesGuestVRAM(false),
    3038 //    mbVGASurfCreated(false),
    3039     mView(aView),
    3040     mConstructingList(NULL),
    3041     mcRemaining2Contruct(0)
    3042 {
    3043     mpMngr = new VBoxVHWAGlProgramMngr();
    3044 //        /* No need for background drawing */
    3045 //        setAttribute (Qt::WA_OpaquePaintEvent);
    3046 }
    3047 
    3048 const QGLFormat & VBoxGLWidget::vboxGLFormat()
    3049 {
    3050     static QGLFormat vboxFormat = QGLFormat();
    3051     vboxFormat.setAlpha(true);
    3052     Assert(vboxFormat.alpha());
    3053     vboxFormat.setSwapInterval(0);
    3054     Assert(vboxFormat.swapInterval() == 0);
    3055     vboxFormat.setAccum(false);
    3056     Assert(!vboxFormat.accum());
    3057     vboxFormat.setDepth(false);
    3058     Assert(!vboxFormat.depth());
    3059     return vboxFormat;
    3060 }
    3061 
    3062 VBoxGLWidget::~VBoxGLWidget()
    3063 {
    3064     delete mpMngr;
    3065 }
    3066 
    3067 
    3068 void VBoxGLWidget::doSetupMatrix(const QSize & aSize, bool bInverted)
    3069 {
    3070     VBOXQGL_CHECKERR(
    3071             glLoadIdentity();
    3072             );
    3073     if(bInverted)
    3074     {
    3075         VBOXQGL_CHECKERR(
    3076                 glScalef(1.0f/aSize.width(), 1.0f/aSize.height(), 1.0f);
    3077                 );
    3078     }
    3079     else
    3080     {
    3081         /* make display coordinates be scaled to pixel coordinates */
    3082         VBOXQGL_CHECKERR(
    3083                 glTranslatef(0.0f, 1.0f, 0.0f);
    3084                 );
    3085         VBOXQGL_CHECKERR(
    3086                 glScalef(1.0f/aSize.width(), 1.0f/aSize.height(), 1.0f);
    3087                 );
    3088         VBOXQGL_CHECKERR(
    3089                 glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
    3090                 );
    3091     }
    3092 }
    3093 void VBoxGLWidget::adjustViewport(const QSize &display, const QRect &viewport)
    3094 {
    3095     /* viewport:  (viewport.x;viewport.y) (viewport.width;viewport.height)*/
    3096     glViewport(-((int)display.width() + viewport.x()),
    3097                 -((int)display.height() - viewport.y() + display.height() - viewport.height()),
    3098                 2*display.width(),
    3099                 2*display.height());
    3100 }
    3101 
    3102 void VBoxGLWidget::setupMatricies(const QSize &display)
    3103 {
    3104     glMatrixMode(GL_PROJECTION);
    3105     glLoadIdentity();
    3106     glFrustum(0., (GLdouble)display.width(), 0., (GLdouble)display.height(), 0., 0.);
    3107 
    3108     glMatrixMode(GL_MODELVIEW);
    3109     //    doSetupMatrix(bInverted ? &mRect.size() : &mTargSize.size(), bInverted);
    3110     doSetupMatrix(display, false);
    3111 }
    3112 
    3113 VBoxVHWACommandElement * VBoxGLWidget::processCmdList(VBoxVHWACommandElement * pCmd)
    3114 {
    3115     VBoxVHWACommandElement * pCur;
    3116     do
    3117     {
    3118         pCur = pCmd;
    3119         switch(pCmd->type())
    3120         {
    3121         case VBOXVHWA_PIPECMD_PAINT:
    3122             vboxDoUpdateRect(&pCmd->rect());
    3123             break;
     150
    3124151#ifdef VBOX_WITH_VIDEOHWACCEL
    3125         case VBOXVHWA_PIPECMD_VHWA:
    3126             vboxDoVHWACmd(pCmd->vhwaCmd());
    3127             break;
    3128         case VBOXVHWA_PIPECMD_OP:
    3129         {
    3130             const VBOXVHWACALLBACKINFO & info = pCmd->op();
    3131             (info.pThis->*(info.pfnCallback))(info.pContext);
    3132             break;
    3133         }
    3134         case VBOXVHWA_PIPECMD_FUNC:
    3135         {
    3136             const VBOXVHWAFUNCCALLBACKINFO & info = pCmd->func();
    3137             info.pfnCallback(info.pContext1, info.pContext2);
    3138             break;
    3139         }
    3140 #endif
    3141         default:
    3142             Assert(0);
    3143         }
    3144         pCmd = pCmd->mpNext;
    3145     } while(pCmd);
    3146 
    3147     return pCur;
    3148 }
    3149 
    3150 void VBoxGLWidget::vboxDoProcessVHWACommands(void *pContext)
    3151 {
    3152     VBoxVHWACommandElementProcessor * pPipe = (VBoxVHWACommandElementProcessor*)pContext;
    3153     VBoxVHWACommandElement * pFirst = pPipe->detachCmdList(NULL, NULL);
    3154     do
    3155     {
    3156         VBoxVHWACommandElement * pLast = processCmdList(pFirst);
    3157 
    3158         pFirst = pPipe->detachCmdList(pFirst, pLast);
    3159     } while(pFirst);
    3160 
    3161 //    mDisplay.performDisplay();
    3162 }
    3163 
    3164 #ifdef VBOX_WITH_VIDEOHWACCEL
    3165 /* static */
    3166 bool VBoxQGLFrameBuffer::isAcceleration2DVideoAvailable()
    3167 {
    3168     vboxVHWAGlInit(NULL);
    3169     return vboxVHWASupportedInternal();
    3170 }
    3171152
    3172153STDMETHODIMP VBoxQGLFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
     
    3183164}
    3184165
    3185 void VBoxGLWidget::vboxDoVHWACmd(void *cmd)
    3186 {
    3187     vboxDoVHWACmdExec(cmd);
    3188 
    3189     CDisplay display = mView->console().GetDisplay();
    3190     Assert (!display.isNull());
    3191 
    3192     display.CompleteVHWACommand((BYTE*)cmd);
    3193 }
    3194 
    3195 void VBoxGLWidget::vboxDoVHWACmdAndFree(void *cmd)
    3196 {
    3197     vboxDoVHWACmdExec(cmd);
    3198 
    3199     free(cmd);
    3200 }
    3201 
    3202 void VBoxGLWidget::vboxDoVHWACmdExec(void *cmd)
    3203 {
    3204     struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
    3205     switch(pCmd->enmCmd)
     166
     167VBoxQImageOverlayFrameBuffer::VBoxQImageOverlayFrameBuffer (VBoxConsoleView *aView)
     168    : VBoxQImageFrameBuffer(aView),
     169      mOverlay(aView, this)
     170{}
     171
     172
     173STDMETHODIMP VBoxQImageOverlayFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
     174{
     175    return mOverlay.onVHWACommand((VBOXVHWACMD*)pCommand);
     176}
     177
     178void VBoxQImageOverlayFrameBuffer::doProcessVHWACommand(QEvent * pEvent)
     179{
     180    mOverlay.onVHWACommandEvent(pEvent);
     181}
     182
     183STDMETHODIMP VBoxQImageOverlayFrameBuffer::NotifyUpdate (ULONG aX, ULONG aY,
     184                             ULONG aW, ULONG aH)
     185{
     186    if(mOverlay.onNotifyUpdate(aX, aY, aW, aH))
     187        return S_OK;
     188    return VBoxQImageFrameBuffer::NotifyUpdate(aX, aY, aW, aH);
     189}
     190
     191void VBoxQImageOverlayFrameBuffer::paintEvent (QPaintEvent *pe)
     192{
     193    QRect rect;
     194    VBOXFBOVERLAY_RESUT res = mOverlay.onPaintEvent(pe, &rect);
     195    switch(res)
    3206196    {
    3207         case VBOXVHWACMD_TYPE_SURF_CANCREATE:
     197        case VBOXFBOVERLAY_MODIFIED:
    3208198        {
    3209             VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
    3210             pCmd->rc = vhwaSurfaceCanCreate(pBody);
     199            QPaintEvent modified(rect);
     200            VBoxQImageFrameBuffer::paintEvent(&modified);
    3211201        } break;
    3212         case VBOXVHWACMD_TYPE_SURF_CREATE:
    3213         {
    3214             VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
    3215             pCmd->rc = vhwaSurfaceCreate(pBody);
    3216         } break;
    3217         case VBOXVHWACMD_TYPE_SURF_DESTROY:
    3218         {
    3219             VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
    3220             pCmd->rc = vhwaSurfaceDestroy(pBody);
    3221         } break;
    3222         case VBOXVHWACMD_TYPE_SURF_LOCK:
    3223         {
    3224             VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
    3225             pCmd->rc = vhwaSurfaceLock(pBody);
    3226         } break;
    3227         case VBOXVHWACMD_TYPE_SURF_UNLOCK:
    3228         {
    3229             VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
    3230             pCmd->rc = vhwaSurfaceUnlock(pBody);
    3231         } break;
    3232         case VBOXVHWACMD_TYPE_SURF_BLT:
    3233         {
    3234             VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
    3235             pCmd->rc = vhwaSurfaceBlt(pBody);
    3236         } break;
    3237         case VBOXVHWACMD_TYPE_SURF_FLIP:
    3238         {
    3239             VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
    3240             pCmd->rc = vhwaSurfaceFlip(pBody);
    3241         } break;
    3242         case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
    3243         {
    3244             VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
    3245             pCmd->rc = vhwaSurfaceOverlayUpdate(pBody);
    3246         } break;
    3247         case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
    3248         {
    3249             VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
    3250             pCmd->rc = vhwaSurfaceOverlaySetPosition(pBody);
    3251         } break;
    3252         case VBOXVHWACMD_TYPE_SURF_COLORKEY_SET:
    3253         {
    3254             VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
    3255             pCmd->rc = vhwaSurfaceColorkeySet(pBody);
    3256         } break;
    3257         case VBOXVHWACMD_TYPE_QUERY_INFO1:
    3258         {
    3259             VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
    3260             pCmd->rc = vhwaQueryInfo1(pBody);
    3261         } break;
    3262         case VBOXVHWACMD_TYPE_QUERY_INFO2:
    3263         {
    3264             VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
    3265             pCmd->rc = vhwaQueryInfo2(pBody);
    3266         } break;
    3267         case VBOXVHWACMD_TYPE_ENABLE:
    3268         case VBOXVHWACMD_TYPE_DISABLE:
    3269             pCmd->rc = VINF_SUCCESS;
    3270             break;
    3271         case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
    3272         {
    3273             VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
    3274             pCmd->rc = vhwaConstruct(pBody);
    3275         } break;
    3276         default:
    3277             Assert(0);
    3278             pCmd->rc = VERR_NOT_IMPLEMENTED;
     202        case VBOXFBOVERLAY_UNTOUCHED:
     203            VBoxQImageFrameBuffer::paintEvent(pe);
    3279204            break;
    3280205    }
    3281206}
    3282207
    3283 int VBoxGLWidget::vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd)
    3284 {
    3285     VBOXQGLLOG_ENTER(("\n"));
    3286 
    3287     if(!(pCmd->SurfInfo.flags & VBOXVHWA_SD_CAPS))
    3288     {
    3289         Assert(0);
    3290         pCmd->u.out.ErrInfo = 1;
    3291         return VINF_SUCCESS;
    3292     }
    3293 
    3294     if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
    3295     {
    3296         pCmd->u.out.ErrInfo = 0;
    3297         return VINF_SUCCESS;
    3298     }
    3299 
    3300     if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN)
    3301     {
    3302         Assert(0);
    3303         pCmd->u.out.ErrInfo = 1;
    3304         return VINF_SUCCESS;
    3305     }
    3306 
    3307     Assert(/*pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN
    3308             || */ pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY);
    3309 
    3310     if(pCmd->u.in.bIsDifferentPixelFormat)
    3311     {
    3312         if(!(pCmd->SurfInfo.flags & VBOXVHWA_SD_PIXELFORMAT))
    3313         {
    3314             Assert(0);
    3315             pCmd->u.out.ErrInfo = 1;
    3316             return VINF_SUCCESS;
    3317         }
    3318 
    3319         if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
    3320         {
    3321             if(pCmd->SurfInfo.PixelFormat.c.rgbBitCount != 32
    3322                     || pCmd->SurfInfo.PixelFormat.c.rgbBitCount != 24)
    3323             {
    3324                 Assert(0);
    3325                 pCmd->u.out.ErrInfo = 1;
    3326                 return VINF_SUCCESS;
    3327             }
    3328         }
    3329         else if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
    3330         {
    3331             /* detect whether we support this format */
    3332             bool bFound = false;
    3333             for(uint32_t i = 0; i < g_vboxVHWAFourccSupportedCount; i++)
    3334             {
    3335                 if(g_vboxVHWAFourccSupportedList[i] == pCmd->SurfInfo.PixelFormat.fourCC)
    3336                 {
    3337                     bFound = true;
    3338                     break;
    3339                 }
    3340             }
    3341             Assert(bFound);
    3342             if(!bFound)
    3343             {
    3344                 Assert(0);
    3345                 pCmd->u.out.ErrInfo = 1;
    3346                 return VINF_SUCCESS;
    3347             }
    3348         }
    3349         else
    3350         {
    3351             Assert(0);
    3352             pCmd->u.out.ErrInfo = 1;
    3353             return VINF_SUCCESS;
    3354         }
    3355     }
    3356 
    3357     pCmd->u.out.ErrInfo = 0;
    3358     return VINF_SUCCESS;
    3359 }
    3360 
    3361 int VBoxGLWidget::vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd)
    3362 {
    3363     VBOXQGLLOG_ENTER(("\n"));
    3364 
    3365     uint32_t handle = VBOXVHWA_SURFHANDLE_INVALID;
    3366     if(pCmd->SurfInfo.hSurf != VBOXVHWA_SURFHANDLE_INVALID)
    3367     {
    3368         handle = pCmd->SurfInfo.hSurf;
    3369         if(mSurfHandleTable.get(handle))
    3370         {
    3371 //            do
    3372 //            {
    3373 //                if(!mcVGASurfCreated)
    3374 //                {
    3375 //                    /* check if it is a primary surface that needs handle adjusting*/
    3376 //                    if((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
    3377 //                            && handle2Surface(handle) == mDisplay.getVGA())
    3378 //                    {
    3379 //                        /* remove, the primary surface will be assigned to a new handle assumed by the guest */
    3380 //                        mSurfHandleTable.remove(handle);
    3381 //                        break;
    3382 //                    }
    3383 //                }
    3384                 Assert(0);
    3385                 return VERR_GENERAL_FAILURE;
    3386 //            }while(0);
    3387         }
    3388     }
    3389 
    3390     VBoxVHWASurfaceBase *surf = NULL;
    3391 //    VBoxVHWAColorFormat *pFormat = NULL, Format;
    3392     bool bPrimary = false;
    3393 
    3394     VBoxVHWAColorKey *pDstBltCKey = NULL, DstBltCKey;
    3395     VBoxVHWAColorKey *pSrcBltCKey = NULL, SrcBltCKey;
    3396     VBoxVHWAColorKey *pDstOverlayCKey = NULL, DstOverlayCKey;
    3397     VBoxVHWAColorKey *pSrcOverlayCKey = NULL, SrcOverlayCKey;
    3398     if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKDESTBLT)
    3399     {
    3400         DstBltCKey = VBoxVHWAColorKey(pCmd->SurfInfo.DstBltCK.high, pCmd->SurfInfo.DstBltCK.low);
    3401         pDstBltCKey = &DstBltCKey;
    3402     }
    3403     if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKSRCBLT)
    3404     {
    3405         SrcBltCKey = VBoxVHWAColorKey(pCmd->SurfInfo.SrcBltCK.high, pCmd->SurfInfo.SrcBltCK.low);
    3406         pSrcBltCKey = &SrcBltCKey;
    3407     }
    3408     if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKDESTOVERLAY)
    3409     {
    3410         DstOverlayCKey = VBoxVHWAColorKey(pCmd->SurfInfo.DstOverlayCK.high, pCmd->SurfInfo.DstOverlayCK.low);
    3411         pDstOverlayCKey = &DstOverlayCKey;
    3412     }
    3413     if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKSRCOVERLAY)
    3414     {
    3415         SrcOverlayCKey = VBoxVHWAColorKey(pCmd->SurfInfo.SrcOverlayCK.high, pCmd->SurfInfo.SrcOverlayCK.low);
    3416         pSrcOverlayCKey = &SrcOverlayCKey;
    3417     }
    3418 
    3419     if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
    3420     {
    3421         bPrimary = true;
    3422         VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
    3423 
    3424         if(pVga->handle() == VBOXVHWA_SURFHANDLE_INVALID)
    3425         {
    3426             Assert(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB);
    3427 //            if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
    3428             {
    3429                 Assert(pCmd->SurfInfo.width == pVga->width());
    3430                 Assert(pCmd->SurfInfo.height == pVga->height());
    3431 //                if(pCmd->SurfInfo.width == pVga->width()
    3432 //                        && pCmd->SurfInfo.height == pVga->height())
    3433                 {
    3434                     VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.c.rgbBitCount,
    3435                                                 pCmd->SurfInfo.PixelFormat.m1.rgbRBitMask,
    3436                                                 pCmd->SurfInfo.PixelFormat.m2.rgbGBitMask,
    3437                                                 pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
    3438                     Assert(pVga->colorFormat().equals(format));
    3439 //                    if(pVga->colorFormat().equals(format))
    3440                     {
    3441                         surf = pVga;
    3442 
    3443                         surf->setDstBltCKey(pDstBltCKey);
    3444                         surf->setSrcBltCKey(pSrcBltCKey);
    3445 
    3446                         surf->setDefaultDstOverlayCKey(pDstOverlayCKey);
    3447                         surf->resetDefaultDstOverlayCKey();
    3448 
    3449                         surf->setDefaultSrcOverlayCKey(pDstOverlayCKey);
    3450                         surf->resetDefaultSrcOverlayCKey();
    3451 //                        mbVGASurfCreated = true;
    3452                     }
    3453                 }
    3454             }
    3455         }
    3456     }
    3457 
    3458     if(!surf)
    3459     {
    3460         if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
    3461         {
    3462             VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.c.rgbBitCount,
    3463                                                 pCmd->SurfInfo.PixelFormat.m1.rgbRBitMask,
    3464                                                 pCmd->SurfInfo.PixelFormat.m2.rgbGBitMask,
    3465                                                 pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
    3466             QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
    3467             QRect primaryRect = mDisplay.getPrimary()->rect();
    3468             surf = new VBoxVHWASurfaceBase(this, surfSize,
    3469 //                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &surfSize),
    3470                         primaryRect,
    3471                         QRect(0, 0, surfSize.width(), surfSize.height()),
    3472                         mViewport,
    3473                         format,
    3474                         pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
    3475                         bPrimary);
    3476         }
    3477         else if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
    3478         {
    3479             QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
    3480             QRect primaryRect = mDisplay.getPrimary()->rect();
    3481 
    3482             VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.fourCC);
    3483             surf = new VBoxVHWASurfaceBase(this, surfSize,
    3484             //                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
    3485                                     primaryRect,
    3486                                     QRect(0, 0, surfSize.width(), surfSize.height()),
    3487                                     mViewport,
    3488                                     format,
    3489                                     pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
    3490                                     bPrimary);
    3491         }
    3492         else
    3493         {
    3494             Assert(0);
    3495             VBOXQGLLOG_EXIT(("pSurf (0x%x)\n",surf));
    3496             return VERR_GENERAL_FAILURE;
    3497         }
    3498 
    3499         uchar * addr = vboxVRAMAddressFromOffset(pCmd->SurfInfo.offSurface);
    3500         surf->init(mDisplay.getPrimary(), addr);
    3501 
    3502         if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY)
    3503         {
    3504             Assert(!bPrimary);
    3505 
    3506             if(!mConstructingList)
    3507             {
    3508                 mConstructingList = new VBoxVHWASurfList();
    3509                 mcRemaining2Contruct = pCmd->SurfInfo.cBackBuffers+1;
    3510                 mDisplay.addOverlay(mConstructingList);
    3511             }
    3512 
    3513             mConstructingList->add(surf);
    3514             mcRemaining2Contruct--;
    3515             if(!mcRemaining2Contruct)
    3516             {
    3517                 mConstructingList = NULL;
    3518             }
    3519         }
    3520         else if(bPrimary)
    3521         {
    3522             VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
    3523             Assert(pVga->handle() != VBOXVHWA_SURFHANDLE_INVALID);
    3524             Assert(pVga != surf);
    3525 //            Assert(mbVGASurfCreated);
    3526             mDisplay.getVGA()->getComplexList()->add(surf);
    3527             Assert(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE);
    3528 //            if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE)
    3529             {
    3530                 Assert(surf->getComplexList() == mDisplay.getVGA()->getComplexList());
    3531                 surf->getComplexList()->setCurrentVisible(surf);
    3532                 mDisplay.updateVGA(surf);
    3533             }
    3534         }
    3535         else if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_COMPLEX)
    3536         {
    3537             //TODO: impl fullscreen mode support
    3538             Assert(0);
    3539         }
    3540         else
    3541         {
    3542             Assert(0);
    3543         }
    3544     }
    3545 
    3546     Assert(mDisplay.getVGA() == mDisplay.getPrimary());
    3547 
    3548     /* tell the guest how we think the memory is organized */
    3549     VBOXQGLLOG(("bps: %d\n", surf->bitsPerPixel()));
    3550 
    3551     pCmd->SurfInfo.pitch        = surf->bitsPerPixel() * surf->width() / 8;
    3552     pCmd->SurfInfo.sizeX = surf->memSize();
    3553     pCmd->SurfInfo.sizeY = 1;
    3554 
    3555     if(handle != VBOXVHWA_SURFHANDLE_INVALID)
    3556     {
    3557         bool bSuccess = mSurfHandleTable.mapPut(handle, surf);
    3558         Assert(bSuccess);
    3559         if(!bSuccess)
    3560         {
    3561             /* @todo: this is very bad, should not be here */
    3562             return VERR_GENERAL_FAILURE;
    3563         }
    3564     }
    3565     else
    3566     {
    3567         /* tell the guest our handle */
    3568         handle = mSurfHandleTable.put(surf);
    3569         pCmd->SurfInfo.hSurf = (VBOXVHWA_SURFHANDLE)handle;
    3570     }
    3571 
    3572     Assert(handle != VBOXVHWA_SURFHANDLE_INVALID);
    3573     Assert(surf->handle() == VBOXVHWA_SURFHANDLE_INVALID);
    3574     surf->setHandle(handle);
    3575     Assert(surf->handle() == handle);
    3576 
    3577     VBOXQGLLOG_EXIT(("pSurf (0x%x)\n",surf));
    3578 
    3579     return VINF_SUCCESS;
    3580 }
    3581 
    3582 int VBoxGLWidget::vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd)
    3583 {
    3584     VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
    3585     VBoxVHWASurfList *pList = pSurf->getComplexList();
    3586     Assert(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID);
    3587 
    3588     VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
    3589     if(pList != mDisplay.getVGA()->getComplexList())
    3590     {
    3591         Assert(pList);
    3592         pList->remove(pSurf);
    3593         if(pList->surfaces().empty())
    3594         {
    3595             mDisplay.removeOverlay(pList);
    3596 //                Assert(mConstructingList != pList);
    3597             if(pList == mConstructingList)
    3598             {
    3599                 mConstructingList = NULL;
    3600                 mcRemaining2Contruct = 0;
    3601             }
    3602             delete pList;
    3603         }
    3604 
    3605         delete(pSurf);
    3606     }
    3607     else
    3608     {
    3609         Assert(pList->size() >= 1);
    3610         if(pList->size() > 1)
    3611         {
    3612             if(pSurf == mDisplay.getVGA())
    3613             {
    3614                 const SurfList & surfaces = pList->surfaces();
    3615 
    3616                 for (SurfList::const_iterator it = surfaces.begin();
    3617                          it != surfaces.end(); ++ it)
    3618                 {
    3619                     VBoxVHWASurfaceBase *pCurSurf = (*it);
    3620                     if(pCurSurf != pSurf)
    3621                     {
    3622                         mDisplay.updateVGA(pCurSurf);
    3623                         pList->setCurrentVisible(pCurSurf);
    3624                         break;
    3625                     }
    3626                 }
    3627             }
    3628 
    3629             pList->remove(pSurf);
    3630             delete(pSurf);
    3631         }
    3632         else
    3633         {
    3634             pSurf->setHandle(VBOXVHWA_SURFHANDLE_INVALID);
    3635         }
    3636     }
    3637 
    3638     void * test = mSurfHandleTable.remove(pCmd->u.in.hSurf);
    3639     Assert(test);
    3640 
    3641     return VINF_SUCCESS;
    3642 }
    3643 
    3644 #define VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_RB(_pr) \
    3645              QRect((_pr)->left,                     \
    3646                  (_pr)->top,                        \
    3647                  (_pr)->right - (_pr)->left + 1,    \
    3648                  (_pr)->bottom - (_pr)->top + 1)
    3649 
    3650 #define VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(_pr) \
    3651              QRect((_pr)->left,                     \
    3652                  (_pr)->top,                        \
    3653                  (_pr)->right - (_pr)->left,        \
    3654                  (_pr)->bottom - (_pr)->top)
    3655 
    3656 int VBoxGLWidget::vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd)
    3657 {
    3658     VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
    3659     VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
    3660     vboxCheckUpdateAddress (pSurf, pCmd->u.in.offSurface);
    3661     if(pCmd->u.in.rectValid)
    3662     {
    3663         QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.rect);
    3664         return pSurf->lock(&r, pCmd->u.in.flags);
    3665     }
    3666     return pSurf->lock(NULL, pCmd->u.in.flags);
    3667 }
    3668 
    3669 int VBoxGLWidget::vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd)
    3670 {
    3671     VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
    3672     VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
    3673     if(pCmd->u.in.xUpdatedMemValid)
    3674     {
    3675         QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedMemRect);
    3676         pSurf->updatedMem(&r);
    3677     }
    3678     return pSurf->unlock();
    3679 }
    3680 
    3681 int VBoxGLWidget::vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd)
    3682 {
    3683     /**/
    3684     Q_UNUSED(pCmd);
    3685     return VERR_NOT_IMPLEMENTED;
    3686 //    VBoxVHWASurfaceBase *pDstSurf = (VBoxVHWASurfaceBase*)pCmd->u.in.hDstSurf;
    3687 //    VBoxVHWASurfaceBase *pSrcSurf = (VBoxVHWASurfaceBase*)pCmd->u.in.hSrcSurf;
    3688 //    VBOXQGLLOG_ENTER(("pDstSurf (0x%x), pSrcSurf (0x%x)\n",pDstSurf,pSrcSurf));
    3689 //    QRect dstRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL(&pCmd->u.in.dstRect);
    3690 //    QRect srcRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL(&pCmd->u.in.srcRect);
    3691 //    vboxCheckUpdateAddress (pSrcSurf, pCmd->u.in.offSrcSurface);
    3692 //    vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
    3693 ////    pDstSurf->makeCurrent();
    3694 ////    const VBoxVHWAColorKey DstCKey, *pDstCKey = NULL;
    3695 ////    const VBoxVHWAColorKey SrcCKey, *pSrcCKey = NULL;
    3696 ////    if(pCmd->u.in.flags & VBOXVHWA_BLT_KEYSRCOVERRIDE)
    3697 ////    {
    3698 ////        pSrcCKey = &
    3699 ////    }
    3700 ////    if(pCmd->u.in.flags & VBOXVHWA_BLT_KEYDESTOVERRIDE)
    3701 ////    {
    3702 ////
    3703 ////    }
    3704 //    if(pCmd->u.in.xUpdatedSrcMemValid)
    3705 //    {
    3706 //        QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL(&pCmd->u.in.xUpdatedSrcMemRect);
    3707 //        pSrcSurf->updatedMem(&r);
    3708 //    }
    3709 //
    3710 //    return pDstSurf->blt(&dstRect, pSrcSurf, &srcRect,
    3711 //            pCmd->u.in.flags & VBOXVHWA_BLT_KEYSRCOVERRIDE ? &VBoxVHWAColorKey(pCmd->u.in.desc.SrcCK.high, pCmd->u.in.desc.SrcCK.low) : NULL,
    3712 //            pCmd->u.in.flags & VBOXVHWA_BLT_KEYDESTOVERRIDE ? &VBoxVHWAColorKey(pCmd->u.in.desc.DstCK.high, pCmd->u.in.desc.DstCK.low) : NULL);
    3713 }
    3714 
    3715 int VBoxGLWidget::vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd)
    3716 {
    3717     VBoxVHWASurfaceBase *pTargSurf = handle2Surface(pCmd->u.in.hTargSurf);
    3718     VBoxVHWASurfaceBase *pCurrSurf = handle2Surface(pCmd->u.in.hCurrSurf);
    3719     VBOXQGLLOG_ENTER(("pTargSurf (0x%x), pCurrSurf (0x%x)\n",pTargSurf,pCurrSurf));
    3720     vboxCheckUpdateAddress (pCurrSurf, pCmd->u.in.offCurrSurface);
    3721     vboxCheckUpdateAddress (pTargSurf, pCmd->u.in.offTargSurface);
    3722 
    3723 //    Assert(pTargSurf->isYInverted());
    3724 //    Assert(!pCurrSurf->isYInverted());
    3725     if(pCmd->u.in.xUpdatedTargMemValid)
    3726     {
    3727         QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedTargMemRect);
    3728         pTargSurf->updatedMem(&r);
    3729     }
    3730     pTargSurf->getComplexList()->setCurrentVisible(pTargSurf);
    3731 
    3732 #ifdef DEBUG
    3733     pCurrSurf->cFlipsCurr++;
    3734     pTargSurf->cFlipsTarg++;
    3735 #endif
    3736 //    mDisplay.flip(pTargSurf, pCurrSurf);
    3737 //    Assert(!pTargSurf->isYInverted());
    3738 //    Assert(pCurrSurf->isYInverted());
    3739     return VINF_SUCCESS;
    3740 }
    3741 
    3742 void VBoxGLWidget::vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd)
    3743 {
    3744     if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYDEST)
    3745     {
    3746         VBOXQGLLOG((", KEYDEST"));
    3747         /* we use src (overlay) surface to maintain overridden dst ckey info
    3748          * to allow multiple overlays have different overridden dst keys for one primary surface */
    3749         /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    3750          * dst ckey value in defaultDstOverlayCKey
    3751          * this allows the NULL to be a valid overridden value as well
    3752          *  i.e.
    3753          * 1. indicate the value is NUL overridden, just set NULL*/
    3754         pSrcSurf->setOverriddenDstOverlayCKey(NULL);
    3755     }
    3756     else if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYDESTOVERRIDE)
    3757     {
    3758         VBOXQGLLOG((", KEYDESTOVERRIDE"));
    3759         /* we use src (overlay) surface to maintain overridden dst ckey info
    3760          * to allow multiple overlays have different overridden dst keys for one primary surface */
    3761         /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    3762          * dst ckey value in defaultDstOverlayCKey
    3763          * this allows the NULL to be a valid overridden value as well
    3764          *  i.e.
    3765          * 1. indicate the value is overridden (no matter what we write here, bu it should be not NULL)*/
    3766         VBoxVHWAColorKey ckey(pCmd->u.in.desc.DstCK.high, pCmd->u.in.desc.DstCK.low);
    3767         VBOXQGLLOG_CKEY(" ckey: ",&ckey, "\n");
    3768         pSrcSurf->setOverriddenDstOverlayCKey(&ckey);
    3769         /* tell the ckey is enabled */
    3770         pSrcSurf->setDefaultDstOverlayCKey(&ckey);
    3771     }
    3772     else
    3773     {
    3774         VBOXQGLLOG((", no KEYDEST"));
    3775         /* we use src (overlay) surface to maintain overridden dst ckey info
    3776          * to allow multiple overlays have different overridden dst keys for one primary surface */
    3777         /* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
    3778          * dst ckey value in defaultDstOverlayCKey
    3779          * this allows the NULL to be a valid overridden value as well
    3780          * i.e.
    3781          * 1. indicate the value is overridden (no matter what we write here, bu it should be not NULL)*/
    3782         VBoxVHWAColorKey dummyCKey(0, 0);
    3783         pSrcSurf->setOverriddenDstOverlayCKey(&dummyCKey);
    3784         /* tell the ckey is disabled */
    3785         pSrcSurf->setDefaultDstOverlayCKey(NULL);
    3786     }
    3787 
    3788     if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYSRC)
    3789     {
    3790         VBOXQGLLOG((", KEYSRC"));
    3791         pSrcSurf->resetDefaultSrcOverlayCKey();
    3792     }
    3793     else if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYSRCOVERRIDE)
    3794     {
    3795         VBOXQGLLOG((", KEYSRCOVERRIDE"));
    3796         VBoxVHWAColorKey ckey(pCmd->u.in.desc.SrcCK.high, pCmd->u.in.desc.SrcCK.low);
    3797         pSrcSurf->setOverriddenSrcOverlayCKey(&ckey);
    3798     }
    3799     else
    3800     {
    3801         VBOXQGLLOG((", no KEYSRC"));
    3802         pSrcSurf->setOverriddenSrcOverlayCKey(NULL);
    3803     }
    3804     VBOXQGLLOG(("\n"));
    3805     if(pDstSurf)
    3806     {
    3807         QRect dstRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.dstRect);
    3808         QRect srcRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.srcRect);
    3809 
    3810         VBOXQGLLOG(("*******overlay update*******\n"));
    3811         VBOXQGLLOG(("dstSurfSize: w(%d), h(%d)\n", pDstSurf->width(), pDstSurf->height()));
    3812         VBOXQGLLOG(("srcSurfSize: w(%d), h(%d)\n", pSrcSurf->width(), pSrcSurf->height()));
    3813         VBOXQGLLOG_QRECT("dstRect:", &dstRect, "\n");
    3814         VBOXQGLLOG_QRECT("srcRect:", &srcRect, "\n");
    3815 
    3816         const VBoxVHWAColorKey *pResSrcCKey = pSrcSurf->getActiveSrcOverlayCKey();
    3817         const VBoxVHWAColorKey *pResDstCKey = pSrcSurf->getActiveDstOverlayCKey(pDstSurf);
    3818 
    3819         VBoxVHWAGlProgramVHWA *pProgram = vboxVHWAGetGlProgramMngr()->getProgram(pResDstCKey != NULL, pResSrcCKey != NULL, &pSrcSurf->colorFormat(), &pDstSurf->colorFormat());
    3820 
    3821         if(pProgram)
    3822         {
    3823             pProgram->start();
    3824             if(pResSrcCKey || pResDstCKey)
    3825             {
    3826                 if(pResSrcCKey)
    3827                 {
    3828                     VBoxVHWASurfaceBase::setCKey(pProgram, &pSrcSurf->colorFormat(), pResSrcCKey, false);
    3829                 }
    3830                 if(pResDstCKey)
    3831                 {
    3832                     VBoxVHWASurfaceBase::setCKey(pProgram, &pDstSurf->colorFormat(), pResDstCKey, true);
    3833                 }
    3834 
    3835             }
    3836 
    3837             switch(pSrcSurf->fourcc())
    3838             {
    3839                 case 0:
    3840                 case FOURCC_AYUV:
    3841                 case FOURCC_YV12:
    3842                     break;
    3843                 case FOURCC_UYVY:
    3844                 case FOURCC_YUY2:
    3845                     break;
    3846                 default:
    3847                     Assert(0);
    3848                     break;
    3849             }
    3850 
    3851             pProgram->stop();
    3852         }
    3853 
    3854         pSrcSurf->setRects(pDstSurf, dstRect, srcRect, mViewport, true);
    3855     }
    3856 }
    3857 
    3858 int VBoxGLWidget::vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd)
    3859 {
    3860     VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(pCmd->u.in.hSrcSurf);
    3861     VBoxVHWASurfList *pList = pSrcSurf->getComplexList();
    3862     vboxCheckUpdateAddress (pSrcSurf, pCmd->u.in.offSrcSurface);
    3863     VBOXQGLLOG(("OverlayUpdate: pSrcSurf (0x%x)\n",pSrcSurf));
    3864     VBoxVHWASurfaceBase *pDstSurf = NULL;
    3865 
    3866     if(pCmd->u.in.hDstSurf)
    3867     {
    3868         pDstSurf = handle2Surface(pCmd->u.in.hDstSurf);
    3869         vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
    3870         VBOXQGLLOG(("pDstSurf (0x%x)\n",pDstSurf));
    3871         Assert(pDstSurf == mDisplay.getVGA());
    3872         Assert(mDisplay.getVGA() == mDisplay.getPrimary());
    3873         Assert(pDstSurf->getComplexList() == mDisplay.getVGA()->getComplexList());
    3874 
    3875         if(pCmd->u.in.flags & VBOXVHWA_OVER_SHOW)
    3876         {
    3877             if(pDstSurf != mDisplay.getPrimary())
    3878             {
    3879                 mDisplay.updateVGA(pDstSurf);
    3880                 pDstSurf->getComplexList()->setCurrentVisible(pDstSurf);
    3881             }
    3882         }
    3883     }
    3884 
    3885     const SurfList & surfaces = pList->surfaces();
    3886 
    3887     for (SurfList::const_iterator it = surfaces.begin();
    3888              it != surfaces.end(); ++ it)
    3889     {
    3890         VBoxVHWASurfaceBase *pCurSrcSurf = (*it);
    3891         vhwaDoSurfaceOverlayUpdate(pDstSurf, pCurSrcSurf, pCmd);
    3892     }
    3893 
    3894     if(pCmd->u.in.flags & VBOXVHWA_OVER_HIDE)
    3895     {
    3896         VBOXQGLLOG(("hide"));
    3897         pList->setCurrentVisible(NULL);
    3898     }
    3899     else if(pCmd->u.in.flags & VBOXVHWA_OVER_SHOW)
    3900     {
    3901         VBOXQGLLOG(("show"));
    3902         pList->setCurrentVisible(pSrcSurf);
    3903     }
    3904 
    3905     return VINF_SUCCESS;
    3906 }
    3907 
    3908 int VBoxGLWidget::vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd)
    3909 {
    3910     VBoxVHWASurfaceBase *pDstSurf = handle2Surface(pCmd->u.in.hDstSurf);
    3911     VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(pCmd->u.in.hSrcSurf);
    3912 
    3913     VBOXQGLLOG_ENTER(("pDstSurf (0x%x), pSrcSurf (0x%x)\n",pDstSurf,pSrcSurf));
    3914 
    3915     vboxCheckUpdateAddress (pSrcSurf, pCmd->u.in.offSrcSurface);
    3916     vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
    3917 
    3918     VBoxVHWASurfList *pList = pSrcSurf->getComplexList();
    3919     const SurfList & surfaces = pList->surfaces();
    3920 
    3921     QPoint pos(pCmd->u.in.xPos, pCmd->u.in.yPos);
    3922 
    3923     for (SurfList::const_iterator it = surfaces.begin();
    3924              it != surfaces.end(); ++ it)
    3925     {
    3926         VBoxVHWASurfaceBase *pCurSrcSurf = (*it);
    3927         pCurSrcSurf->setTargRectPosition(pDstSurf, pos, mViewport);
    3928     }
    3929 
    3930     return VINF_SUCCESS;
    3931 }
    3932 
    3933 int VBoxGLWidget::vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd)
    3934 {
    3935     VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
    3936 
    3937     VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
    3938 
    3939     vboxCheckUpdateAddress (pSurf, pCmd->u.in.offSurface);
    3940 
    3941 //    VBOXVHWA_CKEY_COLORSPACE
    3942     if(pCmd->u.in.flags & VBOXVHWA_CKEY_DESTBLT)
    3943     {
    3944         VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
    3945         pSurf->setDstBltCKey(&ckey);
    3946     }
    3947     if(pCmd->u.in.flags & VBOXVHWA_CKEY_DESTOVERLAY)
    3948     {
    3949         VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
    3950         pSurf->setDefaultDstOverlayCKey(&ckey);
    3951     }
    3952     if(pCmd->u.in.flags & VBOXVHWA_CKEY_SRCBLT)
    3953     {
    3954         VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
    3955         pSurf->setSrcBltCKey(&ckey);
    3956     }
    3957     if(pCmd->u.in.flags & VBOXVHWA_CKEY_SRCOVERLAY)
    3958     {
    3959         VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
    3960         pSurf->setDefaultSrcOverlayCKey(&ckey);
    3961     }
    3962 
    3963     return VINF_SUCCESS;
    3964 }
    3965 
    3966 int VBoxGLWidget::vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd)
    3967 {
    3968     VBOXQGLLOG_ENTER(("\n"));
    3969     bool bEnabled = false;
    3970     if(vboxVHWASupportedInternal())
    3971     {
    3972         Assert(pCmd->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ);
    3973         if(pCmd->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ)
    3974         {
    3975             Assert(pCmd->u.in.guestVersion.min == VBOXVHWA_VERSION_MIN);
    3976             if(pCmd->u.in.guestVersion.min == VBOXVHWA_VERSION_MIN)
    3977             {
    3978                 Assert(pCmd->u.in.guestVersion.bld == VBOXVHWA_VERSION_BLD);
    3979                 if(pCmd->u.in.guestVersion.bld == VBOXVHWA_VERSION_BLD)
    3980                 {
    3981                     Assert(pCmd->u.in.guestVersion.reserved == VBOXVHWA_VERSION_RSV);
    3982                     if(pCmd->u.in.guestVersion.reserved == VBOXVHWA_VERSION_RSV)
    3983                     {
    3984                         bEnabled = true;
    3985                     }
    3986                 }
    3987             }
    3988         }
    3989     }
    3990 
    3991     memset(pCmd, 0, sizeof(VBOXVHWACMD_QUERYINFO1));
    3992     if(bEnabled)
    3993     {
    3994         pCmd->u.out.cfgFlags = VBOXVHWA_CFG_ENABLED;
    3995 
    3996         pCmd->u.out.caps =
    3997 //                        VBOXVHWA_CAPS_BLT | VBOXVHWA_CAPS_BLTSTRETCH | VBOXVHWA_CAPS_BLTQUEUE
    3998 //                                 // | VBOXVHWA_CAPS_BLTCOLORFILL not supported, although adding it is trivial
    3999 //                                 // | VBOXVHWA_CAPS_BLTFOURCC set below if shader support is available
    4000                                  VBOXVHWA_CAPS_OVERLAY
    4001                                  | VBOXVHWA_CAPS_OVERLAYSTRETCH
    4002                                  | VBOXVHWA_CAPS_OVERLAYCANTCLIP
    4003                                  // | VBOXVHWA_CAPS_OVERLAYFOURCC set below if shader support is available
    4004                                  ;
    4005 
    4006         pCmd->u.out.caps2 = VBOXVHWA_CAPS2_CANRENDERWINDOWED
    4007                                     | VBOXVHWA_CAPS2_WIDESURFACES;
    4008 
    4009         //TODO: setup stretchCaps
    4010         pCmd->u.out.stretchCaps = 0;
    4011 
    4012         pCmd->u.out.numOverlays = 1;
    4013         /* TODO: set curOverlays properly */
    4014         pCmd->u.out.curOverlays = 0;
    4015 
    4016         pCmd->u.out.surfaceCaps =
    4017                             VBOXVHWA_SCAPS_PRIMARYSURFACE
    4018                     //        | VBOXVHWA_SCAPS_OFFSCREENPLAIN
    4019                             | VBOXVHWA_SCAPS_FLIP
    4020                             | VBOXVHWA_SCAPS_LOCALVIDMEM
    4021                             | VBOXVHWA_SCAPS_OVERLAY
    4022                     //        | VBOXVHWA_SCAPS_VIDEOMEMORY
    4023                     //        | VBOXVHWA_SCAPS_COMPLEX
    4024                     //        | VBOXVHWA_SCAPS_VISIBLE
    4025                             ;
    4026 
    4027         if(g_vboxVHWAGlShaderSupported && g_vboxVHWAGlMultiTexNumSupported >= 2)
    4028         {
    4029             pCmd->u.out.caps |= VBOXVHWA_CAPS_COLORKEY
    4030                             | VBOXVHWA_CAPS_COLORKEYHWASSIST
    4031                             ;
    4032 
    4033             pCmd->u.out.colorKeyCaps =
    4034 //                          VBOXVHWA_CKEYCAPS_DESTBLT | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE | VBOXVHWA_CKEYCAPS_SRCBLT| VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE |
    4035 //                          VBOXVHWA_CKEYCAPS_SRCOVERLAY | VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE |
    4036                             VBOXVHWA_CKEYCAPS_DESTOVERLAY          |
    4037                             VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE;
    4038                             ;
    4039 
    4040             if(g_vboxVHWAGlTextureRectangleSupported)
    4041             {
    4042                 pCmd->u.out.caps |= VBOXVHWA_CAPS_OVERLAYFOURCC
    4043 //                              | VBOXVHWA_CAPS_BLTFOURCC
    4044                                 ;
    4045 
    4046                 pCmd->u.out.colorKeyCaps |=
    4047 //                               VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV |
    4048                                  VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV;
    4049                                  ;
    4050 
    4051 //              pCmd->u.out.caps2 |= VBOXVHWA_CAPS2_COPYFOURCC;
    4052 
    4053                 pCmd->u.out.numFourCC = g_vboxVHWAFourccSupportedCount;
    4054             }
    4055         }
    4056     }
    4057 
    4058     return VINF_SUCCESS;
    4059 }
    4060 
    4061 int VBoxGLWidget::vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd)
    4062 {
    4063     VBOXQGLLOG_ENTER(("\n"));
    4064 
    4065     Assert(pCmd->numFourCC >= g_vboxVHWAFourccSupportedCount);
    4066     if(pCmd->numFourCC < g_vboxVHWAFourccSupportedCount)
    4067         return VERR_GENERAL_FAILURE;
    4068 
    4069     pCmd->numFourCC = g_vboxVHWAFourccSupportedCount;
    4070     for(uint32_t i = 0; i < g_vboxVHWAFourccSupportedCount; i++)
    4071     {
    4072         pCmd->FourCC[i] = g_vboxVHWAFourccSupportedList[i];
    4073     }
    4074     return VINF_SUCCESS;
    4075 }
    4076 
    4077 static DECLCALLBACK(void) vboxQGLSaveExec(PSSMHANDLE pSSM, void *pvUser)
    4078 {
    4079     VBoxGLWidget * pw = (VBoxGLWidget*)pvUser;
    4080     pw->vhwaSaveExec(pSSM);
    4081 }
    4082 
    4083 static DECLCALLBACK(int) vboxQGLLoadExec(PSSMHANDLE pSSM, void *pvUser, uint32_t u32Version, uint32_t uPass)
    4084 {
    4085     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    4086     VBoxGLWidget * pw = (VBoxGLWidget*)pvUser;
    4087     return pw->vhwaLoadExec(NULL, pSSM, u32Version);
    4088 }
    4089 
    4090 int VBoxGLWidget::vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps)
    4091 {
    4092     VBOXQGL_SAVE_SURFSTART(pSSM);
    4093 
    4094     uint64_t u64 = vboxVRAMOffset(pSurf);
    4095     int rc;
    4096     rc = SSMR3PutU32(pSSM, pSurf->handle());         AssertRC(rc);
    4097     rc = SSMR3PutU64(pSSM, u64);         AssertRC(rc);
    4098     rc = SSMR3PutU32(pSSM, pSurf->width());         AssertRC(rc);
    4099     rc = SSMR3PutU32(pSSM, pSurf->height());         AssertRC(rc);
    4100     rc = SSMR3PutU32(pSSM, surfCaps);         AssertRC(rc);
    4101     uint32_t flags = 0;
    4102     const VBoxVHWAColorKey * pDstBltCKey = pSurf->dstBltCKey();
    4103     const VBoxVHWAColorKey * pSrcBltCKey = pSurf->srcBltCKey();
    4104     const VBoxVHWAColorKey * pDstOverlayCKey = pSurf->dstOverlayCKey();
    4105     const VBoxVHWAColorKey * pSrcOverlayCKey = pSurf->srcOverlayCKey();
    4106     if(pDstBltCKey)
    4107     {
    4108         flags |= VBOXVHWA_SD_CKDESTBLT;
    4109     }
    4110     if(pSrcBltCKey)
    4111     {
    4112         flags |= VBOXVHWA_SD_CKSRCBLT;
    4113     }
    4114     if(pDstOverlayCKey)
    4115     {
    4116         flags |= VBOXVHWA_SD_CKDESTOVERLAY;
    4117     }
    4118     if(pSrcOverlayCKey)
    4119     {
    4120         flags |= VBOXVHWA_SD_CKSRCOVERLAY;
    4121     }
    4122 
    4123     rc = SSMR3PutU32(pSSM, flags);         AssertRC(rc);
    4124     if(pDstBltCKey)
    4125     {
    4126         rc = SSMR3PutU32(pSSM, pDstBltCKey->lower());         AssertRC(rc);
    4127         rc = SSMR3PutU32(pSSM, pDstBltCKey->upper());         AssertRC(rc);
    4128     }
    4129     if(pSrcBltCKey)
    4130     {
    4131         rc = SSMR3PutU32(pSSM, pSrcBltCKey->lower());         AssertRC(rc);
    4132         rc = SSMR3PutU32(pSSM, pSrcBltCKey->upper());         AssertRC(rc);
    4133     }
    4134     if(pDstOverlayCKey)
    4135     {
    4136         rc = SSMR3PutU32(pSSM, pDstOverlayCKey->lower());         AssertRC(rc);
    4137         rc = SSMR3PutU32(pSSM, pDstOverlayCKey->upper());         AssertRC(rc);
    4138     }
    4139     if(pSrcOverlayCKey)
    4140     {
    4141         rc = SSMR3PutU32(pSSM, pSrcOverlayCKey->lower());         AssertRC(rc);
    4142         rc = SSMR3PutU32(pSSM, pSrcOverlayCKey->upper());         AssertRC(rc);
    4143     }
    4144 
    4145     const VBoxVHWAColorFormat & format = pSurf->colorFormat();
    4146     flags = 0;
    4147     if(format.fourcc())
    4148     {
    4149         flags |= VBOXVHWA_PF_FOURCC;
    4150         rc = SSMR3PutU32(pSSM, flags);         AssertRC(rc);
    4151         rc = SSMR3PutU32(pSSM, format.fourcc());         AssertRC(rc);
    4152     }
    4153     else
    4154     {
    4155         flags |= VBOXVHWA_PF_RGB;
    4156         rc = SSMR3PutU32(pSSM, flags);         AssertRC(rc);
    4157         rc = SSMR3PutU32(pSSM, format.bitsPerPixel());         AssertRC(rc);
    4158         rc = SSMR3PutU32(pSSM, format.r().mask());         AssertRC(rc);
    4159         rc = SSMR3PutU32(pSSM, format.g().mask());         AssertRC(rc);
    4160         rc = SSMR3PutU32(pSSM, format.b().mask());         AssertRC(rc);
    4161         rc = SSMR3PutU32(pSSM, format.a().mask());         AssertRC(rc);
    4162     }
    4163 
    4164     VBOXQGL_SAVE_SURFSTOP(pSSM);
    4165 
    4166     return rc;
    4167 }
    4168 
    4169 int VBoxGLWidget::vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version)
    4170 {
    4171     Q_UNUSED(u32Version);
    4172 
    4173     VBOXQGL_LOAD_SURFSTART(pSSM);
    4174 
    4175     char *buf = (char*)malloc(VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE));
    4176     memset(buf, 0, sizeof(buf));
    4177     VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
    4178     pCmd->enmCmd = VBOXVHWACMD_TYPE_SURF_CREATE;
    4179     pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
    4180 
    4181     VBOXVHWACMD_SURF_CREATE * pCreateSurf = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
    4182     int rc;
    4183     uint32_t u32;
    4184     rc = SSMR3GetU32(pSSM, &u32);         AssertRC(rc);
    4185     pCreateSurf->SurfInfo.hSurf = (VBOXVHWA_SURFHANDLE)u32;
    4186     if(RT_SUCCESS(rc))
    4187     {
    4188         rc = SSMR3GetU64(pSSM, &pCreateSurf->SurfInfo.offSurface);         AssertRC(rc);
    4189         rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.width);         AssertRC(rc);
    4190         rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.height);         AssertRC(rc);
    4191         rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.surfCaps);         AssertRC(rc);
    4192         rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.flags);         AssertRC(rc);
    4193         if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKDESTBLT)
    4194         {
    4195             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstBltCK.low);         AssertRC(rc);
    4196             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstBltCK.high);         AssertRC(rc);
    4197         }
    4198         if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKSRCBLT)
    4199         {
    4200             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcBltCK.low);         AssertRC(rc);
    4201             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcBltCK.high);         AssertRC(rc);
    4202         }
    4203         if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKDESTOVERLAY)
    4204         {
    4205             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstOverlayCK.low);         AssertRC(rc);
    4206             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstOverlayCK.high);         AssertRC(rc);
    4207         }
    4208         if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKSRCOVERLAY)
    4209         {
    4210             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcOverlayCK.low);         AssertRC(rc);
    4211             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcOverlayCK.high);         AssertRC(rc);
    4212         }
    4213 
    4214         rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.flags);         AssertRC(rc);
    4215         if(pCreateSurf->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
    4216         {
    4217             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.c.rgbBitCount);         AssertRC(rc);
    4218             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m1.rgbRBitMask);         AssertRC(rc);
    4219             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m2.rgbGBitMask);         AssertRC(rc);
    4220             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m3.rgbBBitMask);         AssertRC(rc);
    4221             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m4.rgbABitMask);         AssertRC(rc);
    4222         }
    4223         else if(pCreateSurf->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
    4224         {
    4225             rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.fourCC);         AssertRC(rc);
    4226         }
    4227         else
    4228         {
    4229             Assert(0);
    4230         }
    4231 
    4232         pCmdList->push_back(pCmd);
    4233 //        vboxExecOnResize(&VBoxGLWidget::vboxDoVHWACmdAndFree, pCmd); AssertRC(rc);
    4234 //        if(RT_SUCCESS(rc))
    4235 //        {
    4236 //            rc = pCmd->rc;
    4237 //            AssertRC(rc);
    4238 //        }
    4239     }
    4240 
    4241     VBOXQGL_LOAD_SURFSTOP(pSSM);
    4242 
    4243     return rc;
    4244 }
    4245 
    4246 int VBoxGLWidget::vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible)
    4247 {
    4248     VBOXQGL_SAVE_OVERLAYSTART(pSSM);
    4249 
    4250     uint32_t flags = 0;
    4251     const VBoxVHWAColorKey * dstCKey = pSurf->dstOverlayCKey();
    4252     const VBoxVHWAColorKey * defaultDstCKey = pSurf->defaultDstOverlayCKey();
    4253     const VBoxVHWAColorKey * srcCKey = pSurf->srcOverlayCKey();;
    4254     const VBoxVHWAColorKey * defaultSrcCKey = pSurf->defaultSrcOverlayCKey();
    4255     bool bSaveDstCKey = false;
    4256     bool bSaveSrcCKey = false;
    4257 
    4258     if(bVisible)
    4259     {
    4260         flags |= VBOXVHWA_OVER_SHOW;
    4261     }
    4262     else
    4263     {
    4264         flags |= VBOXVHWA_OVER_HIDE;
    4265     }
    4266 
    4267     if(!dstCKey)
    4268     {
    4269         flags |= VBOXVHWA_OVER_KEYDEST;
    4270     }
    4271     else if(defaultDstCKey)
    4272     {
    4273         flags |= VBOXVHWA_OVER_KEYDESTOVERRIDE;
    4274         bSaveDstCKey = true;
    4275     }
    4276 
    4277     if(srcCKey == defaultSrcCKey)
    4278     {
    4279         flags |= VBOXVHWA_OVER_KEYSRC;
    4280     }
    4281     else if(srcCKey)
    4282     {
    4283         flags |= VBOXVHWA_OVER_KEYSRCOVERRIDE;
    4284         bSaveSrcCKey = true;
    4285     }
    4286 
    4287     int rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
    4288 
    4289     rc = SSMR3PutU32(pSSM, mDisplay.getPrimary()->handle()); AssertRC(rc);
    4290     rc = SSMR3PutU32(pSSM, pSurf->handle()); AssertRC(rc);
    4291 
    4292     if(bSaveDstCKey)
    4293     {
    4294         rc = SSMR3PutU32(pSSM, dstCKey->lower()); AssertRC(rc);
    4295         rc = SSMR3PutU32(pSSM, dstCKey->upper()); AssertRC(rc);
    4296     }
    4297     if(bSaveSrcCKey)
    4298     {
    4299         rc = SSMR3PutU32(pSSM, srcCKey->lower()); AssertRC(rc);
    4300         rc = SSMR3PutU32(pSSM, srcCKey->upper()); AssertRC(rc);
    4301     }
    4302 
    4303     int x1, x2, y1, y2;
    4304     pSurf->targRect().getCoords(&x1, &y1, &x2, &y2);
    4305     rc = SSMR3PutS32(pSSM, x1); AssertRC(rc);
    4306     rc = SSMR3PutS32(pSSM, x2+1); AssertRC(rc);
    4307     rc = SSMR3PutS32(pSSM, y1); AssertRC(rc);
    4308     rc = SSMR3PutS32(pSSM, y2+1); AssertRC(rc);
    4309 
    4310     pSurf->srcRect().getCoords(&x1, &y1, &x2, &y2);
    4311     rc = SSMR3PutS32(pSSM, x1); AssertRC(rc);
    4312     rc = SSMR3PutS32(pSSM, x2+1); AssertRC(rc);
    4313     rc = SSMR3PutS32(pSSM, y1); AssertRC(rc);
    4314     rc = SSMR3PutS32(pSSM, y2+1); AssertRC(rc);
    4315 
    4316     VBOXQGL_SAVE_OVERLAYSTOP(pSSM);
    4317 
    4318     return rc;
    4319 }
    4320 
    4321 int VBoxGLWidget::vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version)
    4322 {
    4323     Q_UNUSED(u32Version);
    4324 
    4325     VBOXQGL_LOAD_OVERLAYSTART(pSSM);
    4326 
    4327 //    char buf[VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_OVERLAY_UPDATE)];
    4328     char *buf = new char[VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE)];
    4329     memset(buf, 0, sizeof(buf));
    4330     VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
    4331     pCmd->enmCmd = VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE;
    4332     pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
    4333 
    4334     VBOXVHWACMD_SURF_OVERLAY_UPDATE * pUpdateOverlay = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
    4335     int rc;
    4336 
    4337     rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.flags); AssertRC(rc);
    4338     uint32_t hSrc, hDst;
    4339     rc = SSMR3GetU32(pSSM, &hDst); AssertRC(rc);
    4340     rc = SSMR3GetU32(pSSM, &hSrc); AssertRC(rc);
    4341     pUpdateOverlay->u.in.hSrcSurf = hSrc;
    4342     pUpdateOverlay->u.in.hDstSurf = hDst;
    4343 //    Assert(hDst == mDisplay.getVGA()->handle());
    4344 //    VBoxVHWASurfaceBase *pDstSurf = handle2Surface(hDst);
    4345 //    VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(hSrc);
    4346 //    Assert(pSrcSurf);
    4347 //    Assert(pDstSurf);
    4348 //    if(pSrcSurf && pDstSurf)
    4349     {
    4350         pUpdateOverlay->u.in.offDstSurface = VBOXVHWA_OFFSET64_VOID;
    4351 //        vboxVRAMOffset(pDstSurf);
    4352         pUpdateOverlay->u.in.offSrcSurface = VBOXVHWA_OFFSET64_VOID;
    4353 //        vboxVRAMOffset(pSrcSurf);
    4354 
    4355         if(pUpdateOverlay->u.in.flags & VBOXVHWA_OVER_KEYDESTOVERRIDE)
    4356         {
    4357             rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.DstCK.low); AssertRC(rc);
    4358             rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.DstCK.high); AssertRC(rc);
    4359         }
    4360 
    4361         if(pUpdateOverlay->u.in.flags & VBOXVHWA_OVER_KEYSRCOVERRIDE)
    4362         {
    4363             rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.SrcCK.low); AssertRC(rc);
    4364             rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.SrcCK.high); AssertRC(rc);
    4365         }
    4366 
    4367         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.left); AssertRC(rc);
    4368         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.right); AssertRC(rc);
    4369         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.top); AssertRC(rc);
    4370         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.bottom); AssertRC(rc);
    4371 
    4372         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.left); AssertRC(rc);
    4373         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.right); AssertRC(rc);
    4374         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.top); AssertRC(rc);
    4375         rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.bottom); AssertRC(rc);
    4376 
    4377         pCmdList->push_back(pCmd);
    4378 //        vboxExecOnResize(&VBoxGLWidget::vboxDoVHWACmdAndFree, pCmd); AssertRC(rc);
    4379 //        if(RT_SUCCESS(rc))
    4380 //        {
    4381 //            rc = pCmd->rc;
    4382 //            AssertRC(rc);
    4383 //        }
    4384     }
    4385 //    else
    4386 //    {
    4387 //        rc = VERR_GENERAL_FAILURE;
    4388 //    }
    4389 
    4390     VBOXQGL_LOAD_OVERLAYSTOP(pSSM);
    4391 
    4392     return rc;
    4393 }
    4394 
    4395 void VBoxGLWidget::vhwaSaveExec(struct SSMHANDLE * pSSM)
    4396 {
    4397     VBOXQGL_SAVE_START(pSSM);
    4398 
    4399     /* the mechanism of restoring data is based on generating VHWA commands that restore the surfaces state
    4400      * the following commands are generated:
    4401      * I.    CreateSurface
    4402      * II.   UpdateOverlay
    4403      *
    4404      * Data format is the following:
    4405      * I.    u32 - Num primary surfaces - (the current frontbuffer is detected in the stored surf flags which are posted to the generated CreateSurface cmd)
    4406      * II.   for each primary surf
    4407      * II.1    generate & execute CreateSurface cmd (see below on the generation logic)
    4408      * III.  u32 - Num overlays
    4409      * IV.   for each overlay
    4410      * IV.1    u32 - Num surfaces in overlay (the current frontbuffer is detected in the stored surf flags which are posted to the generated CreateSurface cmd)
    4411      * IV.2    for each surface in overlay
    4412      * IV.2.a    generate & execute CreateSurface cmd (see below on the generation logic)
    4413      * IV.2.b    generate & execute UpdateOverlay cmd (see below on the generation logic)
    4414      *
    4415      */
    4416     const SurfList & primaryList = mDisplay.primaries().surfaces();
    4417     uint32_t cPrimary = (uint32_t)primaryList.size();
    4418     Assert(cPrimary >= 1);
    4419     if(mDisplay.getVGA() == NULL || mDisplay.getVGA()->handle() == VBOXVHWA_SURFHANDLE_INVALID)
    4420     {
    4421         cPrimary -= 1;
    4422     }
    4423     int rc = SSMR3PutU32(pSSM, cPrimary);         AssertRC(rc);
    4424 
    4425     for (SurfList::const_iterator pr = primaryList.begin();
    4426          pr != primaryList.end(); ++ pr)
    4427     {
    4428         VBoxVHWASurfaceBase *pSurf = *pr;
    4429 //        bool bVga = (pSurf == mDisplay.getVGA());
    4430         bool bVisible = (pSurf == mDisplay.getPrimary());
    4431         uint32_t flags = VBOXVHWA_SCAPS_PRIMARYSURFACE;
    4432         if(bVisible)
    4433             flags |= VBOXVHWA_SCAPS_VISIBLE;
    4434 
    4435         if(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID)
    4436         {
    4437             rc = vhwaSaveSurface(pSSM, *pr, flags);    AssertRC(rc);
    4438 #ifdef DEBUG
    4439             --cPrimary;
    4440             Assert(cPrimary < UINT32_MAX / 2);
    4441 #endif
    4442         }
    4443         else
    4444         {
    4445             Assert(pSurf == mDisplay.getVGA());
    4446         }
    4447     }
    4448 
    4449 #ifdef DEBUG
    4450     Assert(!cPrimary);
    4451 #endif
    4452 
    4453     const OverlayList & overlays = mDisplay.overlays();
    4454     rc = SSMR3PutU32(pSSM, (uint32_t)overlays.size());         AssertRC(rc);
    4455 
    4456     for (OverlayList::const_iterator it = overlays.begin();
    4457          it != overlays.end(); ++ it)
    4458     {
    4459         VBoxVHWASurfList * pSurfList = *it;
    4460         const SurfList & surfaces = pSurfList->surfaces();
    4461         uint32_t cSurfs = (uint32_t)surfaces.size();
    4462         uint32_t flags = VBOXVHWA_SCAPS_OVERLAY;
    4463         if(cSurfs > 1)
    4464             flags |= VBOXVHWA_SCAPS_COMPLEX;
    4465         rc = SSMR3PutU32(pSSM, cSurfs);         AssertRC(rc);
    4466         for (SurfList::const_iterator sit = surfaces.begin();
    4467              sit != surfaces.end(); ++ sit)
    4468         {
    4469             rc = vhwaSaveSurface(pSSM, *sit, flags);    AssertRC(rc);
    4470         }
    4471 
    4472         bool bVisible = true;
    4473         VBoxVHWASurfaceBase * pOverlayData = pSurfList->current();
    4474         if(!pOverlayData)
    4475         {
    4476             pOverlayData = surfaces.front();
    4477             bVisible = false;
    4478         }
    4479 
    4480         rc = vhwaSaveOverlayData(pSSM, pOverlayData, bVisible);    AssertRC(rc);
    4481     }
    4482 
    4483     VBOXQGL_SAVE_STOP(pSSM);
    4484 }
    4485 
    4486 int VBoxGLWidget::vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version)
    4487 {
    4488     VBOXQGL_LOAD_START(pSSM);
    4489 
    4490     int rc;
    4491     uint32_t u32;
    4492 
    4493     if(pCmdList == NULL)
    4494     {
    4495         /* use our own list */
    4496         pCmdList = &mOnResizeCmdList;
    4497     }
    4498 
    4499     rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
    4500     if(RT_SUCCESS(rc))
    4501     {
    4502         for(uint32_t i = 0; i < u32; ++i)
    4503         {
    4504             rc = vhwaLoadSurface(pCmdList, pSSM, u32Version);  AssertRC(rc);
    4505             if(RT_FAILURE(rc))
    4506                 break;
    4507         }
    4508 
    4509         if(RT_SUCCESS(rc))
    4510         {
    4511             rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
    4512             if(RT_SUCCESS(rc))
    4513             {
    4514                 for(uint32_t i = 0; i < u32; ++i)
    4515                 {
    4516                     uint32_t cSurfs;
    4517                     rc = SSMR3GetU32(pSSM, &cSurfs); AssertRC(rc);
    4518                     for(uint32_t j = 0; j < cSurfs; ++j)
    4519                     {
    4520                         rc = vhwaLoadSurface(pCmdList, pSSM, u32Version);  AssertRC(rc);
    4521                         if(RT_FAILURE(rc))
    4522                             break;
    4523                     }
    4524 
    4525                     if(RT_SUCCESS(rc))
    4526                     {
    4527                         rc = vhwaLoadOverlayData(pCmdList, pSSM, u32Version);  AssertRC(rc);
    4528                     }
    4529 
    4530                     if(RT_FAILURE(rc))
    4531                     {
    4532                         break;
    4533                     }
    4534                 }
    4535             }
    4536         }
    4537     }
    4538 
    4539     VBOXQGL_LOAD_STOP(pSSM);
    4540 
    4541     return rc;
    4542 }
    4543 
    4544 int VBoxGLWidget::vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd)
    4545 {
    4546     PVM pVM = (PVM)pCmd->pVM;
    4547     uint32_t intsId = 0; /* @todo: set the proper id */
    4548 
    4549     char nameFuf[sizeof(VBOXQGL_STATE_NAMEBASE) + 8];
    4550 
    4551     char * pszName = nameFuf;
    4552     sprintf(pszName, "%s%d", VBOXQGL_STATE_NAMEBASE, intsId);
    4553     int rc = SSMR3RegisterExternal(
    4554             pVM,                    /* The VM handle*/
    4555             pszName,                /* Data unit name. */
    4556             intsId,                 /* The instance identifier of the data unit.
    4557                                      * This must together with the name be unique. */
    4558             VBOXQGL_STATE_VERSION,   /* Data layout version number. */
    4559             128,             /* The approximate amount of data in the unit.
    4560                               * Only for progress indicators. */
    4561             NULL, NULL, NULL, /* pfnLiveXxx */
    4562             NULL,            /* Prepare save callback, optional. */
    4563             vboxQGLSaveExec, /* Execute save callback, optional. */
    4564             NULL,            /* Done save callback, optional. */
    4565             NULL,            /* Prepare load callback, optional. */
    4566             vboxQGLLoadExec, /* Execute load callback, optional. */
    4567             NULL,            /* Done load callback, optional. */
    4568             this             /* User argument. */
    4569             );
    4570     Assert(RT_SUCCESS(rc));
    4571     return rc;
    4572 }
    4573 
    4574 uchar * VBoxGLWidget::vboxVRAMAddressFromOffset(uint64_t offset)
    4575 {
    4576     return ((offset != VBOXVHWA_OFFSET64_VOID) && vboxUsesGuestVRAM()) ? vboxAddress() + offset : NULL;
    4577 }
    4578 
    4579 uint64_t VBoxGLWidget::vboxVRAMOffsetFromAddress(uchar* addr)
    4580 {
    4581     return uint64_t(addr - vboxAddress());
    4582 }
    4583 
    4584 uint64_t VBoxGLWidget::vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf)
    4585 {
    4586     return pSurf->addressAlocated() ? VBOXVHWA_OFFSET64_VOID : vboxVRAMOffsetFromAddress(pSurf->address());
    4587 }
    4588 
    4589 #endif
    4590 
    4591 void VBoxGLWidget::initializeGL()
    4592 {
    4593     vboxVHWAGlInit(context());
    4594     VBoxVHWASurfaceBase::globalInit();
    4595 }
    4596 
    4597 #ifdef VBOXQGL_DBG_SURF
    4598 
    4599 int g_iCur = 0;
    4600 VBoxVHWASurfaceBase * g_apSurf[] = {NULL, NULL, NULL};
    4601 
    4602 void VBoxGLWidget::vboxDoTestSurfaces(void* context)
    4603 {
    4604 //    uint32_t width = 103;
    4605 //    uint32_t height = 47;
    4606 //    uint32_t rgbBitCount = 32;
    4607 //    uint32_t r = 0xff, g = 0xff00, b = 0xff0000;
    4608 //    QRect dstRect(10, 50, width, height);
    4609 //    QRect srcRect(0, 0, width, height);
    4610 ////    Assert(0);
    4611 //    if(!pSurf1)
    4612 //    {
    4613 //
    4614 ////        pSurf1 = new VBoxVHWASurfaceBase(this, width, height,
    4615 ////                        VBoxVHWAColorFormat(rgbBitCount,
    4616 ////                                r,
    4617 ////                                g,
    4618 ////                                b),
    4619 ////                        NULL, NULL, NULL, NULL);
    4620 //        pSurf1 = new VBoxVHWASurfaceBase(this, &QSize(width, height),
    4621 ////                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
    4622 //                        &mDisplay.getPrimary()->rect().size(),
    4623 //                        VBoxVHWAColorFormat(rgbBitCount,
    4624 //                                r,
    4625 //                                g,
    4626 //                                b),
    4627 ////                        pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey);
    4628 //                        NULL, NULL, NULL, NULL);
    4629 //
    4630 //        pSurf1->init(mDisplay.getVGA(), NULL);
    4631 //
    4632 //        VBoxVHWASurfList *pConstructingList = new VBoxVHWASurfList();
    4633 //        mDisplay.addOverlay(pConstructingList);
    4634 //        pConstructingList->add(pSurf1);
    4635 //        pConstructingList->setCurrentVisible(pSurf1);
    4636 ////        pSurf1->performDisplay();
    4637 //    }
    4638 //
    4639 ////    pDisplay->blt(&dstRect, pSurf1, &srcRect, NULL, NULL);
    4640 ////    pDisplay->performDisplay();
    4641     if(g_iCur >= RT_ELEMENTS(g_apSurf))
    4642         g_iCur = 0;
    4643     VBoxVHWASurfaceBase * pSurf1 = g_apSurf[g_iCur];
    4644     if(pSurf1)
    4645     {
    4646         pSurf1->getComplexList()->setCurrentVisible(pSurf1);
    4647     }
    4648 }
    4649 #endif
    4650 
    4651 void VBoxGLWidget::vboxDoUpdateViewport(const QRect & aRect)
    4652 {
    4653     adjustViewport(mDisplay.getPrimary()->size(), aRect);
    4654     mViewport = aRect;
    4655 
    4656     const SurfList & primaryList = mDisplay.primaries().surfaces();
    4657 
    4658     for (SurfList::const_iterator pr = primaryList.begin();
    4659          pr != primaryList.end(); ++ pr)
    4660     {
    4661         VBoxVHWASurfaceBase *pSurf = *pr;
    4662         pSurf->updateVisibleTargRect(NULL, aRect);
    4663     }
    4664 
    4665     const OverlayList & overlays = mDisplay.overlays();
    4666 
    4667     for (OverlayList::const_iterator it = overlays.begin();
    4668          it != overlays.end(); ++ it)
    4669     {
    4670         VBoxVHWASurfList * pSurfList = *it;
    4671         const SurfList & surfaces = pSurfList->surfaces();
    4672         for (SurfList::const_iterator sit = surfaces.begin();
    4673              sit != surfaces.end(); ++ sit)
    4674         {
    4675             VBoxVHWASurfaceBase *pSurf = *sit;
    4676             pSurf->updateVisibleTargRect(mDisplay.getPrimary(), aRect);
    4677         }
    4678     }
    4679 }
    4680 
    4681 bool VBoxGLWidget::hasSurfaces() const
    4682 {
    4683     if(mDisplay.overlays().size() != 0)
    4684         return true;
    4685     if(mDisplay.primaries().size() > 1)
    4686         return true;
    4687     return mDisplay.getVGA()->handle() != VBOXVHWA_SURFHANDLE_INVALID;
    4688 }
    4689 
    4690 bool VBoxGLWidget::hasVisibleOverlays()
    4691 {
    4692     const OverlayList & overlays = mDisplay.overlays();
    4693     for (OverlayList::const_iterator it = overlays.begin();
    4694          it != overlays.end(); ++ it)
    4695     {
    4696         VBoxVHWASurfList * pSurfList = *it;
    4697         if(pSurfList->current() != NULL)
    4698             return true;
    4699     }
    4700     return false;
    4701 }
    4702 
    4703 const QRect & VBoxGLWidget::overlaysRectUnion()
    4704 {
    4705     const OverlayList & overlays = mDisplay.overlays();
    4706     VBoxVHWADirtyRect un;
    4707     for (OverlayList::const_iterator it = overlays.begin();
    4708          it != overlays.end(); ++ it)
    4709     {
    4710         VBoxVHWASurfaceBase * pOverlay = (*it)->current();
    4711         if(pOverlay != NULL)
    4712         {
    4713             un.add(pOverlay->targRect());
    4714         }
    4715     }
    4716     return un.toRect();
    4717 }
    4718 
    4719 //void VBoxGLWidget::vboxDoPaint(void *pe)
    4720 //{
    4721 //    Q_UNUSED(pe);
    4722 //
    4723 //#ifdef VBOXQGL_DBG_SURF
    4724 //    vboxDoTestSurfaces(NULL);
    4725 //#endif
    4726 ////#ifdef VBOXQGL_PROF_BASE
    4727 ////    vboxDoUpdateRect(&((QPaintEvent*)pe)->rect());
    4728 ////#endif
    4729 ////    mDisplay.performDisplay();
    4730 //}
    4731 
    4732 void VBoxGLWidget::vboxDoUpdateRect(const QRect * pRect)
    4733 {
    4734     mDisplay.getPrimary()->updatedMem(pRect);
    4735 }
    4736 
    4737 void VBoxGLWidget::vboxDoResize(void *resize)
    4738 {
    4739 //    Assert(!format().accum());
    4740 //    Assert(format().alpha());
    4741 //    Assert(format().alphaBufferSize() == 8);
    4742     Assert(format().blueBufferSize() == 8);
    4743     Assert(format().greenBufferSize() == 8);
    4744     Assert(format().redBufferSize() == 8);
    4745 
    4746 //    Assert(!format().depth());
    4747     Assert(format().directRendering());
    4748     Assert(format().doubleBuffer());
    4749     Assert(format().hasOpenGL());
    4750     VBOXQGLLOG(("hasOpenGLOverlays(%d), hasOverlay(%d)\n", format().hasOpenGLOverlays(), format().hasOverlay()));
    4751 //    Assert(format().hasOpenGLOverlays());
    4752 //    Assert(format().hasOverlay());
    4753     Assert(format().plane() == 0);
    4754     Assert(format().rgba());
    4755     Assert(!format().sampleBuffers());
    4756 //    Assert(!format().stencil());
    4757     Assert(!format().stereo());
    4758     VBOXQGLLOG(("swapInterval(%d)\n", format().swapInterval()));
    4759 //    Assert(format().swapInterval() == 0);
    4760 
    4761 
    4762     VBOXQGL_CHECKERR(
    4763             vboxglActiveTexture(GL_TEXTURE0);
    4764         );
    4765 
    4766     VBoxResizeEvent *re = (VBoxResizeEvent*)resize;
    4767     bool remind = false;
    4768     bool fallback = false;
    4769 
    4770     VBOXQGLLOG(("resizing: fmt=%d, vram=%p, bpp=%d, bpl=%d, width=%d, height=%d\n",
    4771                       re->pixelFormat(), re->VRAM(),
    4772                       re->bitsPerPixel(), re->bytesPerLine(),
    4773                       re->width(), re->height()));
    4774 
    4775     /* clean the old values first */
    4776 
    4777     ulong bytesPerLine;
    4778     uint32_t bitsPerPixel;
    4779     uint32_t b = 0xff, g = 0xff00, r = 0xff0000;
    4780 
    4781     /* check if we support the pixel format and can use the guest VRAM directly */
    4782     if (re->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
    4783     {
    4784 
    4785         bitsPerPixel = re->bitsPerPixel();
    4786         bytesPerLine = re->bytesPerLine();
    4787         ulong bitsPerLine = bytesPerLine * 8;
    4788 
    4789         switch (bitsPerPixel)
    4790         {
    4791             case 32:
    4792 //                format = VBoxVHWAColorFormat(bitsPerPixel, 0xff, 0xff00, 0xff0000);
    4793                 break;
    4794             case 24:
    4795 #ifdef DEBUG_misha
    4796                 Assert(0);
    4797 #endif
    4798 //                format = VBoxVHWAColorFormat(bitsPerPixel, 0xff, 0xff00, 0xff0000);
    4799 //                remind = true;
    4800                 break;
    4801 //            case 16:
    4802 //                Assert(0);
    4803 ////                r = 0xf800;
    4804 ////                g = 0x7e0;
    4805 ////                b = 0x1f;
    4806 //                break;
    4807             case 8:
    4808 #ifdef DEBUG_misha
    4809                 Assert(0);
    4810 #endif
    4811                 g = b = 0;
    4812                 remind = true;
    4813                 break;
    4814             case 1:
    4815 #ifdef DEBUG_misha
    4816                 Assert(0);
    4817 #endif
    4818                 r = 1;
    4819                 g = b = 0;
    4820                 remind = true;
    4821                 break;
    4822             default:
    4823 #ifdef DEBUG_misha
    4824                 Assert(0);
    4825 #endif
    4826                 remind = true;
    4827                 fallback = true;
    4828                 break;
    4829         }
    4830 
    4831         if (!fallback)
    4832         {
    4833             /* QImage only supports 32-bit aligned scan lines... */
    4834             Assert ((re->bytesPerLine() & 3) == 0);
    4835             fallback = ((re->bytesPerLine() & 3) != 0);
    4836         }
    4837         if (!fallback)
    4838         {
    4839             /* ...and the scan lines ought to be a whole number of pixels. */
    4840             Assert ((bitsPerLine & (re->bitsPerPixel() - 1)) == 0);
    4841             fallback = ((bitsPerLine & (re->bitsPerPixel() - 1)) != 0);
    4842         }
    4843         if (!fallback)
    4844         {
    4845             // ulong virtWdt = bitsPerLine / re->bitsPerPixel();
    4846             mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
    4847             mUsesGuestVRAM = true;
    4848         }
    4849     }
    4850     else
    4851     {
    4852         fallback = true;
    4853     }
    4854 
    4855     if (fallback)
    4856     {
    4857         /* we don't support either the pixel format or the color depth,
    4858          * fallback to a self-provided 32bpp RGB buffer */
    4859         bitsPerPixel = 32;
    4860         b = 0xff;
    4861         g = 0xff00;
    4862         r = 0xff0000;
    4863         bytesPerLine = re->width()*bitsPerPixel/8;
    4864         mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
    4865 //        internalformat = 3;//GL_RGB;
    4866 //        format = GL_BGRA_EXT;//GL_RGBA;
    4867 //        type = GL_UNSIGNED_BYTE;
    4868         mUsesGuestVRAM = false;
    4869     }
    4870 
    4871     ulong bytesPerPixel = bitsPerPixel/8;
    4872     ulong displayWidth = bytesPerLine/bytesPerPixel;
    4873     ulong displayHeight = re->height();
    4874 
    4875 #ifdef VBOXQGL_DBG_SURF
    4876     for(int i = 0; i < RT_ELEMENTS(g_apSurf); i++)
    4877     {
    4878         VBoxVHWASurfaceBase * pSurf1 = g_apSurf[i];
    4879         if(pSurf1)
    4880         {
    4881             VBoxVHWASurfList *pConstructingList = pSurf1->getComplexList();
    4882             delete pSurf1;
    4883             if(pConstructingList)
    4884                 delete pConstructingList;
    4885     //
    4886     //            mDisplay.addOverlay(pConstructingList);
    4887     //            //            pConstructingList->add(pSurf1);
    4888     //            //            pConstructingList->setCurrentVisible(pSurf1);
    4889     //            ////            pConstructingList->setCurrentVisible(NULL);
    4890         }
    4891     }
    4892 #endif
    4893 
    4894     VBoxVHWASurfaceBase * pDisplay = mDisplay.setVGA(NULL);
    4895     if(pDisplay)
    4896         delete pDisplay;
    4897 
    4898     VBoxVHWAColorFormat format(bitsPerPixel, r,g,b);
    4899     QSize dispSize(displayWidth, displayHeight);
    4900     QRect dispRect(0, 0, displayWidth, displayHeight);
    4901     pDisplay = new VBoxVHWASurfaceBase(this,
    4902             dispSize,
    4903             dispRect,
    4904             dispRect,
    4905             dispRect, /* we do not know viewport at the stage of recise, set as a disp rect, it will be updated on repaint */
    4906                 format,
    4907             (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, true);
    4908     pDisplay->init(NULL, mUsesGuestVRAM ? re->VRAM() : NULL);
    4909     mDisplay.setVGA(pDisplay);
    4910 //    VBOXQGLLOG(("\n\n*******\n\n     viewport size is: (%d):(%d)\n\n*******\n\n", size().width(), size().height()));
    4911     mViewport = QRect(0,0,displayWidth, displayHeight);
    4912     adjustViewport(dispSize, mViewport);
    4913     setupMatricies(dispSize);
    4914 
    4915 #ifdef VBOXQGL_DBG_SURF
    4916     {
    4917         uint32_t width = 100;
    4918         uint32_t height = 60;
    4919 //        uint32_t rgbBitCount = 32;
    4920 //        uint32_t r = 0xff, g = 0xff00, b = 0xff0000;
    4921 //        QRect dstRect(150, 200, width, height);
    4922 //        QRect srcRect(0, 0, 720, 480);
    4923     //    Assert(0);
    4924 
    4925         for(int i = 0; i < RT_ELEMENTS(g_apSurf); i++)
    4926         {
    4927 
    4928     //        pSurf1 = new VBoxVHWASurfaceBase(this, width, height,
    4929     //                        VBoxVHWAColorFormat(rgbBitCount,
    4930     //                                r,
    4931     //                                g,
    4932     //                                b),
    4933     //                        NULL, NULL, NULL, NULL);
    4934             VBoxVHWASurfaceBase *pSurf1 = new VBoxVHWASurfaceBase(this, &QSize(width, height),
    4935     //                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
    4936                             &mDisplay.getPrimary()->rect().size(),
    4937 //                            VBoxVHWAColorFormat(rgbBitCount,
    4938 //                                    r,
    4939 //                                    g,
    4940 //                                    b),
    4941                             VBoxVHWAColorFormat(FOURCC_YV12),
    4942     //                        pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey);
    4943                             NULL, NULL, NULL, &VBoxVHWAColorKey(0,0), false);
    4944 
    4945             Assert(mDisplay.getVGA());
    4946             pSurf1->init(mDisplay.getVGA(), NULL);
    4947             uchar *addr = pSurf1->address();
    4948             uchar cur = 0;
    4949             for(uint32_t k = 0; k < width*height; k++)
    4950             {
    4951                 addr[k] = cur;
    4952                 cur+=64;
    4953             }
    4954             pSurf1->updatedMem(&QRect(0,0,width, height));
    4955 //            VBOXQGL_CHECKERR(
    4956 //                    vboxglActiveTexture(GL_TEXTURE0);
    4957 //                );
    4958 
    4959             VBoxVHWASurfList *pConstructingList = new VBoxVHWASurfList();
    4960             mDisplay.addOverlay(pConstructingList);
    4961             pConstructingList->add(pSurf1);
    4962 //            pConstructingList->setCurrentVisible(pSurf1);
    4963 //            pConstructingList->setCurrentVisible(NULL);
    4964             g_apSurf[i] = pSurf1;
    4965 
    4966 //            VBoxVHWAGlProgramVHWA * pProgram = vboxVHWAGetGlProgramMngr()->getProgram(true, false, &pSurf1->colorFormat(), &pDisplay->colorFormat());
    4967 //            pProgram->start();
    4968 //            pProgram->setSrcTexImgWidth(pSurf1->texRect().width());
    4969 //            pProgram->stop();
    4970         }
    4971 //        else
    4972 //        {
    4973 //            VBoxVHWASurfList *pConstructingList = pSurf1->getComplexList();
    4974 //            mDisplay.addOverlay(pConstructingList);
    4975 //            pConstructingList->add(pSurf1);
    4976 //            pConstructingList->setCurrentVisible(pSurf1);
    4977 ////            pConstructingList->setCurrentVisible(NULL);
    4978 //        }
    4979 
    4980         VBOXVHWACMD_SURF_OVERLAY_UPDATE updateCmd;
    4981         memset(&updateCmd, 0, sizeof(updateCmd));
    4982         updateCmd.u.in.hSrcSurf = (VBOXVHWA_SURFHANDLE)g_apSurf[0];
    4983         updateCmd.u.in.hDstSurf = (VBOXVHWA_SURFHANDLE)pDisplay;
    4984         updateCmd.u.in.flags =
    4985                         VBOXVHWA_OVER_SHOW
    4986                         | VBOXVHWA_OVER_KEYDESTOVERRIDE;
    4987 
    4988         updateCmd.u.in.desc.DstCK.high = 1;
    4989         updateCmd.u.in.desc.DstCK.low = 1;
    4990 
    4991         updateCmd.u.in.dstRect.left = 0;
    4992         updateCmd.u.in.dstRect.right = pDisplay->width();
    4993         updateCmd.u.in.dstRect.top = (pDisplay->height() - height)/2;
    4994         updateCmd.u.in.dstRect.bottom = updateCmd.u.in.dstRect.top + height;
    4995 
    4996         updateCmd.u.in.srcRect.left = 0;
    4997         updateCmd.u.in.srcRect.right = width;
    4998         updateCmd.u.in.srcRect.top = 0;
    4999         updateCmd.u.in.srcRect.bottom = height;
    5000 
    5001         updateCmd.u.in.offDstSurface = 0xffffffffffffffffL; /* just a magic to avoid surf mem buffer change  */
    5002         updateCmd.u.in.offSrcSurface = 0xffffffffffffffffL; /* just a magic to avoid surf mem buffer change  */
    5003 
    5004         vhwaSurfaceOverlayUpdate(&updateCmd);
    5005     }
    5006 #endif
    5007 
    5008     if(!mOnResizeCmdList.empty())
    5009     {
    5010         for (VHWACommandList::const_iterator it = mOnResizeCmdList.begin();
    5011              it != mOnResizeCmdList.end(); ++ it)
    5012         {
    5013             VBOXVHWACMD * pCmd = (*it);
    5014             vboxDoVHWACmdExec(pCmd);
    5015             free(pCmd);
    5016         }
    5017         mOnResizeCmdList.clear();
    5018     }
    5019 
    5020 
    5021 //    mDisplay.performDisplay();
    5022 
    5023     if (remind)
    5024     {
    5025         class RemindEvent : public VBoxAsyncEvent
    5026         {
    5027             ulong mRealBPP;
    5028         public:
    5029             RemindEvent (ulong aRealBPP)
    5030                 : mRealBPP (aRealBPP) {}
    5031             void handle()
    5032             {
    5033                 vboxProblem().remindAboutWrongColorDepth (mRealBPP, 32);
    5034             }
    5035         };
    5036         (new RemindEvent (re->bitsPerPixel()))->post();
    5037     }
    5038 }
    5039 
    5040 //typedef struct VBOXQGLDEFFEREDOPCONTEXT
    5041 //{
    5042 //    PFNVBOXQGLOP pfn;
    5043 //    void *pContext;
    5044 //    VBoxVHWACommandElement * pEl;
    5045 //}VBOXQGLDEFFEREDOPCONTEXT;
    5046 //
    5047 //void VBoxGLWidget::vboxDefferedOpCallback(void * pContext)
    5048 //{
    5049 //    VBOXQGLDEFFEREDOPCONTEXT * pData = (VBOXQGLDEFFEREDOPCONTEXT*)pContext;
    5050 //    this->*(pData->pfn)(pData->pContext);
    5051 //    delete pEl;
    5052 //}
    5053 
    5054 //int VBoxGLWidget::vboxExecOpSynch(PFNVBOXQGLOP pfn, void* pContext)
    5055 //{
    5056 //    VBOXQGLOPCALLBACKCONTEXT data;
    5057 //    data.pThis = this;
    5058 //    data.pfn = pfn;
    5059 //    data.pContext = pContext;
    5060 //    int rc = RTSemEventCreate(&data.hEvent);
    5061 //    AssertRC(rc);
    5062 //    if(RT_SUCCESS(rc))
    5063 //    {
    5064 //        VBOXVHWACALLBACKINFO info;
    5065 //        info.pContext = &data;
    5066 //        info.pfnCallback = vboxQGLOpCallback;
    5067 //        postCmd(VBOXVHWA_PIPECMD_OP, &info);
    5068 //        rc = RTSemEventWaitNoResume(data.hEvent, RT_INDEFINITE_WAIT);
    5069 //        AssertRC(rc);
    5070 //        if(RT_SUCCESS(rc))
    5071 //        {
    5072 //            RTSemEventDestroy(data.hEvent);
    5073 //        }
    5074 //    }
    5075 //    return rc;
    5076 //}
    5077 
    5078 VBoxVHWAColorFormat::VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b) :
    5079     mWidthCompression(1),
    5080     mHeightCompression(1)
    5081 {
    5082     init(bitsPerPixel, r, g, b);
    5083 }
    5084 
    5085 VBoxVHWAColorFormat::VBoxVHWAColorFormat(uint32_t fourcc) :
    5086     mWidthCompression(1),
    5087     mHeightCompression(1)
    5088 {
    5089     init(fourcc);
    5090 }
    5091 
    5092 void VBoxVHWAColorFormat::init(uint32_t fourcc)
    5093 {
    5094     mDataFormat = fourcc;
    5095     mInternalFormat = GL_RGBA8;//GL_RGB;
    5096     mFormat = GL_BGRA_EXT;//GL_RGBA;
    5097     mType = GL_UNSIGNED_BYTE;
    5098     mR = VBoxVHWAColorComponent(0xff);
    5099     mG = VBoxVHWAColorComponent(0xff);
    5100     mB = VBoxVHWAColorComponent(0xff);
    5101     mA = VBoxVHWAColorComponent(0xff);
    5102     mBitsPerPixelTex = 32;
    5103 
    5104     switch(fourcc)
    5105     {
    5106         case FOURCC_AYUV:
    5107             mBitsPerPixel = 32;
    5108             mWidthCompression = 1;
    5109             break;
    5110         case FOURCC_UYVY:
    5111         case FOURCC_YUY2:
    5112             mBitsPerPixel = 16;
    5113             mWidthCompression = 2;
    5114             break;
    5115         case FOURCC_YV12:
    5116             mBitsPerPixel = 8;
    5117             mWidthCompression = 4;
    5118             break;
    5119         default:
    5120             Assert(0);
    5121             mBitsPerPixel = 0;
    5122             mBitsPerPixelTex = 0;
    5123             mWidthCompression = 0;
    5124             break;
    5125     }
    5126 }
    5127 
    5128 void VBoxVHWAColorFormat::init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b)
    5129 {
    5130     mBitsPerPixel = bitsPerPixel;
    5131     mBitsPerPixelTex = bitsPerPixel;
    5132     mDataFormat = 0;
    5133     switch (bitsPerPixel)
    5134     {
    5135         case 32:
    5136             mInternalFormat = GL_RGB;//3;//GL_RGB;
    5137             mFormat = GL_BGRA_EXT;//GL_RGBA;
    5138             mType = GL_UNSIGNED_BYTE;
    5139             mR = VBoxVHWAColorComponent(r);
    5140             mG = VBoxVHWAColorComponent(g);
    5141             mB = VBoxVHWAColorComponent(b);
    5142             break;
    5143         case 24:
    5144 #ifdef DEBUG_misha
    5145             Assert(0);
    5146 #endif
    5147             mInternalFormat = 3;//GL_RGB;
    5148             mFormat = GL_BGR_EXT;
    5149             mType = GL_UNSIGNED_BYTE;
    5150             mR = VBoxVHWAColorComponent(r);
    5151             mG = VBoxVHWAColorComponent(g);
    5152             mB = VBoxVHWAColorComponent(b);
    5153             break;
    5154         case 16:
    5155 #ifdef DEBUG_misha
    5156             Assert(0);
    5157 #endif
    5158             mInternalFormat = GL_RGB5;
    5159             mFormat = GL_BGR_EXT;
    5160             mType = GL_UNSIGNED_BYTE; /* TODO" ??? */
    5161             mR = VBoxVHWAColorComponent(r);
    5162             mG = VBoxVHWAColorComponent(g);
    5163             mB = VBoxVHWAColorComponent(b);
    5164             break;
    5165         case 8:
    5166 #ifdef DEBUG_misha
    5167             Assert(0);
    5168 #endif
    5169             mInternalFormat = 1;//GL_RGB;
    5170             mFormat = GL_RED;//GL_RGB;
    5171             mType = GL_UNSIGNED_BYTE;
    5172             mR = VBoxVHWAColorComponent(0xff);
    5173             break;
    5174         case 1:
    5175 #ifdef DEBUG_misha
    5176             Assert(0);
    5177 #endif
    5178             mInternalFormat = 1;
    5179             mFormat = GL_COLOR_INDEX;
    5180             mType = GL_BITMAP;
    5181             mR = VBoxVHWAColorComponent(0x1);
    5182             break;
    5183         default:
    5184 #ifdef DEBUG_misha
    5185             Assert(0);
    5186 #endif
    5187             mBitsPerPixel = 0;
    5188             mBitsPerPixelTex = 0;
    5189             break;
    5190     }
    5191 }
    5192 
    5193 bool VBoxVHWAColorFormat::equals (const VBoxVHWAColorFormat & other) const
    5194 {
    5195     if(fourcc())
    5196         return fourcc() == other.fourcc();
    5197     if(other.fourcc())
    5198         return false;
    5199 
    5200     return bitsPerPixel() == other.bitsPerPixel();
    5201 }
    5202 
    5203 VBoxVHWAColorComponent::VBoxVHWAColorComponent(uint32_t aMask)
    5204 {
    5205     unsigned f = ASMBitFirstSetU32(aMask);
    5206     if(f)
    5207     {
    5208         mOffset = f - 1;
    5209         f = ASMBitFirstSetU32(~(aMask >> mOffset));
    5210         if(f)
    5211         {
    5212             mcBits = f - 1;
    5213         }
    5214         else
    5215         {
    5216             mcBits = 32 - mOffset;
    5217         }
    5218 
    5219         Assert(mcBits);
    5220         mMask = (((uint32_t)0xffffffff) >> (32 - mcBits)) << mOffset;
    5221         Assert(mMask == aMask);
    5222 
    5223         mRange = (mMask >> mOffset) + 1;
    5224     }
    5225     else
    5226     {
    5227         mMask = 0;
    5228         mRange = 0;
    5229         mOffset = 32;
    5230         mcBits = 0;
    5231     }
    5232 }
    5233 
    5234 void VBoxVHWAColorFormat::pixel2Normalized (uint32_t pix, float *r, float *g, float *b) const
    5235 {
    5236     *r = mR.colorValNorm(pix);
    5237     *g = mG.colorValNorm(pix);
    5238     *b = mB.colorValNorm(pix);
    5239 }
    5240 #ifdef VBOX_WITH_VIDEOHWACCEL
    5241 VBoxQGLOverlayFrameBuffer::VBoxQGLOverlayFrameBuffer (VBoxConsoleView *aView)
    5242     : VBoxQImageFrameBuffer(aView),
    5243       mGlOn(false),
    5244       mOverlayWidgetVisible(false),
    5245       mOverlayVisible(false),
    5246       mGlCurrent(false),
    5247       mProcessingCommands(false),
    5248       mCmdPipe(aView)
    5249 {
    5250     mpOverlayWidget = new VBoxGLWidget (aView, aView->viewport());
    5251     mOverlayWidgetVisible = true; /* to ensure it is set hidden with vboxShowOverlay */
    5252     vboxShowOverlay(false);
    5253 
    5254     resizeEvent (new VBoxResizeEvent (FramebufferPixelFormat_Opaque,
    5255                                       NULL, 0, 0, 640, 480));
    5256 }
    5257 
    5258 STDMETHODIMP VBoxQGLOverlayFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
    5259 {
    5260 //    Assert(0);
    5261     VBOXVHWACMD * pCmd = (VBOXVHWACMD*)pCommand;
    5262     /* indicate that we process and complete the command asynchronously */
    5263     pCmd->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
    5264     /* post the command to the GUI thread for processing */
    5265 //    QApplication::postEvent (mView,
    5266 //                             new VBoxVHWACommandProcessEvent (pCmd));
    5267     mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
    5268     return S_OK;
    5269 //    return E_NOTIMPL;
    5270 }
    5271 
    5272 void VBoxQGLOverlayFrameBuffer::doProcessVHWACommand(QEvent * pEvent)
    5273 {
    5274     Q_UNUSED(pEvent);
    5275     Assert(!mProcessingCommands);
    5276     mProcessingCommands = true;
    5277     Assert(!mGlCurrent);
    5278     mGlCurrent = false; /* just a fall-back */
    5279     VBoxVHWACommandElement * pFirst = mCmdPipe.detachCmdList(NULL, NULL);
    5280     do
    5281     {
    5282         VBoxVHWACommandElement * pLast = processCmdList(pFirst);
    5283 
    5284         pFirst = mCmdPipe.detachCmdList(pFirst, pLast);
    5285     } while(pFirst);
    5286 
    5287     mProcessingCommands = false;
    5288     vboxOpExit();
    5289 }
    5290 
    5291 STDMETHODIMP VBoxQGLOverlayFrameBuffer::NotifyUpdate(ULONG aX, ULONG aY,
    5292                          ULONG aW, ULONG aH)
    5293 {
    5294 #if 1
    5295     QRect r(aX, aY, aW, aH);
    5296     mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
    5297     return S_OK;
    5298 #else
    5299     /* We're not on the GUI thread and update() isn't thread safe in
    5300      * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
    5301      * on Linux (didn't check Qt 4.x there) and probably on other
    5302      * non-DOS platforms, so post the event instead. */
    5303     QApplication::postEvent (mView,
    5304                              new VBoxRepaintEvent (aX, aY, aW, aH));
    5305 
    5306     return S_OK;
    5307 #endif
    5308 }
    5309 
    5310 void VBoxQGLOverlayFrameBuffer::paintEvent (QPaintEvent *pe)
    5311 {
    5312     if(mOverlayWidgetVisible && !mProcessingCommands)
    5313     {
    5314         Assert(!mGlCurrent);
    5315         vboxDoCheckUpdateViewport();
    5316         vboxOpExit();
    5317     }
    5318 
    5319     VBoxQImageFrameBuffer::paintEvent (pe);
    5320 }
    5321 
    5322 void VBoxQGLOverlayFrameBuffer::resizeEvent (VBoxResizeEvent *re)
    5323 {
     208void VBoxQImageOverlayFrameBuffer::resizeEvent (VBoxResizeEvent *re)
     209{
     210    mOverlay.onResizeEvent(re);
    5324211    VBoxQImageFrameBuffer::resizeEvent(re);
    5325 
    5326     bool bDoOpExit = false;
    5327 
    5328     Assert(0);
    5329 
    5330     if(mGlOn)
    5331     {
    5332         Assert(!mGlCurrent);
    5333         mGlCurrent = false;
    5334         makeCurrent();
    5335         /* need to ensure we're in synch */
    5336         vboxSynchGl();
    5337         bDoOpExit = true;
    5338     }
    5339 
    5340     if(!mOnResizeCmdList.empty())
    5341     {
    5342         for (VHWACommandList::const_iterator it = mOnResizeCmdList.begin();
    5343              it != mOnResizeCmdList.end(); ++ it)
    5344         {
    5345             VBOXVHWACMD * pCmd = (*it);
    5346             vboxDoVHWACmdExec(pCmd);
    5347             free(pCmd);
    5348         }
    5349         mOnResizeCmdList.clear();
    5350         bDoOpExit = true;
    5351     }
    5352 
    5353     if(bDoOpExit)
    5354     {
    5355         vboxOpExit();
    5356     }
    5357     Assert(mGlCurrent == false);
    5358 
    5359 }
    5360 
    5361 void VBoxQGLOverlayFrameBuffer::vboxDoVHWACmd(void *cmd)
    5362 {
    5363     vboxDoVHWACmdExec(cmd);
    5364 
    5365     CDisplay display = mView->console().GetDisplay();
    5366     Assert (!display.isNull());
    5367 
    5368     display.CompleteVHWACommand((BYTE*)cmd);
    5369 }
    5370 
    5371 void VBoxQGLOverlayFrameBuffer::vboxDoUpdateRect(const QRect * pRect)
    5372 {
    5373     if(mGlOn)
    5374     {
    5375         makeCurrent();
    5376         mpOverlayWidget->vboxDoUpdateRect(pRect);
    5377         vboxOpExit();
    5378     }
    5379 
    5380     mView->viewport()->repaint (pRect->x() - mView->contentsX(),
    5381             pRect->y() - mView->contentsY(),
    5382             pRect->width(), pRect->height());
    5383 
    5384     /* translate to widget coords
    5385      * @todo: may eliminate this */
    5386 //    QPaintEvent pe(pRect->translated(-mView->contentsX(), -mView->contentsY()));
    5387 //    VBoxQImageFrameBuffer::paintEvent (&pe);
    5388 }
    5389 
    5390 void VBoxQGLOverlayFrameBuffer::vboxSynchGl()
    5391 {
    5392     if(mpOverlayWidget->vboxIsInitialized()
    5393             && pixelFormat() == mpOverlayWidget->vboxPixelFormat()
    5394             && address() == mpOverlayWidget->vboxAddress()
    5395             && bitsPerPixel() == mpOverlayWidget->vboxBitsPerPixel()
    5396             && bytesPerLine() == mpOverlayWidget->vboxBytesPerLine()
    5397             && width() == mpOverlayWidget->vboxFbWidth()
    5398             && height() == mpOverlayWidget->vboxFbHeight())
    5399     {
    5400         return;
    5401     }
    5402     /* create and issue a resize event to the gl widget to ensure we have all gl data initialized
    5403      * and synchronized with the framebuffer */
    5404     VBoxResizeEvent re(pixelFormat(),
    5405             address(),
    5406             bitsPerPixel(),
    5407             bytesPerLine(),
    5408             width(),
    5409             height());
    5410 
    5411     mpOverlayWidget->vboxResizeEvent(&re);
    5412 }
    5413 
    5414 void VBoxQGLOverlayFrameBuffer::vboxSetGlOn(bool on)
    5415 {
    5416     if(on == mGlOn)
    5417         return;
    5418 
    5419     mGlOn = on;
    5420 
    5421     if(on)
    5422     {
    5423         VBOXQGLLOGREL(("Switching Gl mode on\n"));
    5424         Assert(!mpOverlayWidget->isVisible());
    5425         /* just to ensure */
    5426         vboxShowOverlay(false);
    5427         mOverlayVisible = false;
    5428         vboxSynchGl();
    5429     }
    5430     else
    5431     {
    5432         VBOXQGLLOGREL(("Switching Gl mode off\n"));
    5433         mOverlayVisible = false;
    5434         vboxShowOverlay(false);
    5435         /* for now just set the flag w/o destroying anything */
    5436     }
    5437 }
    5438 
    5439 void VBoxQGLOverlayFrameBuffer::vboxDoCheckUpdateViewport()
    5440 {
    5441     if(!mOverlayVisible)
    5442     {
    5443         vboxShowOverlay(false);
    5444         return;
    5445     }
    5446 
    5447     int cX = mView->contentsX();
    5448     int cY = mView->contentsY();
    5449     QRect fbVp(cX, cY, mView->viewport()->width(), mView->viewport()->height());
    5450     QRect overVp = fbVp.intersected(mOverlayViewport);
    5451 
    5452     if(overVp.isEmpty())
    5453     {
    5454         vboxShowOverlay(false);
    5455     }
    5456     else
    5457     {
    5458         if(overVp != mpOverlayWidget->vboxViewport())
    5459         {
    5460             makeCurrent();
    5461             mpOverlayWidget->vboxDoUpdateViewport(overVp);
    5462         }
    5463 
    5464         QRect rect(overVp.x() - cX, overVp.y() - cY, overVp.width(), overVp.height());
    5465 
    5466         vboxCheckUpdateOverlay(rect);
    5467 
    5468         vboxShowOverlay(true);
    5469     }
    5470 }
    5471 
    5472 void VBoxQGLOverlayFrameBuffer::vboxShowOverlay(bool show)
    5473 {
    5474     if(mOverlayWidgetVisible != show)
    5475     {
    5476         mpOverlayWidget->setVisible(show);
    5477         mOverlayWidgetVisible = show;
    5478     }
    5479 }
    5480 
    5481 //void VBoxQGLOverlayFrameBuffer::vboxUpdateOverlayPosition(const QPoint & pos)
    5482 //{
    5483 ////    makeCurrent();
    5484 //
    5485 //    mpOverlayWidget->move(pos);
    5486 //
    5487 ////    /* */
    5488 ////    QRect rect = mpOverlayWidget->vboxViewport();
    5489 ////    rect.moveTo(pos);
    5490 ////    mpOverlayWidget->vboxDoUpdateViewport(rect);
    5491 //}
    5492 
    5493 void VBoxQGLOverlayFrameBuffer::vboxCheckUpdateOverlay(const QRect & rect)
    5494 {
    5495     QRect overRect = mpOverlayWidget->rect();
    5496     if(overRect.x() != rect.x() || overRect.y() != rect.y())
    5497     {
    5498         mpOverlayWidget->move(rect.x(), rect.y());
    5499     }
    5500 
    5501     if(overRect.width() != rect.width() || overRect.height() != rect.height())
    5502     {
    5503         mpOverlayWidget->resize(rect.width(), rect.height());
    5504     }
    5505 
    5506 //    mpOverlayWidget->vboxDoUpdateViewport(rect);
    5507 //
    5508 //    vboxShowOverlay(show);
    5509 }
    5510 
    5511 void VBoxQGLOverlayFrameBuffer::vboxDoVHWACmdExec(void *cmd)
    5512 {
    5513     struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
    5514     makeCurrent();
    5515     switch(pCmd->enmCmd)
    5516     {
    5517         case VBOXVHWACMD_TYPE_SURF_CANCREATE:
    5518         {
    5519             VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
    5520             pCmd->rc = mpOverlayWidget->vhwaSurfaceCanCreate(pBody);
    5521         } break;
    5522         case VBOXVHWACMD_TYPE_SURF_CREATE:
    5523         {
    5524             VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
    5525             vboxSetGlOn(true);
    5526             pCmd->rc = mpOverlayWidget->vhwaSurfaceCreate(pBody);
    5527             if(!mpOverlayWidget->hasSurfaces())
    5528             {
    5529                 vboxSetGlOn(false);
    5530             }
    5531             else
    5532             {
    5533                 mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
    5534                 if(mOverlayVisible)
    5535                 {
    5536                     mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
    5537                 }
    5538                 vboxDoCheckUpdateViewport();
    5539             }
    5540         } break;
    5541         case VBOXVHWACMD_TYPE_SURF_DESTROY:
    5542         {
    5543             VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
    5544             pCmd->rc = mpOverlayWidget->vhwaSurfaceDestroy(pBody);
    5545             if(!mpOverlayWidget->hasSurfaces())
    5546             {
    5547                 vboxSetGlOn(false);
    5548             }
    5549             else
    5550             {
    5551                 mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
    5552                 if(mOverlayVisible)
    5553                 {
    5554                     mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
    5555                 }
    5556                 vboxDoCheckUpdateViewport();
    5557             }
    5558         } break;
    5559         case VBOXVHWACMD_TYPE_SURF_LOCK:
    5560         {
    5561             VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
    5562             pCmd->rc = mpOverlayWidget->vhwaSurfaceLock(pBody);
    5563         } break;
    5564         case VBOXVHWACMD_TYPE_SURF_UNLOCK:
    5565         {
    5566             VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
    5567             pCmd->rc = mpOverlayWidget->vhwaSurfaceUnlock(pBody);
    5568         } break;
    5569         case VBOXVHWACMD_TYPE_SURF_BLT:
    5570         {
    5571             VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
    5572             pCmd->rc = mpOverlayWidget->vhwaSurfaceBlt(pBody);
    5573         } break;
    5574         case VBOXVHWACMD_TYPE_SURF_FLIP:
    5575         {
    5576             VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
    5577             pCmd->rc = mpOverlayWidget->vhwaSurfaceFlip(pBody);
    5578         } break;
    5579         case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
    5580         {
    5581             VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
    5582             pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlayUpdate(pBody);
    5583             mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
    5584             if(mOverlayVisible)
    5585             {
    5586                 mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
    5587             }
    5588             vboxDoCheckUpdateViewport();
    5589         } break;
    5590         case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
    5591         {
    5592             VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
    5593             pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlaySetPosition(pBody);
    5594             mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
    5595             if(mOverlayVisible)
    5596             {
    5597                 mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
    5598             }
    5599             vboxDoCheckUpdateViewport();
    5600         } break;
    5601         case VBOXVHWACMD_TYPE_SURF_COLORKEY_SET:
    5602         {
    5603             VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
    5604             pCmd->rc = mpOverlayWidget->vhwaSurfaceColorkeySet(pBody);
    5605         } break;
    5606         case VBOXVHWACMD_TYPE_QUERY_INFO1:
    5607         {
    5608             VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
    5609             pCmd->rc = mpOverlayWidget->vhwaQueryInfo1(pBody);
    5610         } break;
    5611         case VBOXVHWACMD_TYPE_QUERY_INFO2:
    5612         {
    5613             VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
    5614             pCmd->rc = mpOverlayWidget->vhwaQueryInfo2(pBody);
    5615         } break;
    5616         case VBOXVHWACMD_TYPE_ENABLE:
    5617         case VBOXVHWACMD_TYPE_DISABLE:
    5618             pCmd->rc = VINF_SUCCESS;
    5619             break;
    5620         case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
    5621         {
    5622             VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
    5623             pCmd->rc = vhwaConstruct(pBody);
    5624         } break;
    5625         default:
    5626             Assert(0);
    5627             pCmd->rc = VERR_NOT_IMPLEMENTED;
    5628             break;
    5629     }
    5630 }
    5631 
    5632 static DECLCALLBACK(void) vboxQGLOverlaySaveExec(PSSMHANDLE pSSM, void *pvUser)
    5633 {
    5634     VBoxQGLOverlayFrameBuffer * fb = (VBoxQGLOverlayFrameBuffer*)pvUser;
    5635     fb->vhwaSaveExec(pSSM);
    5636 }
    5637 
    5638 static DECLCALLBACK(int) vboxQGLOverlayLoadExec(PSSMHANDLE pSSM, void *pvUser, uint32_t u32Version, uint32_t uPass)
    5639 {
    5640     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    5641     VBoxQGLOverlayFrameBuffer * fb = (VBoxQGLOverlayFrameBuffer*)pvUser;
    5642     return fb->vhwaLoadExec(pSSM, u32Version);
    5643 }
    5644 
    5645 int VBoxQGLOverlayFrameBuffer::vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version)
    5646 {
    5647 //    bool bTmp;
    5648 //    int rc = SSMR3GetBool(pSSM, &bTmp /*&mGlOn*/);         AssertRC(rc);
    5649 //    rc = SSMR3GetBool(pSSM, &bTmp /*&mOverlayVisible*/);         AssertRC(rc);
    5650 //    if(RT_SUCCESS(rc))
    5651     return mpOverlayWidget->vhwaLoadExec(&mOnResizeCmdList, pSSM, u32Version);
    5652 //    return rc;
    5653 }
    5654 
    5655 void VBoxQGLOverlayFrameBuffer::vhwaSaveExec(struct SSMHANDLE * pSSM)
    5656 {
    5657 //    int rc = SSMR3PutBool(pSSM, mGlOn);         AssertRC(rc);
    5658 //    rc = SSMR3PutBool(pSSM, mOverlayVisible);         AssertRC(rc);
    5659 //
    5660     mpOverlayWidget->vhwaSaveExec(pSSM);
    5661 }
    5662 
    5663 int VBoxQGLOverlayFrameBuffer::vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd)
    5664 {
    5665     PVM pVM = (PVM)pCmd->pVM;
    5666     uint32_t intsId = 0; /* @todo: set the proper id */
    5667 
    5668     char nameFuf[sizeof(VBOXQGL_STATE_NAMEBASE) + 8];
    5669 
    5670     char * pszName = nameFuf;
    5671     sprintf(pszName, "%s%d", VBOXQGL_STATE_NAMEBASE, intsId);
    5672     int rc = SSMR3RegisterExternal(
    5673             pVM,                    /* The VM handle*/
    5674             pszName,                /* Data unit name. */
    5675             intsId,                 /* The instance identifier of the data unit.
    5676                                      * This must together with the name be unique. */
    5677             VBOXQGL_STATE_VERSION,   /* Data layout version number. */
    5678             128,             /* The approximate amount of data in the unit.
    5679                               * Only for progress indicators. */
    5680             NULL, NULL, NULL, /* pfnLiveXxx */
    5681             NULL,            /* Prepare save callback, optional. */
    5682             vboxQGLOverlaySaveExec, /* Execute save callback, optional. */
    5683             NULL,            /* Done save callback, optional. */
    5684             NULL,            /* Prepare load callback, optional. */
    5685             vboxQGLOverlayLoadExec, /* Execute load callback, optional. */
    5686             NULL,            /* Done load callback, optional. */
    5687             this             /* User argument. */
    5688             );
    5689     Assert(RT_SUCCESS(rc));
    5690     return rc;
    5691 }
    5692 
    5693 VBoxVHWACommandElement * VBoxQGLOverlayFrameBuffer::processCmdList(VBoxVHWACommandElement * pCmd)
    5694 {
    5695     VBoxVHWACommandElement * pCur;
    5696     do
    5697     {
    5698         pCur = pCmd;
    5699         switch(pCmd->type())
    5700         {
    5701         case VBOXVHWA_PIPECMD_PAINT:
    5702             vboxDoUpdateRect(&pCmd->rect());
    5703             break;
    5704 #ifdef VBOX_WITH_VIDEOHWACCEL
    5705         case VBOXVHWA_PIPECMD_VHWA:
    5706             vboxDoVHWACmd(pCmd->vhwaCmd());
    5707             break;
    5708         case VBOXVHWA_PIPECMD_OP:
    5709         {
    5710             const VBOXVHWACALLBACKINFO & info = pCmd->op();
    5711             (info.pThis->*(info.pfnCallback))(info.pContext);
    5712             break;
    5713         }
    5714         case VBOXVHWA_PIPECMD_FUNC:
    5715         {
    5716             const VBOXVHWAFUNCCALLBACKINFO & info = pCmd->func();
    5717             info.pfnCallback(info.pContext1, info.pContext2);
    5718             break;
    5719         }
    5720 #endif
    5721         default:
    5722             Assert(0);
    5723         }
    5724         pCmd = pCmd->mpNext;
    5725     } while(pCmd);
    5726 
    5727     return pCur;
    5728 }
    5729 
    5730 #endif
    5731 
    5732 VBoxVHWACommandElementProcessor::VBoxVHWACommandElementProcessor(VBoxConsoleView *aView)
    5733 {
    5734     int rc = RTCritSectInit(&mCritSect);
    5735     AssertRC(rc);
    5736 
    5737     mpFirstEvent = NULL;
    5738     mpLastEvent = NULL;
    5739     mbNewEvent = false;
    5740     mView = aView;
    5741     for(int i = RT_ELEMENTS(mElementsBuffer) - 1; i >= 0; i--)
    5742     {
    5743         mFreeElements.push(&mElementsBuffer[i]);
    5744     }
    5745 }
    5746 
    5747 VBoxVHWACommandElementProcessor::~VBoxVHWACommandElementProcessor()
    5748 {
    5749     RTCritSectDelete(&mCritSect);
    5750 }
    5751 
    5752 void VBoxVHWACommandElementProcessor::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
    5753 {
    5754     /* 1. lock*/
    5755     RTCritSectEnter(&mCritSect);
    5756     VBoxVHWACommandElement * pCmd = mFreeElements.pop();
    5757     if(!pCmd)
    5758     {
    5759         VBOXQGLLOG(("!!!no more free elements!!!\n"));
    5760 #ifdef VBOXQGL_PROF_BASE
    5761         RTCritSectLeave(&mCritSect);
    5762         return;
    5763 #else
    5764     //TODO:
    5765 #endif
    5766     }
    5767     pCmd->setData(aType, pvData);
    5768     /* 2. if can add to current*/
    5769     if(!mbNewEvent)
    5770     {
    5771         /* 3. if event is being processed (event != 0) */
    5772         if(mpLastEvent)
    5773         {
    5774             /* 3.a add cmd to event */
    5775             mpLastEvent->pipe().put(pCmd);
    5776             /* 3.b unlock and return */
    5777             RTCritSectLeave(&mCritSect);
    5778             return;
    5779         }
    5780     }
    5781 
    5782     /* we're here because the cmd was NOT be added to the current event queue */
    5783     /* 4. unlock*/
    5784     RTCritSectLeave(&mCritSect);
    5785     /* 5. create & initialize new Event */
    5786     VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent(pCmd);
    5787     /* 6. lock */
    5788     RTCritSectEnter(&mCritSect);
    5789     /* 7. if no current event set event as current */
    5790     if(!mpLastEvent)
    5791     {
    5792         Assert(!mpFirstEvent);
    5793         mpFirstEvent = pCurrentEvent;
    5794         mpLastEvent = pCurrentEvent;
    5795         pCurrentEvent->mpNext = NULL;
    5796     }
    5797     else
    5798     {
    5799         mpLastEvent->mpNext = pCurrentEvent;
    5800         mpLastEvent = pCurrentEvent;
    5801     }
    5802     /* 8. reset blocking events counter */
    5803     mbNewEvent = false;
    5804     /* 9. unlock */
    5805     RTCritSectLeave(&mCritSect);
    5806     /* 10. post event */
    5807     QApplication::postEvent (mView, pCurrentEvent);
    5808 }
    5809 
    5810 VBoxVHWACommandElement * VBoxVHWACommandElementProcessor::detachCmdList(VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
    5811 {
    5812     VBoxVHWACommandElement * pList = NULL;
    5813     RTCritSectEnter(&mCritSect);
    5814     if(pFirst2Free)
    5815     {
    5816         mFreeElements.pusha(pFirst2Free, pLast2Free);
    5817     }
    5818     if(mpFirstEvent)
    5819     {
    5820         pList = mpFirstEvent->pipe().detachList();
    5821         if(!pList)
    5822         {
    5823             VBoxVHWACommandProcessEvent *pNext = mpFirstEvent->mpNext;
    5824             if(pNext)
    5825             {
    5826                 mpFirstEvent = pNext;
    5827             }
    5828             else
    5829             {
    5830                 mpFirstEvent = NULL;
    5831                 mpLastEvent = NULL;
    5832             }
    5833         }
    5834     }
    5835     RTCritSectLeave(&mCritSect);
    5836 
    5837     return pList;
    5838 }
    5839 
    5840 
    5841 void VBoxVHWACommandsQueue::enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2)
    5842 {
    5843     VBoxVHWACommandElement *pCmd = new VBoxVHWACommandElement();
    5844     VBOXVHWAFUNCCALLBACKINFO info;
    5845     info.pfnCallback = pfn;
    5846     info.pContext1 = pContext1;
    5847     info.pContext2 = pContext2;
    5848     pCmd->setFunc(info);
    5849     mCmds.put(pCmd);
    5850 }
    5851 
    5852 VBoxVHWACommandElement * VBoxVHWACommandsQueue::detachList()
    5853 {
    5854     return mCmds.detachList();
    5855 }
    5856 
    5857 void VBoxVHWACommandsQueue::freeList(VBoxVHWACommandElement * pList)
    5858 {
    5859     while(pList)
    5860     {
    5861         VBoxVHWACommandElement * pCur = pList;
    5862         pList = pCur->mpNext;
    5863         delete pCur;
    5864     }
    5865 }
    5866 #endif
     212    mOverlay.onResizeEventPostprocess(re);
     213}
     214
     215#endif
     216
     217#endif
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

    r22794 r22816  
    549549            mode = VBoxDefs::QGLMode;
    550550#endif
    551 #if defined (VBOX_GUI_USE_QGL)
    552         else if (::strcmp (aModeStr, "qgloverlay") == 0)
    553             mode = VBoxDefs::QGLOverlayMode;
    554 #endif
     551//#if defined (VBOX_GUI_USE_QGL)
     552//        else if (::strcmp (aModeStr, "qgloverlay") == 0)
     553//            mode = VBoxDefs::QGLOverlayMode;
     554//#endif
    555555
    556556    }
     
    40794079bool VBoxGlobal::isAcceleration2DVideoAvailable()
    40804080{
    4081     return VBoxQGLFrameBuffer::isAcceleration2DVideoAvailable();
     4081    return VBoxQGLOverlay::isAcceleration2DVideoAvailable();
    40824082}
    40834083#endif
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