Changeset 22816 in vbox
- Timestamp:
- Sep 7, 2009 6:08:33 PM (15 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r22629 r22816 484 484 if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_GUI_USE_QGL) 485 485 VirtualBox_SOURCES += \ 486 src/VBoxFBQGL.cpp 486 src/VBoxFBQGL.cpp \ 487 src/VBoxFBOverlay.cpp 487 488 endif 488 489 # The Qt modules we're using. -
trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h
r22737 r22816 72 72 const CConsole &console, 73 73 VBoxDefs::RenderMode rm, 74 #ifdef VBOX_WITH_VIDEOHWACCEL 75 bool accelerate2DVideo, 76 #endif 74 77 QWidget *parent = 0); 75 78 ~VBoxConsoleView(); … … 295 298 296 299 VBoxDefs::RenderMode mode; 300 #ifdef VBOX_WITH_VIDEOHWACCEL 301 bool mAccelerate2DVideo; 302 #endif 297 303 298 304 QRegion mLastVisibleRegion; -
trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
r22794 r22816 84 84 InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode 85 85 #ifdef VBOX_GUI_USE_QGL 86 , QGLMode , QGLOverlayMode86 , QGLMode 87 87 #endif 88 88 }; -
trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
r22800 r22816 35 35 #include <QMoveEvent> 36 36 #if defined (VBOX_GUI_USE_QGL) 37 #include <QGLWidget>37 #include "VBoxFBOverlay.h" 38 38 #endif 39 39 … … 296 296 #if defined (VBOX_GUI_USE_QGL) 297 297 298 #ifdef DEBUG299 #include "iprt/stream.h"300 #define VBOXQGLLOG(_m) RTPrintf _m301 #define VBOXQGLLOGREL(_m) do { RTPrintf _m ; LogRel( _m ); } while(0)302 #else303 #define VBOXQGLLOG(_m)304 #define VBOXQGLLOGREL(_m) LogRel( _m )305 #endif306 #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 DEBUG311 #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 #else324 #define VBOXQGL_ASSERTNOERR() \325 do {}while(0)326 327 #define VBOXQGL_CHECKERR(_op) \328 do { \329 _op \330 }while(0)331 #endif332 333 #ifdef DEBUG334 #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 VBoxVHWADbgTimeCounter345 {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 #else356 #define VBOXQGLLOG_METHODTIME(_m)357 #endif358 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 VBoxVHWADirtyRect368 {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 else382 {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 else412 {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 VBoxVHWAColorKey447 {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 VBoxVHWAColorComponent469 {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 VBoxVHWAColorFormat494 {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 VBoxVHWATexture540 {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 VBoxVHWATexture591 {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 VBoxVHWATextureNP2601 {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 VBoxVHWATextureNP2Rect614 {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 VBoxVHWAHandleTable630 {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->fb651 * 2.blt652 * srcTex->invFB->tex->fb653 * |->mem654 *655 * II. Yinverted surface:656 * 1.direct memory update (paint, lock/unlock):657 * mem->tex->fb658 * 2.blt659 * srcTex->fb->tex660 * |->mem661 *662 * III. flip support:663 * 1. Yinverted<->NON-YInverted conversion :664 * mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex665 * fb-->| |->mem666 * */667 class VBoxVHWASurfaceBase668 {669 public:670 VBoxVHWASurfaceBase(671 class VBoxGLWidget *mWidget,672 #if 0673 class VBoxVHWAGlContextState *aState,674 bool aIsYInverted,675 #endif676 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 else747 {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 else760 {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 else773 {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 else786 {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 else799 {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 else812 {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 DEBUG904 public:905 uint64_t cFlipsCurr;906 uint64_t cFlipsTarg;907 #endif908 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 VBoxVHWASurfList916 {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 VBoxVHWADisplay969 {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() const1002 {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 enum1071 {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 VBOXVHWACALLBACKINFO1079 {1080 VBoxGLWidget *pThis;1081 PFNVBOXQGLOP pfnCallback;1082 void * pContext;1083 }VBOXVHWACALLBACKINFO;1084 1085 typedef struct VBOXVHWAFUNCCALLBACKINFO1086 {1087 PFNVBOXQGLFUNC pfnCallback;1088 void * pContext1;1089 void * pContext2;1090 }VBOXVHWAFUNCCALLBACKINFO;1091 1092 class VBoxVHWACommandElement1093 {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 union1151 {1152 struct _VBOXVHWACMD * mpCmd;1153 VBOXVHWACALLBACKINFO mCallback;1154 VBOXVHWAFUNCCALLBACKINFO mFuncCallback;1155 }u;1156 QRect mRect;1157 };1158 1159 class VBoxVHWACommandElementPipe1160 {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 else1176 {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 VBoxVHWACommandElementStack1202 {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 VBoxVHWACommandElementProcessor1234 {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 VBoxVHWACommandsQueue1252 {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 QGLWidget1265 {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_VIDEOHWACCEL1276 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 #endif1301 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_VIDEOHWACCEL1313 void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}1314 #endif1315 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 // else1337 // {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_SURF1352 void vboxDoTestSurfaces(void *context);1353 #endif1354 #ifdef VBOX_WITH_VIDEOHWACCEL1355 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 #endif1377 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 performed1384 * @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 restoration1423 * till the framebuffer size is restored */1424 VHWACommandList mOnResizeCmdList;1425 1426 class VBoxVHWAGlProgramMngr *mpMngr;1427 };1428 1429 1430 298 class VBoxQGLFrameBuffer : public VBoxFrameBuffer 1431 299 { … … 1445 313 #ifdef VBOX_WITH_VIDEOHWACCEL 1446 314 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand); 1447 1448 1449 static bool isAcceleration2DVideoAvailable();1450 315 #endif 1451 316 … … 1463 328 private: 1464 329 // void vboxMakeCurrent(); 1465 VBoxGLWidget * vboxWidget();1466 1467 VBoxVHWACommandElementProcessor mCmdPipe;330 class VBoxGLWidget * vboxWidget(); 331 332 class VBoxVHWACommandElementProcessor mCmdPipe; 1468 333 }; 1469 334 1470 335 #ifdef VBOX_WITH_VIDEOHWACCEL 1471 class VBoxQ GLOverlayFrameBuffer : public VBoxQImageFrameBuffer1472 { 1473 public: 1474 VBoxQ GLOverlayFrameBuffer (VBoxConsoleView *aView);336 class VBoxQImageOverlayFrameBuffer : public VBoxQImageFrameBuffer 337 { 338 public: 339 VBoxQImageOverlayFrameBuffer (VBoxConsoleView *aView); 1475 340 1476 341 … … 1484 349 void paintEvent (QPaintEvent *pe); 1485 350 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; 351 private: 352 VBoxQGLOverlay mOverlay; 1550 353 }; 1551 354 #endif -
trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
r22794 r22816 750 750 #ifdef VBOX_WITH_VIDEOHWACCEL 751 751 static bool isAcceleration2DVideoAvailable(); 752 VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() {753 #if 0754 return VBoxDefs::QGLOverlayMode;755 #else756 return VBoxDefs::QGLMode;757 #endif758 }752 // VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() { 753 //#if 0 754 // return VBoxDefs::QGLOverlayMode; 755 //#else 756 // return VBoxDefs::QGLMode; 757 //#endif 758 // } 759 759 #endif 760 760 -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
r22810 r22816 696 696 const CConsole &console, 697 697 VBoxDefs::RenderMode rm, 698 #ifdef VBOX_WITH_VIDEOHWACCEL 699 bool accelerate2DVideo, 700 #endif 698 701 QWidget *parent) 699 702 : QAbstractScrollArea (parent) … … 720 723 , muCapsLockAdaptionCnt (2) 721 724 , mode (rm) 725 #ifdef VBOX_WITH_VIDEOHWACCEL 726 , mAccelerate2DVideo(accelerate2DVideo) 727 #endif 722 728 #if defined(Q_WS_WIN) 723 729 , mAlphaCursor (NULL) … … 826 832 mFrameBuf = new VBoxQGLFrameBuffer (this); 827 833 break; 828 case VBoxDefs::QGLOverlayMode:829 mFrameBuf = new VBoxQGLOverlayFrameBuffer (this);830 break;834 // case VBoxDefs::QGLOverlayMode: 835 // mFrameBuf = new VBoxQGLOverlayFrameBuffer (this); 836 // break; 831 837 #endif 832 838 #if defined (VBOX_GUI_USE_QIMAGE) 833 839 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); 835 845 break; 836 846 #endif -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
r22703 r22816 811 811 #ifdef VBOX_WITH_VIDEOHWACCEL 812 812 /* 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()); 818 821 static_cast <QGridLayout*> (centralWidget()->layout())->addWidget (console, 1, 1, Qt::AlignVCenter | Qt::AlignHCenter); 819 822 -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
r22800 r22816 26 26 27 27 #include "VBoxConsoleView.h" 28 #include "VBoxProblemReporter.h"29 #include "VBoxGlobal.h"28 //#include "VBoxProblemReporter.h" 29 //#include "VBoxGlobal.h" 30 30 31 31 /* Qt includes */ 32 32 #include <QGLWidget> 33 33 34 #include <iprt/asm.h>35 34 //#include <iprt/asm.h> 35 // 36 36 #ifdef VBOX_WITH_VIDEOHWACCEL 37 37 #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> 707 42 // 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 2927 46 2928 47 /** @class VBoxQGLFrameBuffer … … 3029 148 } 3030 149 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 3124 151 #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 #endif3141 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 do3155 {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_VIDEOHWACCEL3165 /* static */3166 bool VBoxQGLFrameBuffer::isAcceleration2DVideoAvailable()3167 {3168 vboxVHWAGlInit(NULL);3169 return vboxVHWASupportedInternal();3170 }3171 152 3172 153 STDMETHODIMP VBoxQGLFrameBuffer::ProcessVHWACommand(BYTE *pCommand) … … 3183 164 } 3184 165 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 167 VBoxQImageOverlayFrameBuffer::VBoxQImageOverlayFrameBuffer (VBoxConsoleView *aView) 168 : VBoxQImageFrameBuffer(aView), 169 mOverlay(aView, this) 170 {} 171 172 173 STDMETHODIMP VBoxQImageOverlayFrameBuffer::ProcessVHWACommand(BYTE *pCommand) 174 { 175 return mOverlay.onVHWACommand((VBOXVHWACMD*)pCommand); 176 } 177 178 void VBoxQImageOverlayFrameBuffer::doProcessVHWACommand(QEvent * pEvent) 179 { 180 mOverlay.onVHWACommandEvent(pEvent); 181 } 182 183 STDMETHODIMP 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 191 void VBoxQImageOverlayFrameBuffer::paintEvent (QPaintEvent *pe) 192 { 193 QRect rect; 194 VBOXFBOVERLAY_RESUT res = mOverlay.onPaintEvent(pe, &rect); 195 switch(res) 3206 196 { 3207 case VBOX VHWACMD_TYPE_SURF_CANCREATE:197 case VBOXFBOVERLAY_MODIFIED: 3208 198 { 3209 VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);3210 pCmd->rc = vhwaSurfaceCanCreate(pBody);199 QPaintEvent modified(rect); 200 VBoxQImageFrameBuffer::paintEvent(&modified); 3211 201 } 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); 3279 204 break; 3280 205 } 3281 206 } 3282 207 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 { 208 void VBoxQImageOverlayFrameBuffer::resizeEvent (VBoxResizeEvent *re) 209 { 210 mOverlay.onResizeEvent(re); 5324 211 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 549 549 mode = VBoxDefs::QGLMode; 550 550 #endif 551 #if defined (VBOX_GUI_USE_QGL)552 else if (::strcmp (aModeStr, "qgloverlay") == 0)553 mode = VBoxDefs::QGLOverlayMode;554 #endif551 //#if defined (VBOX_GUI_USE_QGL) 552 // else if (::strcmp (aModeStr, "qgloverlay") == 0) 553 // mode = VBoxDefs::QGLOverlayMode; 554 //#endif 555 555 556 556 } … … 4079 4079 bool VBoxGlobal::isAcceleration2DVideoAvailable() 4080 4080 { 4081 return VBoxQGL FrameBuffer::isAcceleration2DVideoAvailable();4081 return VBoxQGLOverlay::isAcceleration2DVideoAvailable(); 4082 4082 } 4083 4083 #endif
Note:
See TracChangeset
for help on using the changeset viewer.