3
* VBox frontends: Qt GUI ("VirtualBox"):
4
* VBoxFrameBuffer Overly classes declarations
8
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
10
* This file is part of VirtualBox Open Source Edition (OSE), as
11
* available from http://www.virtualbox.org. This file is free software;
12
* you can redistribute it and/or modify it under the terms of the GNU
13
* General Public License (GPL) as published by the Free Software
14
* Foundation, in version 2 as it comes in the "COPYING" file of the
15
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19
* Clara, CA 95054 USA or visit http://www.sun.com if you need
20
* additional information or have any questions.
22
#ifndef __VBoxFBOverlay_h__
23
#define __VBoxFBOverlay_h__
24
#if defined (VBOX_GUI_USE_QGL) || defined(VBOX_WITH_VIDEOHWACCEL)
26
//#define VBOXQGL_PROF_BASE 1
27
//#define VBOXQGL_DBG_SURF 1
31
#include <iprt/assert.h>
32
#include <iprt/critsect.h>
34
#include <VBox/VBoxGL2D.h>
35
#include "VBoxFBOverlayCommon.h"
37
#define VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY 1
40
# define VBOXVHWA_PROFILE_FPS
44
class VBoxVHWADbgTimer
47
VBoxVHWADbgTimer(uint32_t cPeriods);
50
uint64_t everagePeriod() {return mPeriodSum / mcPeriods; }
51
double fps() {return ((double)1000000000.0) / everagePeriod(); }
52
uint64_t frames() {return mcFrames; }
64
class VBoxVHWADirtyRect
71
VBoxVHWADirtyRect(const QRect & aRect)
84
bool isClear() const { return mIsClear; }
86
void add(const QRect & aRect)
91
mRect = mIsClear ? aRect : mRect.united(aRect);
95
void add(const VBoxVHWADirtyRect & aRect)
102
void set(const QRect & aRect)
115
void clear() { mIsClear = true; }
117
const QRect & rect() const {return mRect;}
119
const QRect & toRect()
123
mRect.setCoords(0, 0, -1, -1);
128
bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
130
bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
132
QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
134
bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
136
void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
143
class VBoxVHWAColorKey
151
VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
156
uint32_t upper() const {return mUpper; }
157
uint32_t lower() const {return mLower; }
159
bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
165
class VBoxVHWAColorComponent
168
VBoxVHWAColorComponent() :
175
VBoxVHWAColorComponent(uint32_t aMask);
177
uint32_t mask() const { return mMask; }
178
uint32_t range() const { return mRange; }
179
uint32_t offset() const { return mOffset; }
180
uint32_t cBits() const { return mcBits; }
181
uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
182
float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
190
class VBoxVHWAColorFormat
194
// VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
195
VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
196
VBoxVHWAColorFormat(uint32_t fourcc);
197
VBoxVHWAColorFormat(){}
198
GLint internalFormat() const {return mInternalFormat; }
199
GLenum format() const {return mFormat; }
200
GLenum type() const {return mType; }
201
bool isValid() const {return mBitsPerPixel != 0; }
202
uint32_t fourcc() const {return mDataFormat;}
203
uint32_t bitsPerPixel() const { return mBitsPerPixel; }
204
uint32_t bitsPerPixelTex() const { return mBitsPerPixelTex; }
205
// uint32_t bitsPerPixelDd() const { return mBitsPerPixelDd; }
206
void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
207
uint32_t widthCompression() const {return mWidthCompression;}
208
uint32_t heightCompression() const {return mHeightCompression;}
209
const VBoxVHWAColorComponent& r() const {return mR;}
210
const VBoxVHWAColorComponent& g() const {return mG;}
211
const VBoxVHWAColorComponent& b() const {return mB;}
212
const VBoxVHWAColorComponent& a() const {return mA;}
214
bool equals (const VBoxVHWAColorFormat & other) const;
217
void init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
218
void init(uint32_t fourcc);
220
GLint mInternalFormat;
223
uint32_t mDataFormat;
225
uint32_t mBitsPerPixel;
226
uint32_t mBitsPerPixelTex;
227
// uint32_t mBitsPerPixelDd;
228
uint32_t mWidthCompression;
229
uint32_t mHeightCompression;
230
VBoxVHWAColorComponent mR;
231
VBoxVHWAColorComponent mG;
232
VBoxVHWAColorComponent mB;
233
VBoxVHWAColorComponent mA;
236
class VBoxVHWATexture
240
VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat);
241
virtual ~VBoxVHWATexture();
242
virtual void init(uchar *pvMem);
243
void setAddress(uchar *pvMem) {mAddress = pvMem;}
244
void update(const QRect * pRect) { doUpdate(mAddress, pRect);}
245
void bind() {glBindTexture(texTarget(), mTexture);}
247
virtual void texCoord(int x, int y);
248
virtual void multiTexCoord(GLenum texUnit, int x, int y);
250
// GLuint texture() {return mTexture;}
251
const QRect & texRect() {return mTexRect;}
252
const QRect & rect() {return mRect;}
253
uchar * address(){ return mAddress; }
254
uint32_t rectSizeTex(const QRect * pRect) {return pRect->width() * pRect->height() * mBytesPerPixelTex;}
255
uchar * pointAddress(int x, int y)
259
return pointAddressTex(x, y);
261
uint32_t pointOffsetTex(int x, int y) { return y*mBytesPerLine + x*mBytesPerPixelTex; }
262
uchar * pointAddressTex(int x, int y) { return mAddress + pointOffsetTex(x, y); }
263
int toXTex(int x) {return x/mColorFormat.widthCompression();}
264
int toYTex(int y) {return y/mColorFormat.heightCompression();}
265
ulong memSize(){ return mBytesPerLine * mRect.height(); }
266
uint32_t bytesPerLine() {return mBytesPerLine; }
269
virtual void doUpdate(uchar * pAddress, const QRect * pRect);
270
virtual void initParams();
272
virtual GLenum texTarget() {return GL_TEXTURE_2D; }
275
QRect mTexRect; /* texture size */
276
QRect mRect; /* img size */
279
uint32_t mBytesPerPixel;
280
uint32_t mBytesPerPixelTex;
281
uint32_t mBytesPerLine;
282
VBoxVHWAColorFormat mColorFormat;
287
class VBoxVHWATextureNP2 : public VBoxVHWATexture
290
VBoxVHWATextureNP2() : VBoxVHWATexture() {}
291
VBoxVHWATextureNP2(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
292
VBoxVHWATexture(aRect, aFormat){
293
mTexRect = QRect(0, 0, aRect.width()/aFormat.widthCompression(), aRect.height()/aFormat.heightCompression());
297
class VBoxVHWATextureNP2Rect : public VBoxVHWATextureNP2
300
VBoxVHWATextureNP2Rect() : VBoxVHWATextureNP2() {}
301
VBoxVHWATextureNP2Rect(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
302
VBoxVHWATextureNP2(aRect, aFormat){}
304
virtual void texCoord(int x, int y);
305
virtual void multiTexCoord(GLenum texUnit, int x, int y);
307
virtual GLenum texTarget();
310
class VBoxVHWATextureNP2RectPBO : public VBoxVHWATextureNP2Rect
313
VBoxVHWATextureNP2RectPBO() : VBoxVHWATextureNP2Rect() {}
314
VBoxVHWATextureNP2RectPBO(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
315
VBoxVHWATextureNP2Rect(aRect, aFormat){}
316
virtual ~VBoxVHWATextureNP2RectPBO();
318
virtual void init(uchar *pvMem);
321
virtual void doUpdate(uchar * pAddress, const QRect * pRect);
326
#ifdef VBOXVHWA_USE_TEXGROUP
327
class VBoxVHWATextureGroup
330
VBoxVHWATextureGroup()
335
VBoxVHWATextureGroup(uint32_t cTextures, uint32_t cBacks)
337
init(cTextures, cBacks);
340
~VBoxVHWATextureGroup()
342
delete[] mppTextures;
346
VBoxVHWATexture*& operator[] (size_t i) { return mppCurTextures[i]; }
349
mCur = ((++mCur) % mcSets);
351
mppCurTextures += mcTextures;
353
mppCurTextures = mppTextures;
355
uint32_t numSets() { return mcSets; }
357
void init(uint32_t cTextures, uint32_t cBacks)
360
mcTextures = cTextures;
364
mppTextures = new VBoxVHWATexture*[mcSets * cTextures];
365
mppCurTextures = mppTextures;
366
memset(mppTextures, 0, sizeof(mppTextures[0]) * mcSets * cTextures);
367
mpDisplays = new GLuint[mcSets];
368
memset(mpDisplays, 0, sizeof(mpDisplays[0]) * mcSets);
372
mppTextures = mppCurTextures = NULL;
377
GLuint& display() {return mpDisplays[mCur];}
379
VBoxVHWATexture **mppTextures;
380
VBoxVHWATexture **mppCurTextures;
388
class VBoxVHWAHandleTable
391
VBoxVHWAHandleTable(uint32_t initialSize);
392
~VBoxVHWAHandleTable();
393
uint32_t put(void * data);
394
bool mapPut(uint32_t h, void * data);
395
void* get(uint32_t h);
396
void* remove(uint32_t h);
398
void doPut(uint32_t h, void * data);
399
void doRemove(uint32_t h);
407
* I. NON-Yinverted surface:
408
* 1.direct memory update (paint, lock/unlock):
411
* srcTex->invFB->tex->fb
414
* II. Yinverted surface:
415
* 1.direct memory update (paint, lock/unlock):
422
* 1. Yinverted<->NON-YInverted conversion :
423
* mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
426
class VBoxVHWASurfaceBase
430
class VBoxGLWidget *mWidget,
432
class VBoxVHWAGlContextState *aState,
436
const QRect & aTargRect,
437
const QRect & aSrcRect,
438
const QRect & aVisTargRect,
439
VBoxVHWAColorFormat & aColorFormat,
440
VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
441
VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
442
#ifdef VBOXVHWA_USE_TEXGROUP
447
virtual ~VBoxVHWASurfaceBase();
449
void init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
453
static void globalInit();
455
// int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
457
int lock(const QRect * pRect, uint32_t flags);
461
void updatedMem(const QRect * aRect);
463
bool performDisplay(VBoxVHWASurfaceBase *pPrimary, bool bForce);
465
void setRects (const QRect & aTargRect, const QRect & aSrcRect);
466
void setTargRectPosition (const QPoint & aPoint);
467
void setVisibilityReinitFlag() { mNeedVisibilityReinit = true; }
468
void updateVisibility (VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect, bool bNotIntersected, bool bForce);
470
static ulong calcBytesPerPixel(GLenum format, GLenum type);
472
static GLsizei makePowerOf2(GLsizei val);
474
bool addressAlocated() const { return mFreeAddress; }
475
uchar * address(){ return mAddress; }
479
ulong width() { return mRect.width(); }
480
ulong height() { return mRect.height(); }
481
const QSize size() {return mRect.size();}
483
GLenum format() {return mColorFormat.format(); }
484
GLint internalFormat() { return mColorFormat.internalFormat(); }
485
GLenum type() { return mColorFormat.type(); }
486
uint32_t fourcc() {return mColorFormat.fourcc(); }
488
// ulong bytesPerPixel() { return mpTex[0]->bytesPerPixel(); }
489
ulong bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
490
// ulong bitsPerPixelDd() { return mColorFormat.bitsPerPixelDd(); }
491
ulong bytesPerLine() { return mpTex[0]->bytesPerLine(); }
493
const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
494
const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
495
const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
496
const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
497
const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
498
const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
499
void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
500
void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
502
void setDstBltCKey(const VBoxVHWAColorKey * ckey)
507
mpDstBltCKey = &mDstBltCKey;
515
void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
520
mpSrcBltCKey = &mSrcBltCKey;
528
void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
532
mDefaultDstOverlayCKey = *ckey;
533
mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
537
mpDefaultDstOverlayCKey = NULL;
541
void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
545
mDefaultSrcOverlayCKey = *ckey;
546
mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
550
mpDefaultSrcOverlayCKey = NULL;
554
void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
558
mOverriddenDstOverlayCKey = *ckey;
559
mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
563
mpDstOverlayCKey = NULL;
567
void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
571
mOverriddenSrcOverlayCKey = *ckey;
572
mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
576
mpSrcOverlayCKey = NULL;
580
const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
582
return mpSrcOverlayCKey;
585
const VBoxVHWAColorKey * getActiveDstOverlayCKey(VBoxVHWASurfaceBase * pPrimary)
587
return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : pPrimary->mpDstOverlayCKey;
590
const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
592
void setAddress(uchar * addr);
594
const QRect& rect() const {return mRect;}
595
const QRect& srcRect() const {return mSrcRect; }
596
const QRect& targRect() const {return mTargRect; }
597
class VBoxVHWASurfList * getComplexList() {return mComplexList; }
599
class VBoxVHWAGlProgramMngr * getGlProgramMngr();
600
static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
602
uint32_t handle() const {return mHGHandle;}
603
void setHandle(uint32_t h) {mHGHandle = h;}
605
const VBoxVHWADirtyRect & getDirtyRect() { return mUpdateMem2TexRect; }
607
class VBoxVHWAGlProgramVHWA * getProgram(VBoxVHWASurfaceBase * pPrimary)
609
if(mVisibleDisplayInitialized)
611
return calcProgram(pPrimary);
614
class VBoxVHWAGlProgramVHWA * calcProgram(VBoxVHWASurfaceBase * pPrimary);
615
void setRectValues (const QRect & aTargRect, const QRect & aSrcRect);
616
void setVisibleRectValues (const QRect & aVisTargRect);
618
void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
619
void initDisplay(VBoxVHWASurfaceBase *pPrimary);
620
void deleteDisplay();
622
int createDisplay(VBoxVHWASurfaceBase *pPrimary, GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram);
623
void doDisplay(VBoxVHWASurfaceBase *pPrimary, bool bProgram, bool bBindDst);
624
bool synchTexMem(const QRect * aRect);
626
int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
628
void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
629
void doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex);
630
void doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex);
632
QRect mRect; /* == Inv FB size */
635
QRect mTargRect; /* == Vis FB size */
637
QRect mVisibleTargRect;
638
QRect mVisibleSrcRect;
640
#ifndef VBOXVHWA_USE_TEXGROUP
641
GLuint mVisibleDisplay;
643
class VBoxVHWAGlProgramVHWA * mpProgram;
645
bool mVisibleDisplayInitialized;
646
bool mNeedVisibilityReinit;
647
bool mNotIntersected;
650
#ifdef VBOXVHWA_USE_TEXGROUP
651
VBoxVHWATextureGroup mpTex;
653
VBoxVHWATexture *mpTex[3];
656
VBoxVHWAColorFormat mColorFormat;
658
VBoxVHWAColorKey *mpSrcBltCKey;
659
VBoxVHWAColorKey *mpDstBltCKey;
660
VBoxVHWAColorKey *mpSrcOverlayCKey;
661
VBoxVHWAColorKey *mpDstOverlayCKey;
663
VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
664
VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
666
VBoxVHWAColorKey mSrcBltCKey;
667
VBoxVHWAColorKey mDstBltCKey;
668
VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
669
VBoxVHWAColorKey mOverriddenDstOverlayCKey;
670
VBoxVHWAColorKey mDefaultDstOverlayCKey;
671
VBoxVHWAColorKey mDefaultSrcOverlayCKey;
674
/* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
675
VBoxVHWADirtyRect mUpdateMem2TexRect;
679
class VBoxVHWASurfList *mComplexList;
681
class VBoxGLWidget *mWidget;
690
friend class VBoxVHWASurfList;
693
typedef std::list <VBoxVHWASurfaceBase*> SurfList;
694
typedef std::list <VBoxVHWASurfList*> OverlayList;
695
typedef std::list <struct _VBOXVHWACMD *> VHWACommandList;
697
class VBoxVHWASurfList
701
VBoxVHWASurfList() : mCurrent(NULL) {}
702
void add(VBoxVHWASurfaceBase *pSurf)
704
VBoxVHWASurfList * pOld = pSurf->getComplexList();
709
mSurfaces.push_back(pSurf);
710
pSurf->setComplexList(this);
715
for (SurfList::iterator it = mSurfaces.begin();
716
it != mSurfaces.end(); ++ it)
718
(*it)->setComplexList(NULL);
724
size_t size() const {return mSurfaces.size(); }
726
void remove(VBoxVHWASurfaceBase *pSurf)
728
mSurfaces.remove(pSurf);
729
pSurf->setComplexList(NULL);
730
if(mCurrent == pSurf)
734
bool empty() { return mSurfaces.empty(); }
736
void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
741
VBoxVHWASurfaceBase * current() { return mCurrent; }
742
const SurfList & surfaces() const {return mSurfaces;}
747
VBoxVHWASurfaceBase* mCurrent;
750
class VBoxVHWADisplay
755
mbDisplayPrimary(true)
757
// mSurfPrimary(NULL)
760
VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
762
VBoxVHWASurfaceBase * old = mSurfVGA;
767
Assert(!pVga->getComplexList());
769
mPrimary.setCurrentVisible(pVga);
771
// mSurfPrimary = pVga;
776
VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
778
VBoxVHWASurfaceBase * old = mSurfVGA;
784
VBoxVHWASurfaceBase * getVGA() const
789
VBoxVHWASurfaceBase * getPrimary()
791
return mPrimary.current();
794
void addOverlay(VBoxVHWASurfList * pSurf)
796
mOverlays.push_back(pSurf);
799
void checkAddOverlay(VBoxVHWASurfList * pSurf)
801
if(!hasOverlay(pSurf))
805
bool hasOverlay(VBoxVHWASurfList * pSurf)
807
for (OverlayList::iterator it = mOverlays.begin();
808
it != mOverlays.end(); ++ it)
818
void removeOverlay(VBoxVHWASurfList * pSurf)
820
mOverlays.remove(pSurf);
823
bool performDisplay(bool bForce)
825
VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
830
/* should only display overlay now */
833
bForce |= pPrimary->performDisplay(NULL, bForce);
836
for (OverlayList::const_iterator it = mOverlays.begin();
837
it != mOverlays.end(); ++ it)
839
VBoxVHWASurfaceBase * pOverlay = (*it)->current();
842
bForce |= pOverlay->performDisplay(pPrimary, bForce);
848
bool isPrimary(VBoxVHWASurfaceBase * pSurf) { return pSurf->getComplexList() == &mPrimary; }
850
void setDisplayPrimary(bool bDisplay) { mbDisplayPrimary = bDisplay; }
852
const OverlayList & overlays() const {return mOverlays;}
853
const VBoxVHWASurfList & primaries() const { return mPrimary; }
856
VBoxVHWASurfaceBase *mSurfVGA;
857
VBoxVHWASurfList mPrimary;
859
OverlayList mOverlays;
861
bool mbDisplayPrimary;
864
typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
866
typedef void (*PFNVBOXQGLFUNC)(void*, void*);
870
VBOXVHWA_PIPECMD_PAINT = 1,
871
VBOXVHWA_PIPECMD_VHWA,
873
VBOXVHWA_PIPECMD_FUNC,
874
}VBOXVHWA_PIPECMD_TYPE;
876
typedef struct VBOXVHWACALLBACKINFO
879
PFNVBOXQGLOP pfnCallback;
881
}VBOXVHWACALLBACKINFO;
883
typedef struct VBOXVHWAFUNCCALLBACKINFO
885
PFNVBOXQGLFUNC pfnCallback;
888
}VBOXVHWAFUNCCALLBACKINFO;
890
class VBoxVHWACommandElement
893
void setVHWACmd(struct _VBOXVHWACMD * pCmd)
895
mType = VBOXVHWA_PIPECMD_VHWA;
899
void setPaintCmd(const QRect & aRect)
901
mType = VBOXVHWA_PIPECMD_PAINT;
905
void setOp(const VBOXVHWACALLBACKINFO & aOp)
907
mType = VBOXVHWA_PIPECMD_OP;
911
void setFunc(const VBOXVHWAFUNCCALLBACKINFO & aOp)
913
mType = VBOXVHWA_PIPECMD_FUNC;
914
u.mFuncCallback = aOp;
917
void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
921
case VBOXVHWA_PIPECMD_PAINT:
922
setPaintCmd(*((QRect*)pvData));
924
case VBOXVHWA_PIPECMD_VHWA:
925
setVHWACmd((struct _VBOXVHWACMD *)pvData);
927
case VBOXVHWA_PIPECMD_OP:
928
setOp(*((VBOXVHWACALLBACKINFO *)pvData));
930
case VBOXVHWA_PIPECMD_FUNC:
931
setFunc(*((VBOXVHWAFUNCCALLBACKINFO *)pvData));
939
VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
940
const QRect & rect() const {return mRect;}
941
struct _VBOXVHWACMD * vhwaCmd() const {return u.mpCmd;}
942
const VBOXVHWACALLBACKINFO & op() const {return u.mCallback; }
943
const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
945
VBoxVHWACommandElement * mpNext;
947
VBOXVHWA_PIPECMD_TYPE mType;
950
struct _VBOXVHWACMD * mpCmd;
951
VBOXVHWACALLBACKINFO mCallback;
952
VBOXVHWAFUNCCALLBACKINFO mFuncCallback;
957
class VBoxVHWACommandElementPipe
960
VBoxVHWACommandElementPipe() :
965
void put(VBoxVHWACommandElement *pCmd)
970
mpLast->mpNext = pCmd;
983
VBoxVHWACommandElement * detachList()
987
VBoxVHWACommandElement * pHead = mpFirst;
995
VBoxVHWACommandElement *mpFirst;
996
VBoxVHWACommandElement *mpLast;
999
class VBoxVHWACommandElementStack
1002
VBoxVHWACommandElementStack() :
1005
void push(VBoxVHWACommandElement *pCmd)
1007
pCmd->mpNext = mpFirst;
1011
void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1013
pLast->mpNext = mpFirst;
1017
VBoxVHWACommandElement * pop()
1021
VBoxVHWACommandElement * ret = mpFirst;
1022
mpFirst = ret->mpNext;
1028
VBoxVHWACommandElement *mpFirst;
1031
#define VBOXVHWACMDPIPEC_NEWEVENT 0x00000001
1032
#define VBOXVHWACMDPIPEC_COMPLETEEVENT 0x00000002
1033
class VBoxVHWACommandElementProcessor
1036
VBoxVHWACommandElementProcessor(class VBoxConsoleView *aView);
1037
~VBoxVHWACommandElementProcessor();
1038
void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags);
1039
void completeCurrentEvent();
1040
class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
1041
void reset(class VBoxVHWACommandElement ** ppHead, class VBoxVHWACommandElement ** ppTail);
1043
RTCRITSECT mCritSect;
1044
class VBoxVHWACommandProcessEvent *mpFirstEvent;
1045
class VBoxVHWACommandProcessEvent *mpLastEvent;
1046
class VBoxConsoleView *mView;
1048
bool mbProcessingList;
1049
VBoxVHWACommandElementStack mFreeElements;
1050
VBoxVHWACommandElement mElementsBuffer[2048];
1053
class VBoxVHWACommandsQueue
1056
void enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2);
1058
VBoxVHWACommandElement * detachList();
1060
void freeList(VBoxVHWACommandElement * pList);
1063
VBoxVHWACommandElementPipe mCmds;
1066
class VBoxGLWidget : public QGLWidget
1069
VBoxGLWidget (class VBoxConsoleView *aView, QWidget *aParent);
1072
ulong vboxPixelFormat() { return mPixelFormat; }
1073
bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
1075
uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
1077
#ifdef VBOX_WITH_VIDEOHWACCEL
1078
uchar *vboxVRAMAddressFromOffset(uint64_t offset);
1079
uint64_t vboxVRAMOffsetFromAddress(uchar* addr);
1080
uint64_t vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf);
1082
void vhwaSaveExec(struct SSMHANDLE * pSSM);
1083
static void vhwaSaveExecVoid(struct SSMHANDLE * pSSM);
1084
static int vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1086
int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
1087
int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
1088
int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
1089
int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
1090
int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1091
int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
1092
int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
1093
int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
1094
int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
1095
int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
1096
int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
1097
int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
1098
int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1100
bool hasSurfaces() const;
1101
bool hasVisibleOverlays();
1102
QRect overlaysRectUnion();
1103
QRect overlaysRectIntersection();
1106
int reset(VHWACommandList * pCmdList);
1108
ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
1109
ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
1110
int vboxFbWidth() {return mDisplay.getVGA()->width(); }
1111
int vboxFbHeight() {return mDisplay.getVGA()->height(); }
1112
bool vboxIsInitialized() {return mDisplay.getVGA() != NULL; }
1114
void vboxDoResize(void *re);
1116
// void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
1117
void vboxResizeEvent (class VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
1119
void vboxProcessVHWACommands(class VBoxVHWACommandElementProcessor * pPipe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pPipe);}
1121
class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
1123
VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
1125
#ifdef VBOXVHWA_OLD_COORD
1126
static void doSetupMatrix(const QSize & aSize, bool bInverted);
1129
void vboxDoUpdateViewport(const QRect & aRect);
1130
void vboxDoUpdateRect(const QRect * pRect);
1132
const QRect & vboxViewport() const {return mViewport;}
1134
#ifdef VBOXVHWA_PROFILE_FPS
1135
void reportNewFrame() { mbNewFrame = true; }
1138
bool performDisplayAndSwap(bool bForce)
1140
// VBOXQGLLOG_METHODTIME("t:");
1142
bForce = mDisplay.performDisplay(bForce | mRepaintNeeded);
1148
#ifdef VBOXVHWA_PROFILE_FPS
1151
mFPSCounter.frame();
1152
double fps = mFPSCounter.fps();
1153
if(!(mFPSCounter.frames() % 31))
1155
printf("fps: %f\n", fps);
1163
VHWACommandList &onResizeCmdList() { return mOnResizeCmdList; }
1170
(this->*mpfnOp)(mOpContext);
1173
VBOXQGLLOG(("paintGL\n"));
1176
mDisplay.performDisplay(true);
1180
void initializeGL();
1183
static void setupMatricies(const QSize &display);
1184
static void adjustViewport(const QSize &display, const QRect &viewport);
1185
// void vboxDoPaint(void *rec);
1188
#ifdef VBOXQGL_DBG_SURF
1189
void vboxDoTestSurfaces(void *context);
1191
#ifdef VBOX_WITH_VIDEOHWACCEL
1192
void vboxDoVHWACmdExec(void *cmd);
1193
void vboxDoVHWACmdAndFree(void *cmd);
1194
void vboxDoVHWACmd(void *cmd);
1196
void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
1198
if (pSurface->addressAlocated())
1200
uchar * addr = vboxVRAMAddressFromOffset(offset);
1203
pSurface->setAddress(addr);
1208
int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
1209
static int vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t cBackBuffers, uint32_t u32Version);
1210
int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
1211
static int vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1212
static int vhwaLoadVHWAEnable(VHWACommandList * pCmdList);
1214
void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
1216
static const QGLFormat & vboxGLFormat();
1218
VBoxVHWADisplay mDisplay;
1221
/* we do all opengl stuff in the paintGL context,
1222
* submit the operation to be performed
1223
* @todo: could be moved outside the updateGL */
1224
void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext)
1227
mOpContext = pContext;
1231
// /* posts op to UI thread */
1232
// int vboxExecOpSynch(PFNVBOXQGLOP pfn, void* pContext);
1233
// void vboxExecOnResize(PFNVBOXQGLOP pfn, void* pContext);
1235
void vboxDoProcessVHWACommands(void *pContext);
1237
class VBoxVHWACommandElement * processCmdList(class VBoxVHWACommandElement * pCmd);
1239
VBoxVHWASurfaceBase* handle2Surface(uint32_t h)
1241
VBoxVHWASurfaceBase* pSurf = (VBoxVHWASurfaceBase*)mSurfHandleTable.get(h);
1246
VBoxVHWAHandleTable mSurfHandleTable;
1248
PFNVBOXQGLOP mpfnOp;
1252
bool mUsesGuestVRAM;
1254
bool mRepaintNeeded;
1256
// bool mbVGASurfCreated;
1259
class VBoxConsoleView *mView;
1261
VBoxVHWASurfList *mConstructingList;
1262
int32_t mcRemaining2Contruct;
1264
/* this is used in saved state restore to postpone surface restoration
1265
* till the framebuffer size is restored */
1266
VHWACommandList mOnResizeCmdList;
1268
class VBoxVHWAGlProgramMngr *mpMngr;
1270
#ifdef VBOXVHWA_PROFILE_FPS
1271
VBoxVHWADbgTimer mFPSCounter;
1279
// VBOXFBOVERLAY_DONE = 1,
1280
// VBOXFBOVERLAY_MODIFIED,
1281
// VBOXFBOVERLAY_UNTOUCHED
1282
//} VBOXFBOVERLAY_RESUT;
1284
class VBoxQGLOverlay
1287
VBoxQGLOverlay (class VBoxConsoleView *aView, class VBoxFrameBuffer * aContainer);
1289
int onVHWACommand(struct _VBOXVHWACMD * pCommand);
1291
void onVHWACommandEvent(QEvent * pEvent);
1294
* to be called on NotifyUpdate framebuffer call
1295
* @return true if the request was processed & should not be forwarded to the framebuffer
1296
* false - otherwise */
1297
bool onNotifyUpdate (ULONG aX, ULONG aY,
1298
ULONG aW, ULONG aH);
1301
* to be called on RequestResize framebuffer call
1302
* @return true if the request was processed & should not be forwarded to the framebuffer
1303
* false - otherwise */
1304
bool onRequestResize (ULONG /*aScreenId*/, ULONG /*aPixelFormat*/,
1305
BYTE * /*aVRAM*/, ULONG /*aBitsPerPixel*/, ULONG /*aBytesPerLine*/,
1306
ULONG /*aWidth*/, ULONG /*aHeight*/,
1307
BOOL * /*aFinished*/)
1309
mCmdPipe.completeCurrentEvent();
1313
// VBOXFBOVERLAY_RESUT onPaintEvent (const QPaintEvent *pe, QRect *pRect);
1315
void onResizeEvent (const class VBoxResizeEvent *re);
1316
void onResizeEventPostprocess (const class VBoxResizeEvent *re);
1318
void onViewportResized(QResizeEvent * /*re*/)
1320
vboxDoCheckUpdateViewport();
1324
void onViewportScrolled(int /*dx*/, int /*dy*/)
1326
vboxDoCheckUpdateViewport();
1330
static bool isAcceleration2DVideoAvailable();
1332
/** additional video memory required for the best 2D support performance
1333
* total amount of VRAM required is thus calculated as requiredVideoMemory + required2DOffscreenVideoMemory */
1334
static quint64 required2DOffscreenVideoMemory();
1336
/* not supposed to be called by clients */
1337
int vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version);
1338
void vhwaSaveExec(struct SSMHANDLE * pSSM);
1340
int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1343
void repaintOverlay()
1345
if(mNeedOverlayRepaint)
1347
mNeedOverlayRepaint = false;
1348
performDisplayOverlay();
1352
mNeedSetVisible = false;
1353
mpOverlayWidget->setVisible(true);
1367
mpOverlayWidget->makeCurrent();
1371
void performDisplayOverlay()
1376
mpOverlayWidget->updateGL();
1379
mpOverlayWidget->performDisplayAndSwap(false);
1384
// void vboxOpExit()
1386
// performDisplayOverlay();
1387
// mGlCurrent = false;
1391
void vboxSetGlOn(bool on);
1392
bool vboxGetGlOn() { return mGlOn; }
1394
void vboxDoVHWACmdExec(void *cmd);
1395
void vboxShowOverlay(bool show);
1396
void vboxDoCheckUpdateViewport();
1397
void vboxDoVHWACmd(void *cmd);
1398
void addMainDirtyRect(const QRect & aRect);
1399
// void vboxUpdateOverlayPosition(const QPoint & pos);
1400
void vboxCheckUpdateOverlay(const QRect & rect);
1401
VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
1403
int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1411
VBoxGLWidget *mpOverlayWidget;
1412
class VBoxConsoleView *mView;
1413
class VBoxFrameBuffer *mContainer;
1415
bool mOverlayWidgetVisible;
1416
bool mOverlayVisible;
1418
bool mProcessingCommands;
1419
bool mNeedOverlayRepaint;
1420
bool mNeedSetVisible;
1421
QRect mOverlayViewport;
1422
VBoxVHWADirtyRect mMainDirtyRect;
1424
VBoxVHWACommandElementProcessor mCmdPipe;
1426
/* this is used in saved state restore to postpone surface restoration
1427
* till the framebuffer size is restored */
1428
VHWACommandList mOnResizeCmdList;
1433
class VBoxOverlayFrameBuffer : public T
1436
VBoxOverlayFrameBuffer (class VBoxConsoleView *aView)
1438
mOverlay(aView, this)
1442
STDMETHOD(ProcessVHWACommand)(BYTE *pCommand)
1444
return mOverlay.onVHWACommand((struct _VBOXVHWACMD*)pCommand);
1447
void doProcessVHWACommand(QEvent * pEvent)
1449
mOverlay.onVHWACommandEvent(pEvent);
1452
STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
1453
BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
1454
ULONG aWidth, ULONG aHeight,
1457
if(mOverlay.onRequestResize (aScreenId, aPixelFormat,
1458
aVRAM, aBitsPerPixel, aBytesPerLine,
1464
return T::RequestResize (aScreenId, aPixelFormat,
1465
aVRAM, aBitsPerPixel, aBytesPerLine,
1470
STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1473
if(mOverlay.onNotifyUpdate(aX, aY, aW, aH))
1475
return T::NotifyUpdate(aX, aY, aW, aH);
1478
// void paintEvent (QPaintEvent *pe)
1481
// VBOXFBOVERLAY_RESUT res = mOverlay.onPaintEvent(pe, &rect);
1484
// case VBOXFBOVERLAY_MODIFIED:
1486
// QPaintEvent modified(rect);
1487
// T::paintEvent(&modified);
1489
// case VBOXFBOVERLAY_UNTOUCHED:
1490
// T::paintEvent(pe);
1497
void resizeEvent (VBoxResizeEvent *re)
1499
mOverlay.onResizeEvent(re);
1501
mOverlay.onResizeEventPostprocess(re);
1504
void viewportResized(QResizeEvent * re)
1506
mOverlay.onViewportResized(re);
1507
T::viewportResized(re);
1510
void viewportScrolled(int dx, int dy)
1512
mOverlay.onViewportScrolled(dx, dy);
1513
T::viewportScrolled(dx, dy);
1516
VBoxQGLOverlay mOverlay;
1521
#endif /* #ifndef __VBoxFBOverlay_h__ */