2
* VBoxFBOverlay implementaion
6
* Copyright (C) 2009 Sun Microsystems, Inc.
8
* This file is part of VirtualBox Open Source Edition (OSE), as
9
* available from http://www.virtualbox.org. This file is free software;
10
* you can redistribute it and/or modify it under the terms of the GNU
11
* General Public License (GPL) as published by the Free Software
12
* Foundation, in version 2 as it comes in the "COPYING" file of the
13
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17
* Clara, CA 95054 USA or visit http://www.sun.com if you need
18
* additional information or have any questions.
20
#if defined (VBOX_GUI_USE_QGL)
22
#define LOG_GROUP LOG_GROUP_GUI
24
#include "VBoxFBOverlay.h"
25
#include "VBoxFrameBuffer.h"
27
#include "VBoxConsoleView.h"
28
#include "VBoxProblemReporter.h"
29
#include "VBoxGlobal.h"
31
#include <VBox/VBoxGL2D.h>
38
#ifdef VBOX_WITH_VIDEOHWACCEL
39
#include <VBox/VBoxVideo.h>
40
#include <VBox/types.h>
43
#include <iprt/semaphore.h>
46
#include <QTextStream>
48
#ifdef VBOXQGL_PROF_BASE
49
# ifdef VBOXQGL_DBG_SURF
50
# define VBOXQGL_PROF_WIDTH 1400
51
# define VBOXQGL_PROF_HEIGHT 1050
53
# define VBOXQGL_PROF_WIDTH 1400
54
# define VBOXQGL_PROF_HEIGHT 1050
55
//#define VBOXQGL_PROF_WIDTH 720
56
//#define VBOXQGL_PROF_HEIGHT 480
60
#define VBOXQGL_STATE_NAMEBASE "QGLVHWAData"
61
#define VBOXQGL_STATE_VERSION 2
64
VBoxVHWADbgTimer::VBoxVHWADbgTimer(uint32_t cPeriods) :
71
mpaPeriods = new uint64_t[cPeriods];
72
memset(mpaPeriods, 0, cPeriods * sizeof(mpaPeriods[0]));
75
VBoxVHWADbgTimer::~VBoxVHWADbgTimer()
80
void VBoxVHWADbgTimer::frame()
82
uint64_t cur = VBOXGETTIME();
85
uint64_t curPeriod = cur - mPrevTime;
86
mPeriodSum += curPeriod - mpaPeriods[miPeriod];
87
mpaPeriods[miPeriod] = curPeriod;
89
miPeriod %= mcPeriods;
96
//#define VBOXQGLOVERLAY_STATE_NAMEBASE "QGLOverlayVHWAData"
97
//#define VBOXQGLOVERLAY_STATE_VERSION 1
100
# define VBOXQGL_STATE_DEBUG
103
#ifdef VBOXQGL_STATE_DEBUG
104
#define VBOXQGL_STATE_START_MAGIC 0x12345678
105
#define VBOXQGL_STATE_STOP_MAGIC 0x87654321
107
#define VBOXQGL_STATE_SURFSTART_MAGIC 0x9abcdef1
108
#define VBOXQGL_STATE_SURFSTOP_MAGIC 0x1fedcba9
110
#define VBOXQGL_STATE_OVERLAYSTART_MAGIC 0x13579bdf
111
#define VBOXQGL_STATE_OVERLAYSTOP_MAGIC 0xfdb97531
113
#define VBOXQGL_SAVE_START(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_START_MAGIC); AssertRC(rc);}while(0)
114
#define VBOXQGL_SAVE_STOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_STOP_MAGIC); AssertRC(rc);}while(0)
116
#define VBOXQGL_SAVE_SURFSTART(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_SURFSTART_MAGIC); AssertRC(rc);}while(0)
117
#define VBOXQGL_SAVE_SURFSTOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_SURFSTOP_MAGIC); AssertRC(rc);}while(0)
119
#define VBOXQGL_SAVE_OVERLAYSTART(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_OVERLAYSTART_MAGIC); AssertRC(rc);}while(0)
120
#define VBOXQGL_SAVE_OVERLAYSTOP(_pSSM) do{ int rc = SSMR3PutU32(_pSSM, VBOXQGL_STATE_OVERLAYSTOP_MAGIC); AssertRC(rc);}while(0)
122
#define VBOXQGL_LOAD_CHECK(_pSSM, _v) \
125
int rc = SSMR3GetU32(_pSSM, &_u32); AssertRC(rc); \
128
VBOXQGLLOG(("load error: expected magic (0x%x), but was (0x%x)\n", (_v), _u32));\
130
Assert(_u32 == (_v)); \
133
#define VBOXQGL_LOAD_START(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_START_MAGIC)
134
#define VBOXQGL_LOAD_STOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_STOP_MAGIC)
136
#define VBOXQGL_LOAD_SURFSTART(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_SURFSTART_MAGIC)
137
#define VBOXQGL_LOAD_SURFSTOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_SURFSTOP_MAGIC)
139
#define VBOXQGL_LOAD_OVERLAYSTART(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_OVERLAYSTART_MAGIC)
140
#define VBOXQGL_LOAD_OVERLAYSTOP(_pSSM) VBOXQGL_LOAD_CHECK(_pSSM, VBOXQGL_STATE_OVERLAYSTOP_MAGIC)
144
#define VBOXQGL_SAVE_START(_pSSM) do{}while(0)
145
#define VBOXQGL_SAVE_STOP(_pSSM) do{}while(0)
147
#define VBOXQGL_SAVE_SURFSTART(_pSSM) do{}while(0)
148
#define VBOXQGL_SAVE_SURFSTOP(_pSSM) do{}while(0)
150
#define VBOXQGL_SAVE_OVERLAYSTART(_pSSM) do{}while(0)
151
#define VBOXQGL_SAVE_OVERLAYSTOP(_pSSM) do{}while(0)
153
#define VBOXQGL_LOAD_START(_pSSM) do{}while(0)
154
#define VBOXQGL_LOAD_STOP(_pSSM) do{}while(0)
156
#define VBOXQGL_LOAD_SURFSTART(_pSSM) do{}while(0)
157
#define VBOXQGL_LOAD_SURFSTOP(_pSSM) do{}while(0)
159
#define VBOXQGL_LOAD_OVERLAYSTART(_pSSM) do{}while(0)
160
#define VBOXQGL_LOAD_OVERLAYSTOP(_pSSM) do{}while(0)
164
static VBoxVHWAInfo g_VBoxVHWASupportInfo;
165
static bool g_bVBoxVHWAChecked = false;
166
static bool g_bVBoxVHWASupported = false;
168
static struct _VBOXVHWACMD * vhwaHHCmdCreate(VBOXVHWACMD_TYPE type, size_t size)
170
char *buf = (char*)malloc(VBOXVHWACMD_SIZE_FROMBODYSIZE(size));
171
memset(buf, 0, size);
172
VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
174
pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
178
static const VBoxVHWAInfo & vboxVHWAGetSupportInfo(const QGLContext *pContext)
180
if(!g_VBoxVHWASupportInfo.isInitialized())
184
g_VBoxVHWASupportInfo.init(pContext);
188
VBoxGLTmpContext ctx;
189
const QGLContext *pContext = ctx.makeCurrent();
193
g_VBoxVHWASupportInfo.init(pContext);
197
return g_VBoxVHWASupportInfo;
200
class VBoxVHWACommandProcessEvent : public QEvent
203
VBoxVHWACommandProcessEvent (VBoxVHWACommandElement *pEl)
204
: QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
208
VBoxVHWACommandElementPipe & pipe() { return mCmdPipe; }
210
VBoxVHWACommandProcessEvent *mpNext;
212
VBoxVHWACommandElementPipe mCmdPipe;
217
VBoxVHWAHandleTable::VBoxVHWAHandleTable(uint32_t initialSize)
219
mTable = new void*[initialSize];
220
memset(mTable, 0, initialSize*sizeof(void*));
221
mcSize = initialSize;
223
mCursor = 1; /* 0 is treated as invalid */
226
VBoxVHWAHandleTable::~VBoxVHWAHandleTable()
231
uint32_t VBoxVHWAHandleTable::put(void * data)
235
return VBOXVHWA_SURFHANDLE_INVALID;
237
if(mcUsage == mcSize)
243
Assert(mcUsage < mcSize);
244
if(mcUsage >= mcSize)
245
return VBOXVHWA_SURFHANDLE_INVALID;
247
for(int k = 0; k < 2; ++k)
249
Assert(mCursor != 0);
250
for(uint32_t i = mCursor; i < mcSize; ++i)
259
mCursor = 1; /* 0 is treated as invalid */
263
return VBOXVHWA_SURFHANDLE_INVALID;
266
bool VBoxVHWAHandleTable::mapPut(uint32_t h, void * data)
279
void* VBoxVHWAHandleTable::get(uint32_t h)
286
void* VBoxVHWAHandleTable::remove(uint32_t h)
290
void* val = mTable[h];
299
void VBoxVHWAHandleTable::doPut(uint32_t h, void * data)
305
void VBoxVHWAHandleTable::doRemove(uint32_t h)
311
static VBoxVHWATexture* vboxVHWATextureCreate(const QGLContext * pContext, const QRect & aRect, const VBoxVHWAColorFormat & aFormat, bool bVGA)
313
const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(pContext);
315
if(!bVGA && info.getGlInfo().isPBOSupported())
317
VBOXQGLLOG(("VBoxVHWATextureNP2RectPBO\n"));
318
return new VBoxVHWATextureNP2RectPBO(aRect, aFormat);
320
else if(info.getGlInfo().isTextureRectangleSupported())
322
VBOXQGLLOG(("VBoxVHWATextureNP2Rect\n"));
323
return new VBoxVHWATextureNP2Rect(aRect, aFormat);
325
else if(info.getGlInfo().isTextureNP2Supported())
327
VBOXQGLLOG(("VBoxVHWATextureNP2\n"));
328
return new VBoxVHWATextureNP2(aRect, aFormat);
330
VBOXQGLLOG(("VBoxVHWATexture\n"));
331
return new VBoxVHWATexture(aRect, aFormat);
334
class VBoxVHWAGlShaderComponent
337
VBoxVHWAGlShaderComponent(const char *aRcName, GLenum aType) :
343
// virtual ~VBoxVHWAGlShaderComponent();
347
// virtual int initUniforms(class VBoxVHWAGlProgram * pProgram){}
350
const char * contents() { return mSource.constData(); }
351
bool isInitialized() { return mInitialized; }
359
int VBoxVHWAGlShaderComponent::init()
361
// Assert(!isInitialized());
363
return VINF_ALREADY_INITIALIZED;
366
if (!fi.open(QIODevice::ReadOnly))
369
return VERR_GENERAL_FAILURE;
373
QString program = is.readAll();
375
mSource = program.toAscii();
381
class VBoxVHWAGlShader
385
mType(GL_FRAGMENT_SHADER),
389
VBoxVHWAGlShader & operator= (const VBoxVHWAGlShader & other)
391
mcComponents = other.mcComponents;
395
maComponents = new VBoxVHWAGlShaderComponent*[mcComponents];
396
memcpy(maComponents, other.maComponents, mcComponents * sizeof(maComponents[0]));
401
VBoxVHWAGlShader(const VBoxVHWAGlShader & other)
403
mcComponents = other.mcComponents;
407
maComponents = new VBoxVHWAGlShaderComponent*[mcComponents];
408
memcpy(maComponents, other.maComponents, mcComponents * sizeof(maComponents[0]));
412
VBoxVHWAGlShader(GLenum aType, VBoxVHWAGlShaderComponent ** aComponents, int cComponents)
415
maComponents = new VBoxVHWAGlShaderComponent*[cComponents];
416
mcComponents = cComponents;
417
memcpy(maComponents, aComponents, cComponents * sizeof(maComponents[0]));
420
~VBoxVHWAGlShader() {delete[] maComponents;}
422
GLenum type() { return mType; }
423
GLuint shader() { return mShader; }
427
VBoxVHWAGlShaderComponent ** maComponents;
431
int VBoxVHWAGlShader::init()
435
const char **sources;
436
length = new GLint[mcComponents];
437
sources = new const char*[mcComponents];
438
for(int i = 0; i < mcComponents; i++)
441
rc = maComponents[i]->init();
442
Assert(RT_SUCCESS(rc));
445
sources[i] = maComponents[i]->contents();
449
VBOXQGLLOG(("\ncompiling shaders:\n------------\n"));
450
for(int i = 0; i < mcComponents; i++)
452
VBOXQGLLOG(("**********\n%s\n***********\n", sources[i]));
454
VBOXQGLLOG(("------------\n"));
456
mShader = vboxglCreateShader(mType);
459
vboxglShaderSource(mShader, mcComponents, sources, length);
463
vboxglCompileShader(mShader);
468
vboxglGetShaderiv(mShader, GL_COMPILE_STATUS, &compiled);
472
GLchar * pBuf = new GLchar[16300];
473
vboxglGetShaderInfoLog(mShader, 16300, NULL, pBuf);
474
VBOXQGLLOG(("\ncompile log:\n-----------\n%s\n---------\n", pBuf));
486
vboxglDeleteShader(mShader);
492
return VERR_GENERAL_FAILURE;
495
class VBoxVHWAGlProgram
498
VBoxVHWAGlProgram(VBoxVHWAGlShader ** apShaders, int acShaders);
500
~VBoxVHWAGlProgram();
503
virtual void uninit();
506
bool isInitialized() { return mProgram; }
507
GLuint program() {return mProgram;}
510
VBoxVHWAGlShader *mShaders;
514
VBoxVHWAGlProgram::VBoxVHWAGlProgram(VBoxVHWAGlShader ** apShaders, int acShaders) :
521
mShaders = new VBoxVHWAGlShader[acShaders];
522
for(int i = 0; i < acShaders; i++)
524
mShaders[i] = *apShaders[i];
526
mcShaders = acShaders;
530
VBoxVHWAGlProgram::~VBoxVHWAGlProgram()
540
int VBoxVHWAGlProgram::init()
542
Assert(!isInitialized());
544
return VINF_ALREADY_INITIALIZED;
548
return VERR_GENERAL_FAILURE;
550
int rc = VINF_SUCCESS;
551
for(int i = 0; i < mcShaders; i++)
553
int rc = mShaders[i].init();
554
Assert(RT_SUCCESS(rc));
565
mProgram = vboxglCreateProgram();
569
for(int i = 0; i < mcShaders; i++)
572
vboxglAttachShader(mProgram, mShaders[i].shader());
577
vboxglLinkProgram(mProgram);
582
vboxglGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
585
GLchar * pBuf = new GLchar[16300];
586
vboxglGetProgramInfoLog(mProgram, 16300, NULL, pBuf);
587
VBOXQGLLOG(("link log: %s\n", pBuf));
598
vboxglDeleteProgram(mProgram);
602
return VERR_GENERAL_FAILURE;
605
void VBoxVHWAGlProgram::uninit()
611
vboxglDeleteProgram(mProgram);
616
int VBoxVHWAGlProgram::start()
619
vboxglUseProgram(mProgram);
624
int VBoxVHWAGlProgram::stop()
632
#define VBOXVHWA_PROGRAM_DSTCOLORKEY 0x00000001
633
#define VBOXVHWA_PROGRAM_SRCCOLORKEY 0x00000002
634
#define VBOXVHWA_PROGRAM_COLORCONV 0x00000004
635
#define VBOXVHWA_PROGRAM_COLORKEYNODISCARD 0x00000008
637
#define VBOXVHWA_SUPPORTED_PROGRAM ( \
638
VBOXVHWA_PROGRAM_DSTCOLORKEY \
639
| VBOXVHWA_PROGRAM_SRCCOLORKEY \
640
| VBOXVHWA_PROGRAM_COLORCONV \
641
| VBOXVHWA_PROGRAM_COLORKEYNODISCARD \
644
class VBoxVHWAGlProgramVHWA : public VBoxVHWAGlProgram
647
VBoxVHWAGlProgramVHWA(/*class VBoxVHWAGlProgramMngr *aMngr, */uint32_t type, uint32_t fourcc, VBoxVHWAGlShader ** apShaders, int acShaders);
649
uint32_t type() const {return mType;}
650
uint32_t fourcc() const {return mFourcc;}
652
int setDstCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b);
654
int setDstCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b);
656
int setSrcCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b);
658
int setSrcCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b);
663
bool matches(uint32_t type, uint32_t fourcc)
665
return mType == type && mFourcc == fourcc;
668
bool equals(const VBoxVHWAGlProgramVHWA & other)
670
return matches(other.mType, other.mFourcc);
677
GLfloat mDstUpperR, mDstUpperG, mDstUpperB;
678
GLint mUniDstUpperColor;
680
GLfloat mDstLowerR, mDstLowerG, mDstLowerB;
681
GLint mUniDstLowerColor;
683
GLfloat mSrcUpperR, mSrcUpperG, mSrcUpperB;
684
GLint mUniSrcUpperColor;
686
GLfloat mSrcLowerR, mSrcLowerG, mSrcLowerB;
687
GLint mUniSrcLowerColor;
701
// VBoxVHWAGlProgram *mpProgram;
703
// class VBoxVHWAGlProgramMngr *mpMngr;
706
VBoxVHWAGlProgramVHWA::VBoxVHWAGlProgramVHWA(/*VBoxVHWAGlProgramMngr *aMngr, */uint32_t type, uint32_t fourcc, VBoxVHWAGlShader ** apShaders, int acShaders) :
707
VBoxVHWAGlProgram(apShaders, acShaders),
710
mDstUpperR(0.0), mDstUpperG(0.0), mDstUpperB(0.0),
711
mUniDstUpperColor(-1),
712
mDstLowerR(0.0), mDstLowerG(0.0), mDstLowerB(0.0),
713
mUniDstLowerColor(-1),
714
mSrcUpperR(0.0), mSrcUpperG(0.0), mSrcUpperB(0.0),
715
mUniSrcUpperColor(-1),
716
mSrcLowerR(0.0), mSrcLowerG(0.0), mSrcLowerB(0.0),
717
mUniSrcLowerColor(-1),
729
int VBoxVHWAGlProgramVHWA::init()
731
int rc = VBoxVHWAGlProgram::init();
734
if(rc == VINF_ALREADY_INITIALIZED)
739
rc = VERR_GENERAL_FAILURE;
744
mUniSrcTex = vboxglGetUniformLocation(program(), "uSrcTex");
745
Assert(mUniSrcTex != -1);
750
vboxglUniform1i(mUniSrcTex, tex);
755
if(type() & VBOXVHWA_PROGRAM_SRCCOLORKEY)
757
mUniSrcLowerColor = vboxglGetUniformLocation(program(), "uSrcClr");
758
Assert(mUniSrcLowerColor != -1);
759
if(mUniSrcLowerColor == -1)
762
mSrcLowerR = 0.0; mSrcLowerG = 0.0; mSrcLowerB = 0.0;
765
vboxglUniform4f(mUniSrcLowerColor, 0.0, 0.0, 0.0, 0.0);
769
if(type() & VBOXVHWA_PROGRAM_COLORCONV)
775
mUniVTex = vboxglGetUniformLocation(program(), "uVTex");
776
Assert(mUniVTex != -1);
781
vboxglUniform1i(mUniVTex, tex);
786
mUniUTex = vboxglGetUniformLocation(program(), "uUTex");
787
Assert(mUniUTex != -1);
791
vboxglUniform1i(mUniUTex, tex);
808
if(type() & VBOXVHWA_PROGRAM_DSTCOLORKEY)
811
mUniDstTex = vboxglGetUniformLocation(program(), "uDstTex");
812
Assert(mUniDstTex != -1);
816
vboxglUniform1i(mUniDstTex, tex);
821
mUniDstLowerColor = vboxglGetUniformLocation(program(), "uDstClr");
822
Assert(mUniDstLowerColor != -1);
823
if(mUniDstLowerColor == -1)
826
mDstLowerR = 0.0; mDstLowerG = 0.0; mDstLowerB = 0.0;
829
vboxglUniform4f(mUniDstLowerColor, 0.0, 0.0, 0.0, 0.0);
838
if(rc == VINF_SUCCESS)
842
VBoxVHWAGlProgram::uninit();
843
return VERR_GENERAL_FAILURE;
846
int VBoxVHWAGlProgramVHWA::setDstCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b)
848
Assert(isInitialized());
850
return VERR_GENERAL_FAILURE;
851
if(mDstUpperR == r && mDstUpperG == g && mDstUpperB == b)
852
return VINF_ALREADY_INITIALIZED;
853
vboxglUniform4f(mUniDstUpperColor, r, g, b, 0.0);
860
int VBoxVHWAGlProgramVHWA::setDstCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b)
862
Assert(isInitialized());
864
return VERR_GENERAL_FAILURE;
865
if(mDstLowerR == r && mDstLowerG == g && mDstLowerB == b)
866
return VINF_ALREADY_INITIALIZED;
868
// VBOXQGLLOG(("setDstCKeyLowerRange: r(%f), g(%f), b(%f)\n", r, g, b));
870
vboxglUniform4f(mUniDstLowerColor, r, g, b, 0.0);
879
int VBoxVHWAGlProgramVHWA::setSrcCKeyUpperRange(GLfloat r, GLfloat g, GLfloat b)
881
Assert(isInitialized());
883
return VERR_GENERAL_FAILURE;
884
if(mSrcUpperR == r && mSrcUpperG == g && mSrcUpperB == b)
885
return VINF_ALREADY_INITIALIZED;
886
vboxglUniform4f(mUniSrcUpperColor, r, g, b, 0.0);
893
int VBoxVHWAGlProgramVHWA::setSrcCKeyLowerRange(GLfloat r, GLfloat g, GLfloat b)
895
Assert(isInitialized());
897
return VERR_GENERAL_FAILURE;
898
if(mSrcLowerR == r && mSrcLowerG == g && mSrcLowerB == b)
899
return VINF_ALREADY_INITIALIZED;
901
vboxglUniform4f(mUniSrcLowerColor, r, g, b, 0.0);
909
class VBoxVHWAGlProgramMngr
912
VBoxVHWAGlProgramMngr() :
913
mShaderCConvApplyAYUV(":/cconvApplyAYUV.c", GL_FRAGMENT_SHADER),
914
mShaderCConvAYUV(":/cconvAYUV.c", GL_FRAGMENT_SHADER),
915
// mShaderCConvAYUVVoid(":/cconvAYUV_void.c", GL_FRAGMENT_SHADER),
916
mShaderCConvBGR(":/cconvBGR.c", GL_FRAGMENT_SHADER),
917
// mShaderCConvBGRVoid(":/cconvBGR_void.c", GL_FRAGMENT_SHADER),
918
mShaderCConvUYVY(":/cconvUYVY.c", GL_FRAGMENT_SHADER),
919
// mShaderCConvUYVYVoid(":/cconvUYVY_void.c", GL_FRAGMENT_SHADER),
920
mShaderCConvYUY2(":/cconvYUY2.c", GL_FRAGMENT_SHADER),
921
// mShaderCConvYUY2Void(":/cconvYUY2_void.c", GL_FRAGMENT_SHADER),
922
mShaderCConvYV12(":/cconvYV12.c", GL_FRAGMENT_SHADER),
923
// mShaderCConvYV12Void(":/cconvYV12_void.c", GL_FRAGMENT_SHADER),
924
mShaderSplitBGRA(":/splitBGRA.c", GL_FRAGMENT_SHADER),
925
mShaderCKeyDst(":/ckeyDst.c", GL_FRAGMENT_SHADER),
926
mShaderCKeyDst2(":/ckeyDst2.c", GL_FRAGMENT_SHADER),
927
// mShaderCKeyDstVoid(":/ckeyDst_void.c", GL_FRAGMENT_SHADER),
929
// mShaderCKeySrcVoid;
930
mShaderMainOverlay(":/mainOverlay.c", GL_FRAGMENT_SHADER),
931
mShaderMainOverlayNoCKey(":/mainOverlayNoCKey.c", GL_FRAGMENT_SHADER),
932
mShaderMainOverlayNoDiscard(":/mainOverlayNoDiscard.c", GL_FRAGMENT_SHADER),
933
mShaderMainOverlayNoDiscard2(":/mainOverlayNoDiscard2.c", GL_FRAGMENT_SHADER)
936
VBoxVHWAGlProgramVHWA * getProgram(uint32_t type, const VBoxVHWAColorFormat * pFrom, const VBoxVHWAColorFormat * pTo);
938
void stopCurrentProgram()
945
VBoxVHWAGlProgramVHWA * searchProgram(uint32_t type, uint32_t fourcc, bool bCreate);
947
VBoxVHWAGlProgramVHWA * createProgram(uint32_t type, uint32_t fourcc);
949
// int startProgram(VBoxVHWAGlProgramVHWA * pProgram) {mCurrentProgram = pProgram; return pProgram->start();}
951
typedef std::list <VBoxVHWAGlProgramVHWA*> ProgramList;
953
// VBoxVHWAGlProgramVHWA * mCurrentProgram;
954
ProgramList mPrograms;
956
VBoxVHWAGlShaderComponent mShaderCConvApplyAYUV;
958
VBoxVHWAGlShaderComponent mShaderCConvAYUV;
959
// VBoxVHWAGlShaderComponent mShaderCConvAYUVVoid;
960
VBoxVHWAGlShaderComponent mShaderCConvBGR;
961
// VBoxVHWAGlShaderComponent mShaderCConvBGRVoid;
962
VBoxVHWAGlShaderComponent mShaderCConvUYVY;
963
// VBoxVHWAGlShaderComponent mShaderCConvUYVYVoid;
964
VBoxVHWAGlShaderComponent mShaderCConvYUY2;
965
// VBoxVHWAGlShaderComponent mShaderCConvYUY2Void;
966
VBoxVHWAGlShaderComponent mShaderCConvYV12;
967
// VBoxVHWAGlShaderComponent mShaderCConvYV12Void;
968
VBoxVHWAGlShaderComponent mShaderSplitBGRA;
970
/* expected the dst surface texture to be bound to the 1-st tex unit */
971
VBoxVHWAGlShaderComponent mShaderCKeyDst;
972
/* expected the dst surface texture to be bound to the 2-nd tex unit */
973
VBoxVHWAGlShaderComponent mShaderCKeyDst2;
974
// VBoxVHWAGlShaderComponent mShaderCKeyDstVoid;
975
// VBoxVHWAGlShaderComponent mShaderCKeySrc;
976
// VBoxVHWAGlShaderComponent mShaderCKeySrcVoid;
978
VBoxVHWAGlShaderComponent mShaderMainOverlay;
979
VBoxVHWAGlShaderComponent mShaderMainOverlayNoCKey;
980
VBoxVHWAGlShaderComponent mShaderMainOverlayNoDiscard;
981
VBoxVHWAGlShaderComponent mShaderMainOverlayNoDiscard2;
983
friend class VBoxVHWAGlProgramVHWA;
986
VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::createProgram(uint32_t type, uint32_t fourcc)
988
VBoxVHWAGlShaderComponent * apShaders[16];
989
uint32_t cShaders = 0;
991
/* workaround for NVIDIA driver bug: ensure we attach the shader before those it is used in */
992
/* reserve a slot for the mShaderCConvApplyAYUV,
993
* in case it is not used the slot will be occupied by mShaderCConvBGR , which is ok */
996
if(!!(type & VBOXVHWA_PROGRAM_DSTCOLORKEY)
997
&& !(type & VBOXVHWA_PROGRAM_COLORKEYNODISCARD))
999
if(fourcc == FOURCC_YV12)
1001
apShaders[cShaders++] = &mShaderCKeyDst2;
1005
apShaders[cShaders++] = &mShaderCKeyDst;
1008
// ensure we don't have empty functions /* paranoya for for ATI on linux */
1011
// apShaders[cShaders++] = &mShaderCKeyDstVoid;
1014
if(type & VBOXVHWA_PROGRAM_SRCCOLORKEY)
1017
/* disabled for now, not really necessary for video overlaying */
1020
bool bFound = false;
1022
// if(type & VBOXVHWA_PROGRAM_COLORCONV)
1024
if(fourcc == FOURCC_UYVY)
1026
apShaders[cShaders++] = &mShaderCConvUYVY;
1029
else if(fourcc == FOURCC_YUY2)
1031
apShaders[cShaders++] = &mShaderCConvYUY2;
1034
else if(fourcc == FOURCC_YV12)
1036
// apShaders[cShaders++] = &mShaderSplitBGRA;
1037
apShaders[cShaders++] = &mShaderCConvYV12;
1040
else if(fourcc == FOURCC_AYUV)
1042
apShaders[cShaders++] = &mShaderCConvAYUV;
1049
type |= VBOXVHWA_PROGRAM_COLORCONV;
1050
apShaders[0] = &mShaderCConvApplyAYUV;
1054
type &= (~VBOXVHWA_PROGRAM_COLORCONV);
1055
apShaders[0] = &mShaderCConvBGR;
1058
if(type & VBOXVHWA_PROGRAM_DSTCOLORKEY)
1060
if(type & VBOXVHWA_PROGRAM_COLORKEYNODISCARD)
1062
if(fourcc == FOURCC_YV12)
1064
apShaders[cShaders++] = &mShaderMainOverlayNoDiscard2;
1068
apShaders[cShaders++] = &mShaderMainOverlayNoDiscard;
1073
apShaders[cShaders++] = &mShaderMainOverlay;
1078
// ensure we don't have empty functions /* paranoya for for ATI on linux */
1079
apShaders[cShaders++] = &mShaderMainOverlayNoCKey;
1082
Assert(cShaders <= RT_ELEMENTS(apShaders));
1084
VBoxVHWAGlShader shader(GL_FRAGMENT_SHADER, apShaders, cShaders);
1085
VBoxVHWAGlShader *pShader = &shader;
1087
VBoxVHWAGlProgramVHWA *pProgram = new VBoxVHWAGlProgramVHWA(/*this, */type, fourcc, &pShader, 1);
1093
VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::getProgram(uint32_t type, const VBoxVHWAColorFormat * pFrom, const VBoxVHWAColorFormat * pTo)
1096
uint32_t fourcc = 0;
1097
type &= VBOXVHWA_SUPPORTED_PROGRAM;
1099
if(pFrom && pFrom->fourcc())
1101
fourcc = pFrom->fourcc();
1102
type |= VBOXVHWA_PROGRAM_COLORCONV;
1106
type &= (~VBOXVHWA_PROGRAM_COLORCONV);
1109
if(!(type & VBOXVHWA_PROGRAM_DSTCOLORKEY)
1110
&& !(type & VBOXVHWA_PROGRAM_SRCCOLORKEY))
1112
type &= (~VBOXVHWA_PROGRAM_COLORKEYNODISCARD);
1116
return searchProgram(type, fourcc, true);
1120
VBoxVHWAGlProgramVHWA * VBoxVHWAGlProgramMngr::searchProgram(uint32_t type, uint32_t fourcc, bool bCreate)
1122
// if(mCurrentProgram && mCurrentProgram->matches(type))
1123
// return mCurrentProgram;
1125
for (ProgramList::const_iterator it = mPrograms.begin();
1126
it != mPrograms.end(); ++ it)
1128
if (!(*it)->matches(type, fourcc))
1136
VBoxVHWAGlProgramVHWA *pProgram = createProgram(type, fourcc);
1139
mPrograms.push_back(pProgram);
1146
int VBoxVHWASurfaceBase::setCKey(VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst)
1149
// pProgram->start();
1150
// pFormat->pixel2Normalized(pCKey->upper(), &r, &g, &b);
1151
// int rcU = pProgram->setCKeyUpperRange(r, g, b);
1152
// Assert(RT_SUCCESS(rcU));
1153
pFormat->pixel2Normalized(pCKey->lower(), &r, &g, &b);
1154
int rcL = bDst ? pProgram->setDstCKeyLowerRange(r, g, b) : pProgram->setSrcCKeyLowerRange(r, g, b);
1155
Assert(RT_SUCCESS(rcL));
1156
// pProgram->stop();
1158
return RT_SUCCESS(rcL) /*&& RT_SUCCESS(rcU)*/ ? VINF_SUCCESS: VERR_GENERAL_FAILURE;
1163
void VBoxVHWASurfaceBase::setAddress(uchar * addr)
1167
if(addr == mAddress) return;
1175
mFreeAddress = false;
1177
#ifdef VBOXVHWA_USE_TEXGROUP
1178
for(int i = mpTex.numSets()-1; i >=0; --i)
1181
mpTex[0]->setAddress(mAddress);
1182
if(fourcc() == FOURCC_YV12)
1184
uchar *pTexAddr = mAddress+mpTex[0]->memSize();
1185
mpTex[1]->setAddress(pTexAddr);
1186
pTexAddr = pTexAddr+mpTex[1]->memSize();
1187
mpTex[2]->setAddress(pTexAddr);
1189
#ifdef VBOXVHWA_USE_TEXGROUP
1195
// updateTexture(&mRect);
1196
mUpdateMem2TexRect.set(mRect);
1197
Assert(!mUpdateMem2TexRect.isClear());
1198
Assert(mRect.contains(mUpdateMem2TexRect.rect()));
1199
// mUpdateTex2FBRect.clear();
1200
// Assert(mUpdateTex2FBRect.isClear());
1203
void VBoxVHWASurfaceBase::globalInit()
1205
VBOXQGLLOG(("globalInit\n"));
1207
// glEnable(GL_TEXTURE_2D);
1208
glEnable(GL_TEXTURE_RECTANGLE);
1209
glDisable(GL_DEPTH_TEST);
1212
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1215
glPixelStorei(GL_PACK_ALIGNMENT, 1);
1218
// VBOXQGL_CHECKERR(
1219
// vboxglActiveTexture(GL_TEXTURE1);
1221
// VBOXQGL_CHECKERR(
1222
// glEnable(GL_TEXTURE_2D);
1224
// VBOXQGL_CHECKERR(
1225
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1227
// VBOXQGL_CHECKERR(
1228
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1230
// VBOXQGL_CHECKERR(
1231
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1233
// VBOXQGL_CHECKERR(
1234
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1237
// VBOXQGL_CHECKERR(
1238
// vboxglActiveTexture(GL_TEXTURE0);
1240
// VBOXQGL_CHECKERR(
1241
// glEnable(GL_TEXTURE_2D);
1243
// VBOXQGL_CHECKERR(
1244
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1246
// VBOXQGL_CHECKERR(
1247
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1249
// VBOXQGL_CHECKERR(
1250
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1252
// VBOXQGL_CHECKERR(
1253
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1257
VBoxVHWASurfaceBase::VBoxVHWASurfaceBase(class VBoxGLWidget *aWidget,
1258
const QSize & aSize,
1259
const QRect & aTargRect,
1260
const QRect & aSrcRect,
1261
const QRect & aVisTargRect,
1262
VBoxVHWAColorFormat & aColorFormat,
1263
VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
1264
VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
1265
#ifdef VBOXVHWA_USE_TEXGROUP
1269
mRect(0,0,aSize.width(),aSize.height()),
1271
mVisibleDisplayInitialized(false),
1272
mNeedVisibilityReinit(true),
1273
mNotIntersected(false),
1275
mColorFormat(aColorFormat),
1278
mpSrcOverlayCKey(NULL),
1279
mpDstOverlayCKey(NULL),
1280
mpDefaultDstOverlayCKey(NULL),
1281
mpDefaultSrcOverlayCKey(NULL),
1283
mFreeAddress(false),
1286
mHGHandle(VBOXVHWA_SURFHANDLE_INVALID)
1293
setDstBltCKey(pDstBltCKey);
1294
setSrcBltCKey(pSrcBltCKey);
1296
setDefaultDstOverlayCKey(pDstOverlayCKey);
1297
resetDefaultDstOverlayCKey();
1299
setDefaultSrcOverlayCKey(pSrcOverlayCKey);
1300
resetDefaultSrcOverlayCKey();
1302
#ifdef VBOXVHWA_USE_TEXGROUP
1303
mpTex.init(mColorFormat.fourcc() == FOURCC_YV12 ? 3 : 1, cBackTex);
1304
Assert(mpTex.numSets());
1305
for(int i = mpTex.numSets()-1; i >=0; --i)
1308
mpTex[0] = vboxVHWATextureCreate(mWidget->context(), QRect(0,0,aSize.width(),aSize.height()), mColorFormat, bVGA);
1309
if(mColorFormat.fourcc() == FOURCC_YV12)
1311
QRect rect(0,0,aSize.width()/2,aSize.height()/2);
1312
mpTex[1] = vboxVHWATextureCreate(mWidget->context(), rect, mColorFormat, bVGA);
1313
mpTex[2] = vboxVHWATextureCreate(mWidget->context(), rect, mColorFormat, bVGA);
1315
#ifdef VBOXVHWA_USE_TEXGROUP
1320
setRectValues(aTargRect, aSrcRect);
1321
setVisibleRectValues(aVisTargRect);
1322
// mTargSize = QRect(0, 0, aTargSize->width(), aTargSize->height());
1324
// mBytesPerPixel = calcBytesPerPixel(mColorFormat.format(), mColorFormat.type());
1325
// mBytesPerLine = mRect.width() * mBytesPerPixel;
1328
VBoxVHWASurfaceBase::~VBoxVHWASurfaceBase()
1333
GLsizei VBoxVHWASurfaceBase::makePowerOf2(GLsizei val)
1335
int last = ASMBitLastSetS32(val);
1339
if((1 << last) != val)
1341
Assert((1 << last) < val);
1342
val = (1 << (last+1));
1348
ulong VBoxVHWASurfaceBase::calcBytesPerPixel(GLenum format, GLenum type)
1350
/* we now support only common byte-aligned data */
1351
int numComponents = 0;
1354
case GL_COLOR_INDEX:
1370
case GL_LUMINANCE_ALPHA:
1378
int componentSize = 0;
1381
case GL_UNSIGNED_BYTE:
1386
case GL_UNSIGNED_SHORT:
1390
case GL_UNSIGNED_INT:
1399
return numComponents * componentSize;
1402
void VBoxVHWASurfaceBase::uninit()
1404
// mState->makeCurrent(this);
1408
#ifdef VBOXVHWA_USE_TEXGROUP
1409
for(int i = mpTex.numSets()-1; i >=0; --i)
1413
if(fourcc() == FOURCC_YV12)
1418
#ifdef VBOXVHWA_USE_TEXGROUP
1423
if(mAddress && mFreeAddress)
1430
ulong VBoxVHWASurfaceBase::memSize()
1432
ulong size = mpTex[0]->memSize();
1433
if(fourcc() == FOURCC_YV12)
1435
size += mpTex[1]->memSize() + mpTex[2]->memSize();
1440
void VBoxVHWASurfaceBase::init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem)
1445
vboxglActiveTexture(GL_TEXTURE1);
1449
int size = memSize();
1450
uchar * address = (uchar *)malloc(size);
1452
int tex0Size = mpTex[0]->memSize();
1455
memset(address, 0xff, tex0Size);
1456
Assert(size >= tex0Size);
1459
memset(address + tex0Size, 0x0, size - tex0Size);
1464
memset(address, 0x0f, tex0Size);
1465
Assert(size >= tex0Size);
1468
memset(address + tex0Size, 0x3f, size - tex0Size);
1472
memset(address, 0, size);
1475
#ifdef VBOXVHWA_USE_TEXGROUP
1476
for(int i = mpTex.numSets()-1; i >=0; --i)
1479
mpTex[0]->init(address);
1480
if(fourcc() == FOURCC_YV12)
1482
mpTex[1]->init(address);
1483
mpTex[2]->init(address);
1485
#ifdef VBOXVHWA_USE_TEXGROUP
1494
mFreeAddress = false;
1500
mFreeAddress = true;
1503
#ifdef VBOXVHWA_USE_TEXGROUP
1504
for(int i = mpTex.numSets()-1; i >=0; --i)
1507
mpTex[0]->setAddress(mAddress);
1508
if(fourcc() == FOURCC_YV12)
1510
uchar *pTexAddr = mAddress+mpTex[0]->memSize();
1511
mpTex[1]->setAddress(pTexAddr);
1512
pTexAddr = pTexAddr+mpTex[1]->memSize();
1513
mpTex[2]->setAddress(pTexAddr);
1515
#ifdef VBOXVHWA_USE_TEXGROUP
1520
initDisplay(pPrimary);
1522
mUpdateMem2TexRect.set(mRect);
1523
Assert(!mUpdateMem2TexRect.isClear());
1524
Assert(mRect.contains(mUpdateMem2TexRect.rect()));
1528
VBOXQGLLOG(("restoring to tex 0"));
1530
vboxglActiveTexture(GL_TEXTURE0);
1536
#ifdef DEBUGVHWASTRICT
1537
bool g_DbgTest = false;
1540
void VBoxVHWATexture::doUpdate(uchar * pAddress, const QRect * pRect)
1542
#ifdef DEBUGVHWASTRICT
1545
pAddress = (uchar*)malloc(memSize());
1547
for(uint32_t i = 0; i < memSize(); i++)
1555
GLenum tt = texTarget();
1558
Assert(mRect.contains(*pRect));
1565
Assert(glIsTexture(mTexture));
1567
glBindTexture(tt, mTexture);
1570
int x = pRect->x()/mColorFormat.widthCompression();
1571
int y = pRect->y()/mColorFormat.heightCompression();
1572
int width = pRect->width()/mColorFormat.widthCompression();
1573
int height = pRect->height()/mColorFormat.heightCompression();
1575
uchar * address = pAddress + pointOffsetTex(x, y);
1578
glPixelStorei(GL_UNPACK_ROW_LENGTH, mRect.width()/mColorFormat.widthCompression());
1584
x, y, width, height,
1585
mColorFormat.format(),
1586
mColorFormat.type(),
1590
#ifdef DEBUGVHWASTRICT
1598
void VBoxVHWATexture::texCoord(int x, int y)
1600
glTexCoord2f(((float)x)/mTexRect.width()/mColorFormat.widthCompression(), ((float)y)/mTexRect.height()/mColorFormat.heightCompression());
1603
void VBoxVHWATexture::multiTexCoord(GLenum texUnit, int x, int y)
1605
vboxglMultiTexCoord2f(texUnit, ((float)x)/mTexRect.width()/mColorFormat.widthCompression(), ((float)y)/mTexRect.height()/mColorFormat.heightCompression());
1608
void VBoxVHWATexture::uninit()
1612
glDeleteTextures(1,&mTexture);
1616
VBoxVHWATexture::VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat)
1620
mColorFormat = aFormat;
1622
mBytesPerPixel = mColorFormat.bitsPerPixel()/8;
1623
mBytesPerPixelTex = mColorFormat.bitsPerPixelTex()/8;
1624
mBytesPerLine = mBytesPerPixel * mRect.width();
1625
GLsizei wdt = VBoxVHWASurfaceBase::makePowerOf2(mRect.width()/mColorFormat.widthCompression());
1626
GLsizei hgt = VBoxVHWASurfaceBase::makePowerOf2(mRect.height()/mColorFormat.heightCompression());
1627
mTexRect = QRect(0,0,wdt,hgt);
1630
void VBoxVHWATexture::initParams()
1632
GLenum tt = texTarget();
1634
glTexParameteri(tt, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1635
VBOXQGL_ASSERTNOERR();
1636
glTexParameteri(tt, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1637
VBOXQGL_ASSERTNOERR();
1638
glTexParameteri(tt, GL_TEXTURE_WRAP_S, GL_CLAMP);
1639
VBOXQGL_ASSERTNOERR();
1641
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1642
VBOXQGL_ASSERTNOERR();
1643
glPixelStorei(GL_PACK_ALIGNMENT, 1);
1644
VBOXQGL_ASSERTNOERR();
1646
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1647
VBOXQGL_ASSERTNOERR();
1650
void VBoxVHWATexture::load()
1653
glPixelStorei(GL_UNPACK_ROW_LENGTH, mTexRect.width());
1657
glTexImage2D(texTarget(),
1659
mColorFormat.internalFormat(),
1663
mColorFormat.format(),
1664
mColorFormat.type(),
1665
(GLvoid *)mAddress);
1669
void VBoxVHWATexture::init(uchar *pvMem)
1671
// GLsizei wdt = mTexRect.width();
1672
// GLsizei hgt = mTexRect.height();
1675
glGenTextures(1, &mTexture);
1678
VBOXQGLLOG(("tex: %d", mTexture));
1689
VBoxVHWATexture::~VBoxVHWATexture()
1694
void VBoxVHWATextureNP2Rect::texCoord(int x, int y)
1696
glTexCoord2i(x/mColorFormat.widthCompression(), y/mColorFormat.heightCompression());
1699
void VBoxVHWATextureNP2Rect::multiTexCoord(GLenum texUnit, int x, int y)
1701
vboxglMultiTexCoord2i(texUnit, x/mColorFormat.widthCompression(), y/mColorFormat.heightCompression());
1704
GLenum VBoxVHWATextureNP2Rect::texTarget() {return GL_TEXTURE_RECTANGLE; }
1706
bool VBoxVHWASurfaceBase::synchTexMem(const QRect * pRect)
1710
Assert(mRect.contains(*pRect));
1713
if(mUpdateMem2TexRect.isClear())
1716
if(pRect && !mUpdateMem2TexRect.rect().intersects(*pRect))
1719
#ifdef VBOXVHWA_USE_TEXGROUP
1723
#ifdef VBOXVHWA_PROFILE_FPS
1724
mWidget->reportNewFrame();
1727
mpTex[0]->update(&mUpdateMem2TexRect.rect());
1728
if(fourcc() == FOURCC_YV12)
1730
QRect rect(mUpdateMem2TexRect.rect().x()/2, mUpdateMem2TexRect.rect().y()/2,
1731
mUpdateMem2TexRect.rect().width()/2, mUpdateMem2TexRect.rect().height()/2);
1732
mpTex[1]->update(&rect);
1733
mpTex[2]->update(&rect);
1737
mUpdateTex2FBRect.add(mUpdateMem2TexRect);
1738
Assert(!mUpdateTex2FBRect.isClear());
1739
Assert(mRect.contains(mUpdateTex2FBRect.rect()));
1741
mUpdateMem2TexRect.clear();
1742
Assert(mUpdateMem2TexRect.isClear());
1744
// VBOXPRINTDIF(dbgTime, ("texMem:"));
1749
void VBoxVHWATextureNP2RectPBO::init(uchar *pvMem)
1752
vboxglGenBuffers(1, &mPBO);
1754
VBoxVHWATextureNP2Rect::init(pvMem);
1757
void VBoxVHWATextureNP2RectPBO::doUpdate(uchar * pAddress, const QRect * pRect)
1762
vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
1767
buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
1772
// updateBuffer((uchar*)buf, pRect);
1773
memcpy(buf, mAddress, memSize());
1777
unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
1782
VBoxVHWATextureNP2Rect::doUpdate(0, &mRect);
1784
vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1788
VBOXQGLLOGREL(("failed to map PBO, trying fallback to non-PBO approach\n"));
1789
/* try fallback to non-PBO approach */
1790
vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1791
VBoxVHWATextureNP2Rect::doUpdate(pAddress, pRect);
1795
VBoxVHWATextureNP2RectPBO::~VBoxVHWATextureNP2RectPBO()
1798
vboxglDeleteBuffers(1, &mPBO);
1803
void VBoxVHWATextureNP2RectPBO::load()
1805
VBoxVHWATextureNP2Rect::load();
1808
vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
1812
vboxglBufferData(GL_PIXEL_UNPACK_BUFFER, memSize(), NULL, GL_STREAM_DRAW);
1815
GLvoid *buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
1819
// updateBuffer((uchar*)buf, &mRect);
1820
memcpy(buf, mAddress, memSize());
1822
bool unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
1823
Assert(unmapped); NOREF(unmapped);
1826
vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1830
void VBoxVHWASurfaceBase::synch(const QRect * aRect)
1837
void VBoxVHWASurfaceBase::synchFB(const QRect * pRect)
1839
Assert(isYInverted());
1843
Assert(mRect.contains(*pRect));
1848
if(mUpdateTex2FBRect.isClear())
1851
if(pRect && !mUpdateTex2FBRect.rect().intersects(*pRect))
1854
mState->makeCurrent(this);
1857
glBindTexture(GL_TEXTURE_2D, mTexture);
1860
VBoxVHWAGlProgramMngr * pMngr = getGlProgramMngr();
1861
pMngr->stopCurrentProgram();
1863
doTex2FB(&mUpdateTex2FBRect.rect(), &mUpdateTex2FBRect.rect());
1865
mUpdateTex2FBRect.clear();
1866
Assert(mUpdateTex2FBRect.isClear());
1869
void VBoxVHWASurfaceBase::synchMem(const QRect * pRect)
1873
Assert(mRect.contains(*pRect));
1876
if(mUpdateFB2MemRect.isClear())
1879
if(pRect && !mUpdateFB2MemRect.rect().intersects(*pRect))
1882
mState->makeYInvertedCurrent(this);
1883
// mState->makeCurrent(this);
1885
uchar * address = pointAddress(mUpdateFB2MemRect.rect().x(), mUpdateFB2MemRect.rect().y());
1888
glPixelStorei(GL_PACK_ROW_LENGTH, mRect.width());
1892
mUpdateFB2MemRect.rect().x(),
1893
mUpdateFB2MemRect.rect().y(),
1894
mUpdateFB2MemRect.rect().width(),
1895
mUpdateFB2MemRect.rect().height(),
1896
mColorFormat.format(),
1897
mColorFormat.type(),
1901
mUpdateFB2MemRect.clear();
1902
Assert(mUpdateFB2TexRect.isClear());
1905
int VBoxVHWASurfaceBase::performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt)
1910
GLuint tex = pSrcSurface->textureSynched(pSrcRect);
1917
mState->makeCurrent(this, blt);
1919
VBoxVHWAGlProgramMngr * pMngr = getGlProgramMngr();
1920
VBoxVHWAGlProgramVHWA * pProgram = pMngr->getProgram(pSrcCKey != NULL, &pSrcSurface->colorFormat(), &colorFormat());
1923
if(pSrcCKey != NULL)
1926
setCKey(pProgram, &pSrcSurface->colorFormat(), pSrcCKey);
1928
vboxglActiveTexture(GL_TEXTURE0);
1933
pMngr->stopCurrentProgram();
1939
glBindTexture(GL_TEXTURE_2D, tex);
1942
//TODO: setup strething params
1943
GLsizei wdt = pSrcSurface->mTexRect.width();
1944
GLsizei hgt = pSrcSurface->mTexRect.height();
1947
glMatrixMode(GL_TEXTURE);
1953
VBoxGLWidget::doSetupMatrix(QSize(wdt, hgt), true);
1955
glMatrixMode(GL_MODELVIEW);
1958
doTex2FB(pDstRect, pSrcRect);
1961
glMatrixMode(GL_TEXTURE);
1967
glMatrixMode(GL_MODELVIEW);
1975
/* if dst color key */
1976
/* setup ckey shader */
1980
glBindTexture(GL_TEXTURE_2D, mTexture);
1982
pProgram = pMngr->getProgram(true, NULL, NULL);
1983
/* setup ckey values*/
1984
setCKey(pProgram, &colorFormat(), pDstCKey);
1986
doTex2FB(pDstRect, pDstRect);
1989
return VINF_SUCCESS;
1992
int VBoxVHWASurfaceBase::overlay(VBoxVHWASurfaceBase * pOverlaySurface)
1994
VBOXQGLLOG(("overlay src(0x%x) ", pOverlaySurface));
1995
VBOXQGLLOG_QRECT("dst: ", &pOverlaySurface->mTargRect, "\n");
1996
VBOXQGLLOG_QRECT("src: ", &pOverlaySurface->mSrcRect, "\n");
1997
VBOXQGLLOG_METHODTIME("time:");
1999
Assert(!pOverlaySurface->isHidden());
2001
if(pOverlaySurface->isHidden())
2003
VBOXQGLLOG(("!!!hidden!!!\n"));
2004
return VINF_SUCCESS;
2007
const QRect * pSrcRect = &pOverlaySurface->mSrcRect;
2008
const QRect * pDstRect = &pOverlaySurface->mTargRect;
2009
const VBoxVHWAColorKey * pSrcCKey = pOverlaySurface->srcOverlayCKey();
2010
/* we use src (overlay) surface to maintain overridden dst ckey info
2011
* to allow multiple overlays have different overridden dst keys for one primary surface */
2012
/* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
2013
* dst ckey value in defaultDstOverlayCKey
2014
* this allows the NULL to be a valid overridden value as well */
2015
const VBoxVHWAColorKey * pDstCKey = pOverlaySurface->dstOverlayCKey() ? pOverlaySurface->defaultDstOverlayCKey() : dstOverlayCKey();
2017
return performBlt(pDstRect, pOverlaySurface, pSrcRect, pDstCKey, pSrcCKey, false);
2020
int VBoxVHWASurfaceBase::blt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey)
2024
Assert(mRect.contains(*pDstRect));
2033
Assert(pSrcSurface->mRect.contains(*pSrcRect));
2037
pSrcRect = &pSrcSurface->mRect;
2041
pSrcCKey = pSrcSurface->srcBltCKey();
2043
pDstCKey = dstBltCKey();
2045
VBOXQGLLOG(("blt dst(0x%x), src(0x%x)", this, pSrcSurface));
2046
VBOXQGLLOG_QRECT("dst: ", pDstRect, "\n");
2047
VBOXQGLLOG_QRECT("src: ", pSrcRect, "\n");
2048
VBOXQGLLOG_METHODTIME("time:");
2049
int rc = performBlt(pDstRect, pSrcSurface, pSrcRect, pDstCKey, pSrcCKey, true);
2051
mUpdateFB2TexRect.add(*pDstRect);
2052
Assert(!mUpdateFB2TexRect.isClear());
2053
Assert(mRect.contains(mUpdateFB2TexRect.rect()));
2054
// synchTexture(pDstRect);
2055
mUpdateFB2MemRect.add(*pDstRect);
2056
Assert(!mUpdateFB2MemRect.isClear());
2057
Assert(mRect.contains(mUpdateFB2MemRect.rect()));
2062
void VBoxVHWASurfaceBase::doTex2FB(const QRect * pDstRect, const QRect * pSrcRect)
2064
int tx1, ty1, tx2, ty2;
2065
pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
2066
int bx1, by1, bx2, by2;
2067
pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
2068
tx2++; ty2++;bx2++; by2++;
2071
// VBOXQGL_CHECKERR(
2072
VBOXQGLLOG_QRECT("texRect: ", &mpTex[0]->texRect(), "\n");
2074
// glTexCoord2d(((double)tx1)/mpTex[0]->texRect().width(), ((double)ty1)/mpTex[0]->texRect().height());
2075
// glVertex2i(bx1, by1);
2076
// glTexCoord2d(((double)tx1)/mpTex[0]->texRect().width(), ((double)ty2)/mpTex[0]->texRect().height());
2077
// glVertex2i(bx1, by2);
2078
// glTexCoord2d(((double)tx2)/mpTex[0]->texRect().width(), ((double)ty2)/mpTex[0]->texRect().height());
2079
// glVertex2i(bx2, by2);
2080
// glTexCoord2d(((double)tx2)/mpTex[0]->texRect().width(), ((double)ty1)/mpTex[0]->texRect().height());
2081
// glVertex2i(bx2, by1);
2082
mpTex[0]->texCoord(tx1, ty1);
2083
glVertex2i(bx1, by1);
2084
mpTex[0]->texCoord(tx1, ty2);
2085
glVertex2i(bx1, by2);
2086
mpTex[0]->texCoord(tx2, ty2);
2087
glVertex2i(bx2, by2);
2088
mpTex[0]->texCoord(tx2, ty1);
2089
glVertex2i(bx2, by1);
2095
glTexCoord2d(0.0, 0.0);
2097
glTexCoord2d(0.0, 1.0);
2098
glVertex2i(0, mRect.height());
2099
glTexCoord2d(1.0, 1.0);
2100
glVertex2i(mRect.width(), mRect.height());
2101
glTexCoord2d(1.0, 0.0);
2102
glVertex2i(mRect.width(), 0);
2108
void VBoxVHWASurfaceBase::doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex)
2110
int tx1, ty1, tx2, ty2;
2111
pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
2112
int bx1, by1, bx2, by2;
2113
pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
2114
tx2++; ty2++;bx2++; by2++;
2115
uint32_t t0width = mpTex[0]->rect().width();
2116
uint32_t t0height = mpTex[0]->rect().height();
2118
// VBOXQGL_CHECKERR(
2120
for(int i = 0; i < cSrcTex; i++)
2122
// vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
2123
// ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
2124
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->texRect().width()), ty1/(t0height/mpTex[i]->rect().height()));
2126
glVertex2i(bx1, by1);
2127
for(int i = 0; i < cSrcTex; i++)
2129
// vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx1)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
2130
// ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
2131
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->texRect().width()), ty2/(t0height/mpTex[i]->rect().height()));
2133
glVertex2i(bx1, by2);
2134
for(int i = 0; i < cSrcTex; i++)
2136
// vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
2137
// ((double)ty2)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
2138
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->texRect().width()), ty2/(t0height/mpTex[i]->rect().height()));
2141
glVertex2i(bx2, by2);
2142
for(int i = 0; i < cSrcTex; i++)
2144
// vboxglMultiTexCoord2d(GL_TEXTURE0 + i, ((double)tx2)/mpTex[i]->texRect().width()/(width()/mpTex[i]->rect().width()),
2145
// ((double)ty1)/mpTex[i]->texRect().height()/(height()/mpTex[i]->rect().height()));
2146
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->texRect().width()), ty1/(t0height/mpTex[i]->rect().height()));
2148
glVertex2i(bx2, by1);
2153
void VBoxVHWASurfaceBase::doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex)
2155
int tx1, ty1, tx2, ty2;
2156
pSrcRect->getCoords(&tx1, &ty1, &tx2, &ty2);
2157
int bx1, by1, bx2, by2;
2158
pDstRect->getCoords(&bx1, &by1, &bx2, &by2);
2159
tx2++; ty2++;bx2++; by2++;
2160
uint32_t t0width = mpTex[0]->rect().width();
2161
uint32_t t0height = mpTex[0]->rect().height();
2163
// VBOXQGL_CHECKERR(
2166
for(int i = 0; i < cSrcTex; i++)
2168
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->rect().width()), ty1/(t0height/mpTex[i]->rect().height()));
2170
pDstTex->multiTexCoord(GL_TEXTURE0 + cSrcTex, bx1, by1);
2171
glVertex2i(bx1, by1);
2173
for(int i = 0; i < cSrcTex; i++)
2175
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx1/(t0width/mpTex[i]->rect().width()), ty2/(t0height/mpTex[i]->rect().height()));
2177
pDstTex->multiTexCoord(GL_TEXTURE0 + cSrcTex, bx1, by2);
2178
glVertex2i(bx1, by2);
2180
for(int i = 0; i < cSrcTex; i++)
2182
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->rect().width()), ty2/(t0height/mpTex[i]->rect().height()));
2184
pDstTex->multiTexCoord(GL_TEXTURE0 + cSrcTex, bx2, by2);
2185
glVertex2i(bx2, by2);
2187
for(int i = 0; i < cSrcTex; i++)
2189
mpTex[i]->multiTexCoord(GL_TEXTURE0 + i, tx2/(t0width/mpTex[i]->rect().width()), ty1/(t0height/mpTex[i]->rect().height()));
2191
pDstTex->multiTexCoord(GL_TEXTURE0 + cSrcTex, bx2, by1);
2192
glVertex2i(bx2, by1);
2199
int VBoxVHWASurfaceBase::lock(const QRect * pRect, uint32_t flags)
2205
Assert(mRect.contains(*pRect));
2208
Assert(mLockCount >= 0);
2209
if(pRect && pRect->isEmpty())
2210
return VERR_GENERAL_FAILURE;
2212
return VERR_GENERAL_FAILURE;
2214
VBOXQGLLOG(("lock (0x%x)", this));
2215
VBOXQGLLOG_QRECT("rect: ", pRect ? pRect : &mRect, "\n");
2216
VBOXQGLLOG_METHODTIME("time ");
2217
// if(!(flags & VBOXVHWA_LOCK_DISCARDCONTENTS))
2222
mUpdateMem2TexRect.add(pRect ? *pRect : mRect);
2224
Assert(!mUpdateMem2TexRect.isClear());
2225
Assert(mRect.contains(mUpdateMem2TexRect.rect()));
2226
return VINF_SUCCESS;
2229
int VBoxVHWASurfaceBase::unlock()
2231
VBOXQGLLOG(("unlock (0x%x)\n", this));
2233
return VINF_SUCCESS;
2236
void VBoxVHWASurfaceBase::setRectValues (const QRect & aTargRect, const QRect & aSrcRect)
2238
mTargRect = aTargRect;
2239
mSrcRect = aSrcRect;
2242
void VBoxVHWASurfaceBase::setVisibleRectValues (const QRect & aVisTargRect)
2244
mVisibleTargRect = aVisTargRect.intersected(mTargRect);
2245
if(mVisibleTargRect.isEmpty() || mTargRect.isEmpty())
2247
mVisibleSrcRect.setSize(QSize(0, 0));
2251
float stretchX = float(mSrcRect.width()) / mTargRect.width();
2252
float stretchY = float(mSrcRect.height()) / mTargRect.height();
2253
int tx1, tx2, ty1, ty2, vtx1, vtx2, vty1, vty2;
2254
int sx1, sx2, sy1, sy2;
2255
mVisibleTargRect.getCoords(&vtx1, &vty1, &vtx2, &vty2);
2256
mTargRect.getCoords(&tx1, &ty1, &tx2, &ty2);
2257
mSrcRect.getCoords(&sx1, &sy1, &sx2, &sy2);
2258
int dx1 = vtx1 - tx1;
2259
int dy1 = vty1 - ty1;
2260
int dx2 = vtx2 - tx2;
2261
int dy2 = vty2 - ty2;
2262
int vsx1, vsy1, vsx2, vsy2;
2267
vsx1 = sx1 + int(dx1*stretchX);
2268
vsy1 = sy1 + int(dy1*stretchY);
2269
vsx2 = sx2 + int(dx2*stretchX);
2270
vsy2 = sy2 + int(dy2*stretchY);
2271
mVisibleSrcRect.setCoords(vsx1, vsy1, vsx2, vsy2);
2272
Assert(!mVisibleSrcRect.isEmpty());
2273
Assert(mSrcRect.contains(mVisibleSrcRect));
2278
void VBoxVHWASurfaceBase::setRects(const QRect & aTargRect, const QRect & aSrcRect)
2280
if(mTargRect != aTargRect || mSrcRect != aSrcRect)
2282
setRectValues(aTargRect, aSrcRect);
2283
mNeedVisibilityReinit = true;
2287
void VBoxVHWASurfaceBase::setTargRectPosition(const QPoint & aPoint)
2289
QRect tRect = targRect();
2290
tRect.moveTopLeft(aPoint);
2291
setRects(tRect, srcRect());
2294
void VBoxVHWASurfaceBase::updateVisibility (VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect, bool bNotIntersected, bool bForce)
2296
if(mNeedVisibilityReinit || bForce || aVisibleTargRect.intersected(mTargRect) != mVisibleTargRect || mNotIntersected != bNotIntersected)
2298
setVisibleRectValues(aVisibleTargRect);
2299
mNotIntersected = bNotIntersected;
2300
initDisplay(pPrimary);
2301
mNeedVisibilityReinit = false;
2305
void VBoxVHWASurfaceBase::deleteDisplay(
2309
if(mVisibleDisplayInitialized)
2311
#ifdef VBOXVHWA_USE_TEXGROUP
2312
for(int i = mpTex.numSets()-1; i >=0; --i)
2316
glDeleteLists(mpTex.display(), 1);
2317
mpTex.display() = 0;
2328
glDeleteLists(mVisibleDisplay, 1);
2329
mVisibleDisplay = 0;
2336
mVisibleDisplayInitialized = false;
2340
void VBoxVHWASurfaceBase::doDisplay(VBoxVHWASurfaceBase *pPrimary, bool bProgram, bool bBindDst)
2342
bool bInvokeMultiTex2 = false;
2346
// pProgram->start();
2348
// if(pSrcCKey != NULL)
2350
// pProgram->start();
2351
// setCKey(pProgram, &pSrcSurface->colorFormat(), pSrcCKey);
2353
// vboxglActiveTexture(GL_TEXTURE0);
2358
if(fourcc() == FOURCC_YV12)
2360
vboxglActiveTexture(GL_TEXTURE1);
2362
vboxglActiveTexture(GL_TEXTURE1+1);
2365
vboxglActiveTexture(GL_TEXTURE1+2);
2369
vboxglActiveTexture(GL_TEXTURE1);
2371
pPrimary->mpTex[0]->bind();
2373
vboxglActiveTexture(GL_TEXTURE0);
2375
bInvokeMultiTex2 = true;
2379
if(fourcc() == FOURCC_YV12)
2381
vboxglActiveTexture(GL_TEXTURE1);
2383
vboxglActiveTexture(GL_TEXTURE0);
2390
// vboxglActiveTexture(GL_TEXTURE0);
2392
// VBOXQGLLOG(("binding (primary??) texture: %d\n", mpTex[0]->texture()));
2395
if(bInvokeMultiTex2)
2397
doMultiTex2FB(&mVisibleTargRect, pPrimary->mpTex[0], &mVisibleSrcRect,
2398
(fourcc() == FOURCC_YV12) ? 2 : 1);
2402
if(fourcc() == FOURCC_YV12)
2404
doMultiTex2FB(&mVisibleTargRect, &mVisibleSrcRect, 2);
2408
VBOXQGLLOG_QRECT("mVisibleTargRect: ", &mVisibleTargRect, "\n");
2409
VBOXQGLLOG_QRECT("mVisibleSrcRect: ", &mVisibleSrcRect, "\n");
2410
doTex2FB(&mVisibleTargRect, &mVisibleSrcRect);
2416
// pProgram->stop();
2420
class VBoxVHWAGlProgramVHWA * VBoxVHWASurfaceBase::calcProgram(VBoxVHWASurfaceBase * pPrimary)
2422
const VBoxVHWAColorKey * pSrcCKey = NULL, *pDstCKey = NULL;
2425
pSrcCKey = getActiveSrcOverlayCKey();
2426
/* we use src (overlay) surface to maintain overridden dst ckey info
2427
* to allow multiple overlays have different overridden dst keys for one primary surface */
2428
/* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
2429
* dst ckey value in defaultDstOverlayCKey
2430
* this allows the NULL to be a valid overridden value as well */
2431
pDstCKey = getActiveDstOverlayCKey(pPrimary);
2433
if(pDstCKey != NULL)
2434
type |= VBOXVHWA_PROGRAM_DSTCOLORKEY;
2436
type |= VBOXVHWA_PROGRAM_SRCCOLORKEY;
2437
if((pDstCKey || pSrcCKey) && mNotIntersected)
2438
type |= VBOXVHWA_PROGRAM_COLORKEYNODISCARD;
2440
return mWidget->vboxVHWAGetGlProgramMngr()->getProgram(type, &colorFormat(), &pPrimary->colorFormat());
2443
int VBoxVHWASurfaceBase::createDisplay(VBoxVHWASurfaceBase *pPrimary, GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram)
2445
if(mVisibleTargRect.isEmpty())
2447
Assert(mVisibleSrcRect.isEmpty());
2450
Assert(!mVisibleSrcRect.isEmpty());
2451
/* just for the fallback */
2452
if(mVisibleSrcRect.isEmpty())
2455
return VINF_SUCCESS;
2458
VBoxVHWAGlProgramVHWA * pProgram = NULL;
2461
pProgram = calcProgram(pPrimary);
2464
const VBoxVHWAColorKey *pResSrcCKey = getActiveSrcOverlayCKey();
2465
const VBoxVHWAColorKey *pResDstCKey = getActiveDstOverlayCKey(pPrimary);
2470
VBoxVHWASurfaceBase::setCKey(pProgram, &colorFormat(), pResSrcCKey, false);
2474
VBoxVHWASurfaceBase::setCKey(pProgram, &pPrimary->colorFormat(), pResDstCKey, true);
2480
glGetError(); /* clear the err flag */
2481
GLuint display = glGenLists(1);
2482
GLenum err = glGetError();
2483
if(err == GL_NO_ERROR)
2488
/* well, it seems it should not return 0 on success according to the spec,
2489
* but just in case, pick another one */
2490
display = glGenLists(1);
2492
if(err == GL_NO_ERROR)
2506
const VBoxVHWAColorKey * pDstCKey = pPrimary ? getActiveDstOverlayCKey(pPrimary) : NULL;
2508
glNewList(display, GL_COMPILE);
2510
doDisplay(pPrimary, pProgram != 0, pDstCKey != NULL);
2513
VBOXQGL_ASSERTNOERR();
2514
*pDisplay = display;
2515
*ppProgram = pProgram;
2516
return VINF_SUCCESS;
2521
VBOXQGLLOG(("gl error ocured (0x%x)\n", err));
2522
Assert(err == GL_NO_ERROR);
2525
return VERR_GENERAL_FAILURE;
2528
void VBoxVHWASurfaceBase::initDisplay(VBoxVHWASurfaceBase *pPrimary)
2533
#ifdef VBOXVHWA_USE_TEXGROUP
2534
for(int i = mpTex.numSets()-1; i >=0; --i)
2536
rc = createDisplay(pPrimary, &mpTex.display(), &mpProgram);
2543
rc = createDisplay(pPrimary, &mVisibleDisplay, &mpProgram);
2548
mVisibleDisplayInitialized = true;
2552
mVisibleDisplayInitialized = false;
2556
void VBoxVHWASurfaceBase::updatedMem(const QRect *rec)
2560
Assert(mRect.contains(*rec));
2562
mUpdateMem2TexRect.add(*rec);
2565
//void VBoxVHWASurfaceBase::setVisibleTargetRect(const QRect & aRect)
2567
// Assert(mVisibleRect.contains(aRect));
2568
// mVisibleRect = mSrcRect.intersected(aRect);
2571
bool VBoxVHWASurfaceBase::performDisplay(VBoxVHWASurfaceBase *pPrimary, bool bForce)
2573
Assert(mVisibleDisplayInitialized);
2575
#ifdef VBOXVHWA_USE_TEXGROUP
2576
if(mpTex.display() == 0)
2578
if(mVisibleDisplay == 0)
2581
/* nothing to display, i.e. the surface is not visible,
2582
* in the sense that it's located behind the viewport ranges */
2583
Assert(mVisibleSrcRect.isEmpty());
2584
Assert(mVisibleTargRect.isEmpty());
2589
Assert(!mVisibleSrcRect.isEmpty());
2590
Assert(!mVisibleTargRect.isEmpty());
2593
bForce |= synchTexMem(&mVisibleSrcRect);
2594
if(pPrimary && getActiveDstOverlayCKey(pPrimary))
2596
bForce |= pPrimary->synchTexMem(&mVisibleTargRect);
2602
#ifdef VBOXVHWA_USE_TEXGROUP
2603
Assert(mpTex.display());
2605
Assert(mVisibleDisplay);
2608
if(!mVisibleDisplayInitialized)
2610
VBoxVHWAGlProgramVHWA * pProgram = NULL;
2613
pProgram = calcProgram(pPrimary);
2616
const VBoxVHWAColorKey * pDstCKey = NULL;
2617
pDstCKey = getActiveDstOverlayCKey(pPrimary);
2621
doDisplay(pPrimary, pProgram != 0, pDstCKey != NULL);
2626
// doDisplay(pPrimary, NULL, false);
2632
#ifdef VBOXVHWA_USE_TEXGROUP
2634
glCallList(mpTex.display());
2638
glCallList(mVisibleDisplay);
2650
class VBoxGLContext : public QGLContext
2653
VBoxGLContext (const QGLFormat & format ) :
2655
mAllowDoneCurrent(true)
2661
if(!mAllowDoneCurrent)
2663
QGLContext::doneCurrent();
2666
bool isDoneCurrentAllowed() { return mAllowDoneCurrent; }
2667
void allowDoneCurrent(bool bAllow) { mAllowDoneCurrent = bAllow; }
2669
bool mAllowDoneCurrent;
2672
VBoxGLWidget::VBoxGLWidget (VBoxConsoleView *aView, QWidget *aParent)
2673
: QGLWidget (new VBoxGLContext(VBoxGLWidget::vboxGLFormat()), aParent),
2674
mSurfHandleTable(128), /* 128 should be enough */
2678
mUsesGuestVRAM(false),
2679
mRepaintNeeded(false),
2680
// mbVGASurfCreated(false),
2682
mConstructingList(NULL),
2683
mcRemaining2Contruct(0)
2684
#ifdef VBOXVHWA_PROFILE_FPS
2690
mpMngr = new VBoxVHWAGlProgramMngr();
2691
// /* No need for background drawing */
2692
// setAttribute (Qt::WA_OpaquePaintEvent);
2695
const QGLFormat & VBoxGLWidget::vboxGLFormat()
2697
static QGLFormat vboxFormat = QGLFormat();
2698
vboxFormat.setAlpha(true);
2699
Assert(vboxFormat.alpha());
2700
vboxFormat.setSwapInterval(0);
2701
Assert(vboxFormat.swapInterval() == 0);
2702
vboxFormat.setAccum(false);
2703
Assert(!vboxFormat.accum());
2704
vboxFormat.setDepth(false);
2705
Assert(!vboxFormat.depth());
2706
// vboxFormat.setRedBufferSize(8);
2707
// vboxFormat.setGreenBufferSize(8);
2708
// vboxFormat.setBlueBufferSize(8);
2712
VBoxGLWidget::~VBoxGLWidget()
2717
#ifdef VBOXVHWA_OLD_COORD
2718
void VBoxGLWidget::doSetupMatrix(const QSize & aSize, bool bInverted)
2726
glScalef(1.0f/aSize.width(), 1.0f/aSize.height(), 1.0f);
2731
/* make display coordinates be scaled to pixel coordinates */
2733
glTranslatef(0.0f, 1.0f, 0.0f);
2736
glScalef(1.0f/aSize.width(), 1.0f/aSize.height(), 1.0f);
2739
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
2745
void VBoxGLWidget::adjustViewport(const QSize &display, const QRect &viewport)
2747
#ifdef VBOXVHWA_OLD_COORD
2748
/* viewport: (viewport.x;viewport.y) (viewport.width;viewport.height)*/
2749
glViewport(-((int)display.width() + viewport.x()),
2750
-((int)display.height() - viewport.y() + display.height() - viewport.height()),
2752
2*display.height());
2754
glViewport(-viewport.x(),
2755
viewport.height() + viewport.y() - display.height(),
2762
void VBoxGLWidget::setupMatricies(const QSize &display)
2764
#ifdef VBOXVHWA_OLD_COORD
2765
glMatrixMode(GL_PROJECTION);
2767
glFrustum(0., (GLdouble)display.width(), 0., (GLdouble)display.height(), 0., 0.);
2769
glMatrixMode(GL_MODELVIEW);
2770
// doSetupMatrix(bInverted ? &mRect.size() : &mTargSize.size(), bInverted);
2771
doSetupMatrix(display, false);
2773
glMatrixMode(GL_PROJECTION);
2775
glOrtho(0., (GLdouble)display.width(), (GLdouble)display.height(), 0., -1., 1.);
2777
glMatrixMode(GL_MODELVIEW);
2782
VBoxVHWACommandElement * VBoxGLWidget::processCmdList(VBoxVHWACommandElement * pCmd)
2784
VBoxVHWACommandElement * pCur;
2788
switch(pCmd->type())
2790
case VBOXVHWA_PIPECMD_PAINT:
2791
vboxDoUpdateRect(&pCmd->rect());
2793
#ifdef VBOX_WITH_VIDEOHWACCEL
2794
case VBOXVHWA_PIPECMD_VHWA:
2795
vboxDoVHWACmd(pCmd->vhwaCmd());
2797
case VBOXVHWA_PIPECMD_OP:
2799
const VBOXVHWACALLBACKINFO & info = pCmd->op();
2800
(info.pThis->*(info.pfnCallback))(info.pContext);
2803
case VBOXVHWA_PIPECMD_FUNC:
2805
const VBOXVHWAFUNCCALLBACKINFO & info = pCmd->func();
2806
info.pfnCallback(info.pContext1, info.pContext2);
2813
pCmd = pCmd->mpNext;
2819
void VBoxGLWidget::vboxDoProcessVHWACommands(void *pContext)
2821
VBoxVHWACommandElementProcessor * pPipe = (VBoxVHWACommandElementProcessor*)pContext;
2822
VBoxVHWACommandElement * pFirst = pPipe->detachCmdList(NULL, NULL);
2825
VBoxVHWACommandElement * pLast = processCmdList(pFirst);
2827
pFirst = pPipe->detachCmdList(pFirst, pLast);
2830
// mDisplay.performDisplay();
2833
int VBoxGLWidget::reset(VHWACommandList * pCmdList)
2836
const OverlayList & overlays = mDisplay.overlays();
2837
for (OverlayList::const_iterator oIt = overlays.begin();
2838
oIt != overlays.end(); ++ oIt)
2840
VBoxVHWASurfList * pSurfList = *oIt;
2841
if(pSurfList->current())
2843
/* 1. hide overlay */
2844
pCmd = vhwaHHCmdCreate(VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
2845
VBOXVHWACMD_SURF_OVERLAY_UPDATE *pOUCmd = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
2846
pOUCmd->u.in.hSrcSurf = pSurfList->current()->handle();
2847
pOUCmd->u.in.flags = VBOXVHWA_OVER_HIDE;
2849
pCmdList->push_back(pCmd);
2852
/* 2. destroy overlay */
2853
const SurfList & surfaces = pSurfList->surfaces();
2855
for (SurfList::const_iterator sIt = surfaces.begin();
2856
sIt != surfaces.end(); ++ sIt)
2858
VBoxVHWASurfaceBase *pCurSurf = (*sIt);
2859
pCmd = vhwaHHCmdCreate(VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
2860
VBOXVHWACMD_SURF_DESTROY *pSDCmd = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
2861
pSDCmd->u.in.hSurf = pCurSurf->handle();
2863
pCmdList->push_back(pCmd);
2867
/* 3. destroy primaries */
2868
const SurfList & surfaces = mDisplay.primaries().surfaces();
2869
for (SurfList::const_iterator sIt = surfaces.begin();
2870
sIt != surfaces.end(); ++ sIt)
2872
VBoxVHWASurfaceBase *pCurSurf = (*sIt);
2873
if(pCurSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID)
2875
pCmd = vhwaHHCmdCreate(VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
2876
VBOXVHWACMD_SURF_DESTROY *pSDCmd = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
2877
pSDCmd->u.in.hSurf = pCurSurf->handle();
2879
pCmdList->push_back(pCmd);
2883
return VINF_SUCCESS;
2886
#ifdef VBOX_WITH_VIDEOHWACCEL
2887
void VBoxGLWidget::vboxDoVHWACmd(void *cmd)
2889
vboxDoVHWACmdExec(cmd);
2891
CDisplay display = mView->console().GetDisplay();
2892
Assert (!display.isNull());
2894
display.CompleteVHWACommand((BYTE*)cmd);
2897
void VBoxGLWidget::vboxDoVHWACmdAndFree(void *cmd)
2899
vboxDoVHWACmdExec(cmd);
2904
void VBoxGLWidget::vboxDoVHWACmdExec(void *cmd)
2906
struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
2907
switch(pCmd->enmCmd)
2909
case VBOXVHWACMD_TYPE_SURF_CANCREATE:
2911
VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
2912
pCmd->rc = vhwaSurfaceCanCreate(pBody);
2914
case VBOXVHWACMD_TYPE_SURF_CREATE:
2916
VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
2917
pCmd->rc = vhwaSurfaceCreate(pBody);
2919
case VBOXVHWACMD_TYPE_SURF_DESTROY:
2921
VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
2922
pCmd->rc = vhwaSurfaceDestroy(pBody);
2924
case VBOXVHWACMD_TYPE_SURF_LOCK:
2926
VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
2927
pCmd->rc = vhwaSurfaceLock(pBody);
2929
case VBOXVHWACMD_TYPE_SURF_UNLOCK:
2931
VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
2932
pCmd->rc = vhwaSurfaceUnlock(pBody);
2934
case VBOXVHWACMD_TYPE_SURF_BLT:
2936
VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2937
pCmd->rc = vhwaSurfaceBlt(pBody);
2939
case VBOXVHWACMD_TYPE_SURF_FLIP:
2941
VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2942
pCmd->rc = vhwaSurfaceFlip(pBody);
2944
case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
2946
VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
2947
pCmd->rc = vhwaSurfaceOverlayUpdate(pBody);
2949
case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
2951
VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
2952
pCmd->rc = vhwaSurfaceOverlaySetPosition(pBody);
2954
case VBOXVHWACMD_TYPE_SURF_COLORKEY_SET:
2956
VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
2957
pCmd->rc = vhwaSurfaceColorkeySet(pBody);
2959
case VBOXVHWACMD_TYPE_QUERY_INFO1:
2961
VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
2962
pCmd->rc = vhwaQueryInfo1(pBody);
2964
case VBOXVHWACMD_TYPE_QUERY_INFO2:
2966
VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
2967
pCmd->rc = vhwaQueryInfo2(pBody);
2969
case VBOXVHWACMD_TYPE_ENABLE:
2970
case VBOXVHWACMD_TYPE_DISABLE:
2971
pCmd->rc = VINF_SUCCESS;
2973
case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
2975
VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
2976
pCmd->rc = vhwaConstruct(pBody);
2980
pCmd->rc = VERR_NOT_IMPLEMENTED;
2985
int VBoxGLWidget::vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd)
2987
VBOXQGLLOG_ENTER(("\n"));
2989
const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
2991
if(!(pCmd->SurfInfo.flags & VBOXVHWA_SD_CAPS))
2994
pCmd->u.out.ErrInfo = -1;
2995
return VINF_SUCCESS;
2997
#ifdef VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY
2998
if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN)
3000
#ifdef DEBUGVHWASTRICT
3003
pCmd->u.out.ErrInfo = -1;
3004
return VINF_SUCCESS;
3008
if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
3010
if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_COMPLEX)
3015
pCmd->u.out.ErrInfo = -1;
3019
pCmd->u.out.ErrInfo = 0;
3021
return VINF_SUCCESS;
3024
#ifdef VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY
3025
if((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) == 0)
3027
#ifdef DEBUGVHWASTRICT
3030
pCmd->u.out.ErrInfo = -1;
3031
return VINF_SUCCESS;
3035
if(pCmd->u.in.bIsDifferentPixelFormat)
3037
if(!(pCmd->SurfInfo.flags & VBOXVHWA_SD_PIXELFORMAT))
3040
pCmd->u.out.ErrInfo = -1;
3041
return VINF_SUCCESS;
3044
if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
3046
if(pCmd->SurfInfo.PixelFormat.c.rgbBitCount != 32
3047
|| pCmd->SurfInfo.PixelFormat.c.rgbBitCount != 24)
3050
pCmd->u.out.ErrInfo = -1;
3051
return VINF_SUCCESS;
3054
else if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
3056
/* detect whether we support this format */
3057
bool bFound = false;
3058
for(int i = 0; i < info.getFourccSupportedCount(); i++)
3060
if(info.getFourccSupportedList()[i] == pCmd->SurfInfo.PixelFormat.fourCC)
3069
VBOXQGLLOG(("!!unsupported fourcc!!!: %c%c%c%c\n",
3070
(pCmd->SurfInfo.PixelFormat.fourCC & 0x000000ff),
3071
(pCmd->SurfInfo.PixelFormat.fourCC & 0x0000ff00) >> 8,
3072
(pCmd->SurfInfo.PixelFormat.fourCC & 0x00ff0000) >> 16,
3073
(pCmd->SurfInfo.PixelFormat.fourCC & 0xff000000) >> 24
3075
//#ifdef DEBUG_misha
3078
pCmd->u.out.ErrInfo = -1;
3079
return VINF_SUCCESS;
3085
pCmd->u.out.ErrInfo = -1;
3086
return VINF_SUCCESS;
3090
pCmd->u.out.ErrInfo = 0;
3091
return VINF_SUCCESS;
3094
int VBoxGLWidget::vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd)
3096
VBOXQGLLOG_ENTER(("\n"));
3098
uint32_t handle = VBOXVHWA_SURFHANDLE_INVALID;
3099
if(pCmd->SurfInfo.hSurf != VBOXVHWA_SURFHANDLE_INVALID)
3101
handle = pCmd->SurfInfo.hSurf;
3102
if(mSurfHandleTable.get(handle))
3106
// if(!mcVGASurfCreated)
3108
// /* check if it is a primary surface that needs handle adjusting*/
3109
// if((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
3110
// && handle2Surface(handle) == mDisplay.getVGA())
3112
// /* remove, the primary surface will be assigned to a new handle assumed by the guest */
3113
// mSurfHandleTable.remove(handle);
3118
return VERR_GENERAL_FAILURE;
3123
VBoxVHWASurfaceBase *surf = NULL;
3124
// VBoxVHWAColorFormat *pFormat = NULL, Format;
3125
bool bNoPBO = false;
3126
bool bPrimary = false;
3128
VBoxVHWAColorKey *pDstBltCKey = NULL, DstBltCKey;
3129
VBoxVHWAColorKey *pSrcBltCKey = NULL, SrcBltCKey;
3130
VBoxVHWAColorKey *pDstOverlayCKey = NULL, DstOverlayCKey;
3131
VBoxVHWAColorKey *pSrcOverlayCKey = NULL, SrcOverlayCKey;
3132
if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKDESTBLT)
3134
DstBltCKey = VBoxVHWAColorKey(pCmd->SurfInfo.DstBltCK.high, pCmd->SurfInfo.DstBltCK.low);
3135
pDstBltCKey = &DstBltCKey;
3137
if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKSRCBLT)
3139
SrcBltCKey = VBoxVHWAColorKey(pCmd->SurfInfo.SrcBltCK.high, pCmd->SurfInfo.SrcBltCK.low);
3140
pSrcBltCKey = &SrcBltCKey;
3142
if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKDESTOVERLAY)
3144
DstOverlayCKey = VBoxVHWAColorKey(pCmd->SurfInfo.DstOverlayCK.high, pCmd->SurfInfo.DstOverlayCK.low);
3145
pDstOverlayCKey = &DstOverlayCKey;
3147
if(pCmd->SurfInfo.flags & VBOXVHWA_SD_CKSRCOVERLAY)
3149
SrcOverlayCKey = VBoxVHWAColorKey(pCmd->SurfInfo.SrcOverlayCK.high, pCmd->SurfInfo.SrcOverlayCK.low);
3150
pSrcOverlayCKey = &SrcOverlayCKey;
3153
if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_PRIMARYSURFACE)
3157
VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
3159
Assert((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN) == 0);
3160
if(pVga->handle() == VBOXVHWA_SURFHANDLE_INVALID
3161
&& (pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN) == 0)
3163
Assert(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB);
3164
// if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
3166
Assert(pCmd->SurfInfo.width == pVga->width());
3167
Assert(pCmd->SurfInfo.height == pVga->height());
3168
// if(pCmd->SurfInfo.width == pVga->width()
3169
// && pCmd->SurfInfo.height == pVga->height())
3171
VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.c.rgbBitCount,
3172
pCmd->SurfInfo.PixelFormat.m1.rgbRBitMask,
3173
pCmd->SurfInfo.PixelFormat.m2.rgbGBitMask,
3174
pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
3175
Assert(pVga->colorFormat().equals(format));
3176
// if(pVga->colorFormat().equals(format))
3180
surf->setDstBltCKey(pDstBltCKey);
3181
surf->setSrcBltCKey(pSrcBltCKey);
3183
surf->setDefaultDstOverlayCKey(pDstOverlayCKey);
3184
surf->resetDefaultDstOverlayCKey();
3186
surf->setDefaultSrcOverlayCKey(pDstOverlayCKey);
3187
surf->resetDefaultSrcOverlayCKey();
3188
// mbVGASurfCreated = true;
3194
else if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OFFSCREENPLAIN)
3201
if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
3203
VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.c.rgbBitCount,
3204
pCmd->SurfInfo.PixelFormat.m1.rgbRBitMask,
3205
pCmd->SurfInfo.PixelFormat.m2.rgbGBitMask,
3206
pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
3207
QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
3208
QRect primaryRect = mDisplay.getPrimary()->rect();
3209
surf = new VBoxVHWASurfaceBase(this, surfSize,
3210
// ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &surfSize),
3212
QRect(0, 0, surfSize.width(), surfSize.height()),
3215
pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
3216
#ifdef VBOXVHWA_USE_TEXGROUP
3221
else if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
3223
QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
3224
QRect primaryRect = mDisplay.getPrimary()->rect();
3226
VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.fourCC);
3227
surf = new VBoxVHWASurfaceBase(this, surfSize,
3228
// ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
3230
QRect(0, 0, surfSize.width(), surfSize.height()),
3233
pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
3234
#ifdef VBOXVHWA_USE_TEXGROUP
3242
VBOXQGLLOG_EXIT(("pSurf (0x%x)\n",surf));
3243
return VERR_GENERAL_FAILURE;
3246
uchar * addr = vboxVRAMAddressFromOffset(pCmd->SurfInfo.offSurface);
3247
surf->init(mDisplay.getPrimary(), addr);
3249
if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY)
3255
if(!mConstructingList)
3257
mConstructingList = new VBoxVHWASurfList();
3258
mcRemaining2Contruct = pCmd->SurfInfo.cBackBuffers+1;
3259
mDisplay.addOverlay(mConstructingList);
3262
mConstructingList->add(surf);
3263
mcRemaining2Contruct--;
3264
if(!mcRemaining2Contruct)
3266
mConstructingList = NULL;
3271
VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
3272
Assert(pVga->handle() != VBOXVHWA_SURFHANDLE_INVALID);
3273
Assert(pVga != surf); NOREF(pVga);
3274
// Assert(mbVGASurfCreated);
3275
mDisplay.getVGA()->getComplexList()->add(surf);
3276
#ifdef DEBUGVHWASTRICT
3277
Assert(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE);
3281
Assert(surf->getComplexList() == mDisplay.getVGA()->getComplexList());
3282
surf->getComplexList()->setCurrentVisible(surf);
3283
mDisplay.updateVGA(surf);
3288
Assert(mDisplay.getVGA() == mDisplay.getPrimary());
3290
/* tell the guest how we think the memory is organized */
3291
VBOXQGLLOG(("bps: %d\n", surf->bitsPerPixel()));
3293
pCmd->SurfInfo.pitch = surf->bitsPerPixel() * surf->width() / 8;
3294
pCmd->SurfInfo.sizeX = surf->memSize();
3295
pCmd->SurfInfo.sizeY = 1;
3297
if(handle != VBOXVHWA_SURFHANDLE_INVALID)
3299
bool bSuccess = mSurfHandleTable.mapPut(handle, surf);
3303
/* @todo: this is very bad, should not be here */
3304
return VERR_GENERAL_FAILURE;
3309
/* tell the guest our handle */
3310
handle = mSurfHandleTable.put(surf);
3311
pCmd->SurfInfo.hSurf = (VBOXVHWA_SURFHANDLE)handle;
3314
Assert(handle != VBOXVHWA_SURFHANDLE_INVALID);
3315
Assert(surf->handle() == VBOXVHWA_SURFHANDLE_INVALID);
3316
surf->setHandle(handle);
3317
Assert(surf->handle() == handle);
3319
VBOXQGLLOG_EXIT(("pSurf (0x%x)\n",surf));
3321
return VINF_SUCCESS;
3324
int VBoxGLWidget::vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd)
3326
VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
3327
VBoxVHWASurfList *pList = pSurf->getComplexList();
3328
Assert(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID);
3330
VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
3331
if(pList != mDisplay.getVGA()->getComplexList())
3334
pList->remove(pSurf);
3335
if(pList->surfaces().empty())
3337
mDisplay.removeOverlay(pList);
3338
// Assert(mConstructingList != pList);
3339
if(pList == mConstructingList)
3341
mConstructingList = NULL;
3342
mcRemaining2Contruct = 0;
3351
Assert(pList->size() >= 1);
3352
if(pList->size() > 1)
3354
if(pSurf == mDisplay.getVGA())
3356
const SurfList & surfaces = pList->surfaces();
3358
for (SurfList::const_iterator it = surfaces.begin();
3359
it != surfaces.end(); ++ it)
3361
VBoxVHWASurfaceBase *pCurSurf = (*it);
3362
if(pCurSurf != pSurf)
3364
mDisplay.updateVGA(pCurSurf);
3365
pList->setCurrentVisible(pCurSurf);
3371
pList->remove(pSurf);
3376
pSurf->setHandle(VBOXVHWA_SURFHANDLE_INVALID);
3380
/* just in case we destroy a visible overlay sorface */
3381
mRepaintNeeded = true;
3383
void * test = mSurfHandleTable.remove(pCmd->u.in.hSurf);
3384
Assert(test); NOREF(test);
3386
return VINF_SUCCESS;
3389
#define VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_RB(_pr) \
3390
QRect((_pr)->left, \
3392
(_pr)->right - (_pr)->left + 1, \
3393
(_pr)->bottom - (_pr)->top + 1)
3395
#define VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(_pr) \
3396
QRect((_pr)->left, \
3398
(_pr)->right - (_pr)->left, \
3399
(_pr)->bottom - (_pr)->top)
3401
int VBoxGLWidget::vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd)
3403
VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
3404
VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
3405
vboxCheckUpdateAddress (pSurf, pCmd->u.in.offSurface);
3406
if(pCmd->u.in.rectValid)
3408
QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.rect);
3409
return pSurf->lock(&r, pCmd->u.in.flags);
3411
return pSurf->lock(NULL, pCmd->u.in.flags);
3414
int VBoxGLWidget::vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd)
3416
VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
3418
/* for performance reasons we should receive unlock for visible surfaces only
3419
* other surfaces receive unlock only once becoming visible, e.g. on DdFlip
3420
* Ensure this is so*/
3421
if(pSurf != mDisplay.getPrimary())
3423
const OverlayList & overlays = mDisplay.overlays();
3424
bool bFound = false;
3426
if(!mDisplay.isPrimary(pSurf))
3428
for (OverlayList::const_iterator it = overlays.begin();
3429
it != overlays.end(); ++ it)
3431
VBoxVHWASurfList * pSurfList = *it;
3432
if(pSurfList->current() == pSurf)
3445
VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
3446
if(pCmd->u.in.xUpdatedMemValid)
3448
QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedMemRect);
3449
pSurf->updatedMem(&r);
3452
return pSurf->unlock();
3455
int VBoxGLWidget::vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd)
3458
return VERR_NOT_IMPLEMENTED;
3461
int VBoxGLWidget::vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd)
3463
VBoxVHWASurfaceBase *pTargSurf = handle2Surface(pCmd->u.in.hTargSurf);
3464
VBoxVHWASurfaceBase *pCurrSurf = handle2Surface(pCmd->u.in.hCurrSurf);
3465
VBOXQGLLOG_ENTER(("pTargSurf (0x%x), pCurrSurf (0x%x)\n",pTargSurf,pCurrSurf));
3466
vboxCheckUpdateAddress (pCurrSurf, pCmd->u.in.offCurrSurface);
3467
vboxCheckUpdateAddress (pTargSurf, pCmd->u.in.offTargSurface);
3470
if(pCmd->u.in.xUpdatedTargMemValid)
3472
QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedTargMemRect);
3473
pTargSurf->updatedMem(&r);
3475
pTargSurf->getComplexList()->setCurrentVisible(pTargSurf);
3477
mRepaintNeeded = true;
3479
pCurrSurf->cFlipsCurr++;
3480
pTargSurf->cFlipsTarg++;
3483
return VINF_SUCCESS;
3486
void VBoxGLWidget::vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd)
3488
/* get old values first to check whether we need to re-init display and program values */
3489
bool bHadSrcCKey = false, bHadDstCKey = false;
3493
bHadSrcCKey = !!(pSrcSurf->getActiveSrcOverlayCKey());
3494
bHadDstCKey = !!(pSrcSurf->getActiveDstOverlayCKey(pDstSurf));
3497
if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYDEST)
3499
VBOXQGLLOG((", KEYDEST"));
3500
/* we use src (overlay) surface to maintain overridden dst ckey info
3501
* to allow multiple overlays have different overridden dst keys for one primary surface */
3502
/* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
3503
* dst ckey value in defaultDstOverlayCKey
3504
* this allows the NULL to be a valid overridden value as well
3506
* 1. indicate the value is NUL overridden, just set NULL*/
3507
pSrcSurf->setOverriddenDstOverlayCKey(NULL);
3509
else if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYDESTOVERRIDE)
3511
VBOXQGLLOG((", KEYDESTOVERRIDE"));
3512
/* we use src (overlay) surface to maintain overridden dst ckey info
3513
* to allow multiple overlays have different overridden dst keys for one primary surface */
3514
/* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
3515
* dst ckey value in defaultDstOverlayCKey
3516
* this allows the NULL to be a valid overridden value as well
3518
* 1. indicate the value is overridden (no matter what we write here, bu it should be not NULL)*/
3519
VBoxVHWAColorKey ckey(pCmd->u.in.desc.DstCK.high, pCmd->u.in.desc.DstCK.low);
3520
VBOXQGLLOG_CKEY(" ckey: ",&ckey, "\n");
3521
pSrcSurf->setOverriddenDstOverlayCKey(&ckey);
3522
/* tell the ckey is enabled */
3523
pSrcSurf->setDefaultDstOverlayCKey(&ckey);
3527
VBOXQGLLOG((", no KEYDEST"));
3528
/* we use src (overlay) surface to maintain overridden dst ckey info
3529
* to allow multiple overlays have different overridden dst keys for one primary surface */
3530
/* non-null dstOverlayCKey for overlay would mean the overlay surface contains the overridden
3531
* dst ckey value in defaultDstOverlayCKey
3532
* this allows the NULL to be a valid overridden value as well
3534
* 1. indicate the value is overridden (no matter what we write here, bu it should be not NULL)*/
3535
VBoxVHWAColorKey dummyCKey(0, 0);
3536
pSrcSurf->setOverriddenDstOverlayCKey(&dummyCKey);
3537
/* tell the ckey is disabled */
3538
pSrcSurf->setDefaultDstOverlayCKey(NULL);
3541
if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYSRC)
3543
VBOXQGLLOG((", KEYSRC"));
3544
pSrcSurf->resetDefaultSrcOverlayCKey();
3546
else if(pCmd->u.in.flags & VBOXVHWA_OVER_KEYSRCOVERRIDE)
3548
VBOXQGLLOG((", KEYSRCOVERRIDE"));
3549
VBoxVHWAColorKey ckey(pCmd->u.in.desc.SrcCK.high, pCmd->u.in.desc.SrcCK.low);
3550
pSrcSurf->setOverriddenSrcOverlayCKey(&ckey);
3554
VBOXQGLLOG((", no KEYSRC"));
3555
pSrcSurf->setOverriddenSrcOverlayCKey(NULL);
3560
QRect dstRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.dstRect);
3561
QRect srcRect = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.srcRect);
3563
VBOXQGLLOG(("*******overlay update*******\n"));
3564
VBOXQGLLOG(("dstSurfSize: w(%d), h(%d)\n", pDstSurf->width(), pDstSurf->height()));
3565
VBOXQGLLOG(("srcSurfSize: w(%d), h(%d)\n", pSrcSurf->width(), pSrcSurf->height()));
3566
VBOXQGLLOG_QRECT("dstRect:", &dstRect, "\n");
3567
VBOXQGLLOG_QRECT("srcRect:", &srcRect, "\n");
3569
const VBoxVHWAColorKey *pResSrcCKey = pSrcSurf->getActiveSrcOverlayCKey();
3570
const VBoxVHWAColorKey *pResDstCKey = pSrcSurf->getActiveDstOverlayCKey(pDstSurf);
3572
if(bHadSrcCKey != !!pResSrcCKey || bHadDstCKey != !!pResDstCKey)
3574
pSrcSurf->setVisibilityReinitFlag();
3576
else if(pResSrcCKey || pResDstCKey)
3578
VBoxVHWAGlProgramVHWA *pProgram = pSrcSurf->getProgram(pDstSurf);
3584
VBoxVHWASurfaceBase::setCKey(pProgram, &pSrcSurf->colorFormat(), pResSrcCKey, false);
3588
VBoxVHWASurfaceBase::setCKey(pProgram, &pDstSurf->colorFormat(), pResDstCKey, true);
3594
pSrcSurf->setRects(dstRect, srcRect);
3599
int VBoxGLWidget::vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd)
3601
VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(pCmd->u.in.hSrcSurf);
3602
VBoxVHWASurfList *pList = pSrcSurf->getComplexList();
3603
vboxCheckUpdateAddress (pSrcSurf, pCmd->u.in.offSrcSurface);
3604
VBOXQGLLOG(("OverlayUpdate: pSrcSurf (0x%x)\n",pSrcSurf));
3605
VBoxVHWASurfaceBase *pDstSurf = NULL;
3607
if(pCmd->u.in.hDstSurf)
3609
pDstSurf = handle2Surface(pCmd->u.in.hDstSurf);
3610
vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
3611
VBOXQGLLOG(("pDstSurf (0x%x)\n",pDstSurf));
3612
#ifdef DEBUGVHWASTRICT
3613
Assert(pDstSurf == mDisplay.getVGA());
3614
Assert(mDisplay.getVGA() == mDisplay.getPrimary());
3616
Assert(pDstSurf->getComplexList() == mDisplay.getVGA()->getComplexList());
3618
if(pCmd->u.in.flags & VBOXVHWA_OVER_SHOW)
3620
if(pDstSurf != mDisplay.getPrimary())
3622
mDisplay.updateVGA(pDstSurf);
3623
pDstSurf->getComplexList()->setCurrentVisible(pDstSurf);
3628
const SurfList & surfaces = pList->surfaces();
3630
for (SurfList::const_iterator it = surfaces.begin();
3631
it != surfaces.end(); ++ it)
3633
VBoxVHWASurfaceBase *pCurSrcSurf = (*it);
3634
vhwaDoSurfaceOverlayUpdate(pDstSurf, pCurSrcSurf, pCmd);
3637
if(pCmd->u.in.flags & VBOXVHWA_OVER_HIDE)
3639
VBOXQGLLOG(("hide\n"));
3640
pList->setCurrentVisible(NULL);
3642
else if(pCmd->u.in.flags & VBOXVHWA_OVER_SHOW)
3644
VBOXQGLLOG(("show\n"));
3645
pList->setCurrentVisible(pSrcSurf);
3648
mRepaintNeeded = true;
3650
return VINF_SUCCESS;
3653
int VBoxGLWidget::vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd)
3655
VBoxVHWASurfaceBase *pDstSurf = handle2Surface(pCmd->u.in.hDstSurf);
3656
VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(pCmd->u.in.hSrcSurf);
3658
VBOXQGLLOG_ENTER(("pDstSurf (0x%x), pSrcSurf (0x%x)\n",pDstSurf,pSrcSurf));
3660
vboxCheckUpdateAddress (pSrcSurf, pCmd->u.in.offSrcSurface);
3661
vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
3663
VBoxVHWASurfList *pList = pSrcSurf->getComplexList();
3664
const SurfList & surfaces = pList->surfaces();
3666
QPoint pos(pCmd->u.in.xPos, pCmd->u.in.yPos);
3668
#ifdef DEBUGVHWASTRICT
3669
Assert(pDstSurf == mDisplay.getVGA());
3670
Assert(mDisplay.getVGA() == mDisplay.getPrimary());
3672
if(pSrcSurf->getComplexList()->current() != NULL)
3675
if(pDstSurf != mDisplay.getPrimary())
3677
mDisplay.updateVGA(pDstSurf);
3678
pDstSurf->getComplexList()->setCurrentVisible(pDstSurf);
3682
mRepaintNeeded = true;
3684
for (SurfList::const_iterator it = surfaces.begin();
3685
it != surfaces.end(); ++ it)
3687
VBoxVHWASurfaceBase *pCurSrcSurf = (*it);
3688
pCurSrcSurf->setTargRectPosition(pos);
3691
return VINF_SUCCESS;
3694
int VBoxGLWidget::vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd)
3696
VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
3698
VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
3700
vboxCheckUpdateAddress (pSurf, pCmd->u.in.offSurface);
3702
mRepaintNeeded = true;
3704
// VBOXVHWA_CKEY_COLORSPACE
3705
if(pCmd->u.in.flags & VBOXVHWA_CKEY_DESTBLT)
3707
VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
3708
pSurf->setDstBltCKey(&ckey);
3710
if(pCmd->u.in.flags & VBOXVHWA_CKEY_DESTOVERLAY)
3712
VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
3713
pSurf->setDefaultDstOverlayCKey(&ckey);
3715
if(pCmd->u.in.flags & VBOXVHWA_CKEY_SRCBLT)
3717
VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
3718
pSurf->setSrcBltCKey(&ckey);
3720
if(pCmd->u.in.flags & VBOXVHWA_CKEY_SRCOVERLAY)
3722
VBoxVHWAColorKey ckey(pCmd->u.in.CKey.high, pCmd->u.in.CKey.low);
3723
pSurf->setDefaultSrcOverlayCKey(&ckey);
3726
/* ensure all overlays programs & display lists are updated */
3727
const OverlayList & overlays = mDisplay.overlays();
3728
for (OverlayList::const_iterator it = overlays.begin();
3729
it != overlays.end(); ++ it)
3731
VBoxVHWASurfList * pSurfList = *it;
3732
const SurfList & surfaces = pSurfList->surfaces();
3733
for (SurfList::const_iterator sit = surfaces.begin();
3734
sit != surfaces.end(); ++ sit)
3736
VBoxVHWASurfaceBase *pOverlaySurf = *sit;
3737
pOverlaySurf->setVisibilityReinitFlag();
3740
return VINF_SUCCESS;
3743
int VBoxGLWidget::vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd)
3745
VBOXQGLLOG_ENTER(("\n"));
3746
bool bEnabled = false;
3747
const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
3748
if(info.isVHWASupported())
3750
Assert(pCmd->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ);
3751
if(pCmd->u.in.guestVersion.maj == VBOXVHWA_VERSION_MAJ)
3753
Assert(pCmd->u.in.guestVersion.min == VBOXVHWA_VERSION_MIN);
3754
if(pCmd->u.in.guestVersion.min == VBOXVHWA_VERSION_MIN)
3756
Assert(pCmd->u.in.guestVersion.bld == VBOXVHWA_VERSION_BLD);
3757
if(pCmd->u.in.guestVersion.bld == VBOXVHWA_VERSION_BLD)
3759
Assert(pCmd->u.in.guestVersion.reserved == VBOXVHWA_VERSION_RSV);
3760
if(pCmd->u.in.guestVersion.reserved == VBOXVHWA_VERSION_RSV)
3769
memset(pCmd, 0, sizeof(VBOXVHWACMD_QUERYINFO1));
3772
pCmd->u.out.cfgFlags = VBOXVHWA_CFG_ENABLED;
3775
// VBOXVHWA_CAPS_BLT | VBOXVHWA_CAPS_BLTSTRETCH | VBOXVHWA_CAPS_BLTQUEUE
3776
// // | VBOXVHWA_CAPS_BLTCOLORFILL not supported, although adding it is trivial
3777
// // | VBOXVHWA_CAPS_BLTFOURCC set below if shader support is available
3778
VBOXVHWA_CAPS_OVERLAY
3779
| VBOXVHWA_CAPS_OVERLAYSTRETCH
3780
| VBOXVHWA_CAPS_OVERLAYCANTCLIP
3781
// | VBOXVHWA_CAPS_OVERLAYFOURCC set below if shader support is available
3784
pCmd->u.out.caps2 = VBOXVHWA_CAPS2_CANRENDERWINDOWED
3785
| VBOXVHWA_CAPS2_WIDESURFACES;
3787
//TODO: setup stretchCaps
3788
pCmd->u.out.stretchCaps = 0;
3790
pCmd->u.out.numOverlays = 1;
3791
/* TODO: set curOverlays properly */
3792
pCmd->u.out.curOverlays = 0;
3794
pCmd->u.out.surfaceCaps =
3795
VBOXVHWA_SCAPS_PRIMARYSURFACE
3796
#ifndef VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY
3797
| VBOXVHWA_SCAPS_OFFSCREENPLAIN
3799
| VBOXVHWA_SCAPS_FLIP
3800
| VBOXVHWA_SCAPS_LOCALVIDMEM
3801
| VBOXVHWA_SCAPS_OVERLAY
3802
// | VBOXVHWA_SCAPS_BACKBUFFER
3803
// | VBOXVHWA_SCAPS_FRONTBUFFER
3804
// | VBOXVHWA_SCAPS_VIDEOMEMORY
3805
// | VBOXVHWA_SCAPS_COMPLEX
3806
// | VBOXVHWA_SCAPS_VISIBLE
3809
if(info.getGlInfo().isFragmentShaderSupported() && info.getGlInfo().getMultiTexNumSupported() >= 2)
3811
pCmd->u.out.caps |= VBOXVHWA_CAPS_COLORKEY
3812
| VBOXVHWA_CAPS_COLORKEYHWASSIST
3815
pCmd->u.out.colorKeyCaps =
3816
// VBOXVHWA_CKEYCAPS_DESTBLT | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE | VBOXVHWA_CKEYCAPS_SRCBLT| VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE |
3817
// VBOXVHWA_CKEYCAPS_SRCOVERLAY | VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE |
3818
VBOXVHWA_CKEYCAPS_DESTOVERLAY |
3819
VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE;
3822
if(info.getGlInfo().isTextureRectangleSupported())
3824
pCmd->u.out.caps |= VBOXVHWA_CAPS_OVERLAYFOURCC
3825
// | VBOXVHWA_CAPS_BLTFOURCC
3828
pCmd->u.out.colorKeyCaps |=
3829
// VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV |
3830
VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV;
3833
// pCmd->u.out.caps2 |= VBOXVHWA_CAPS2_COPYFOURCC;
3835
pCmd->u.out.numFourCC = info.getFourccSupportedCount();
3840
return VINF_SUCCESS;
3843
int VBoxGLWidget::vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd)
3845
VBOXQGLLOG_ENTER(("\n"));
3847
const VBoxVHWAInfo & info = vboxVHWAGetSupportInfo(context());
3849
Assert(pCmd->numFourCC >= (uint32_t)info.getFourccSupportedCount());
3850
if(pCmd->numFourCC < (uint32_t)info.getFourccSupportedCount())
3851
return VERR_GENERAL_FAILURE;
3853
pCmd->numFourCC = (uint32_t)info.getFourccSupportedCount();
3854
for(int i = 0; i < info.getFourccSupportedCount(); i++)
3856
pCmd->FourCC[i] = info.getFourccSupportedList()[i];
3858
return VINF_SUCCESS;
3861
static DECLCALLBACK(void) vboxQGLSaveExec(PSSMHANDLE pSSM, void *pvUser)
3863
VBoxGLWidget * pw = (VBoxGLWidget*)pvUser;
3864
pw->vhwaSaveExec(pSSM);
3867
static DECLCALLBACK(int) vboxQGLLoadExec(PSSMHANDLE pSSM, void *pvUser, uint32_t u32Version, uint32_t uPass)
3869
Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
3870
VBoxGLWidget * pw = (VBoxGLWidget*)pvUser;
3871
return VBoxGLWidget::vhwaLoadExec(&pw->onResizeCmdList(), pSSM, u32Version);
3874
int VBoxGLWidget::vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps)
3876
VBOXQGL_SAVE_SURFSTART(pSSM);
3878
uint64_t u64 = vboxVRAMOffset(pSurf);
3880
rc = SSMR3PutU32(pSSM, pSurf->handle()); AssertRC(rc);
3881
rc = SSMR3PutU64(pSSM, u64); AssertRC(rc);
3882
rc = SSMR3PutU32(pSSM, pSurf->width()); AssertRC(rc);
3883
rc = SSMR3PutU32(pSSM, pSurf->height()); AssertRC(rc);
3884
rc = SSMR3PutU32(pSSM, surfCaps); AssertRC(rc);
3886
const VBoxVHWAColorKey * pDstBltCKey = pSurf->dstBltCKey();
3887
const VBoxVHWAColorKey * pSrcBltCKey = pSurf->srcBltCKey();
3888
const VBoxVHWAColorKey * pDstOverlayCKey = pSurf->dstOverlayCKey();
3889
const VBoxVHWAColorKey * pSrcOverlayCKey = pSurf->srcOverlayCKey();
3892
flags |= VBOXVHWA_SD_CKDESTBLT;
3896
flags |= VBOXVHWA_SD_CKSRCBLT;
3900
flags |= VBOXVHWA_SD_CKDESTOVERLAY;
3904
flags |= VBOXVHWA_SD_CKSRCOVERLAY;
3907
rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
3910
rc = SSMR3PutU32(pSSM, pDstBltCKey->lower()); AssertRC(rc);
3911
rc = SSMR3PutU32(pSSM, pDstBltCKey->upper()); AssertRC(rc);
3915
rc = SSMR3PutU32(pSSM, pSrcBltCKey->lower()); AssertRC(rc);
3916
rc = SSMR3PutU32(pSSM, pSrcBltCKey->upper()); AssertRC(rc);
3920
rc = SSMR3PutU32(pSSM, pDstOverlayCKey->lower()); AssertRC(rc);
3921
rc = SSMR3PutU32(pSSM, pDstOverlayCKey->upper()); AssertRC(rc);
3925
rc = SSMR3PutU32(pSSM, pSrcOverlayCKey->lower()); AssertRC(rc);
3926
rc = SSMR3PutU32(pSSM, pSrcOverlayCKey->upper()); AssertRC(rc);
3929
const VBoxVHWAColorFormat & format = pSurf->colorFormat();
3933
flags |= VBOXVHWA_PF_FOURCC;
3934
rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
3935
rc = SSMR3PutU32(pSSM, format.fourcc()); AssertRC(rc);
3939
flags |= VBOXVHWA_PF_RGB;
3940
rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
3941
rc = SSMR3PutU32(pSSM, format.bitsPerPixel()); AssertRC(rc);
3942
rc = SSMR3PutU32(pSSM, format.r().mask()); AssertRC(rc);
3943
rc = SSMR3PutU32(pSSM, format.g().mask()); AssertRC(rc);
3944
rc = SSMR3PutU32(pSSM, format.b().mask()); AssertRC(rc);
3945
rc = SSMR3PutU32(pSSM, format.a().mask()); AssertRC(rc);
3948
VBOXQGL_SAVE_SURFSTOP(pSSM);
3953
int VBoxGLWidget::vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t cBackBuffers, uint32_t u32Version)
3955
Q_UNUSED(u32Version);
3957
VBOXQGL_LOAD_SURFSTART(pSSM);
3959
char *buf = (char*)malloc(VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE));
3960
memset(buf, 0, sizeof(VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE)));
3961
VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
3962
pCmd->enmCmd = VBOXVHWACMD_TYPE_SURF_CREATE;
3963
pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
3965
VBOXVHWACMD_SURF_CREATE * pCreateSurf = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
3968
rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
3969
pCreateSurf->SurfInfo.hSurf = (VBOXVHWA_SURFHANDLE)u32;
3972
rc = SSMR3GetU64(pSSM, &pCreateSurf->SurfInfo.offSurface); AssertRC(rc);
3973
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.width); AssertRC(rc);
3974
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.height); AssertRC(rc);
3975
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.surfCaps); AssertRC(rc);
3976
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.flags); AssertRC(rc);
3977
if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKDESTBLT)
3979
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstBltCK.low); AssertRC(rc);
3980
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstBltCK.high); AssertRC(rc);
3982
if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKSRCBLT)
3984
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcBltCK.low); AssertRC(rc);
3985
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcBltCK.high); AssertRC(rc);
3987
if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKDESTOVERLAY)
3989
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstOverlayCK.low); AssertRC(rc);
3990
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.DstOverlayCK.high); AssertRC(rc);
3992
if(pCreateSurf->SurfInfo.flags & VBOXVHWA_SD_CKSRCOVERLAY)
3994
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcOverlayCK.low); AssertRC(rc);
3995
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.SrcOverlayCK.high); AssertRC(rc);
3998
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.flags); AssertRC(rc);
3999
if(pCreateSurf->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
4001
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.c.rgbBitCount); AssertRC(rc);
4002
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m1.rgbRBitMask); AssertRC(rc);
4003
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m2.rgbGBitMask); AssertRC(rc);
4004
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m3.rgbBBitMask); AssertRC(rc);
4005
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.m4.rgbABitMask); AssertRC(rc);
4007
else if(pCreateSurf->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_FOURCC)
4009
rc = SSMR3GetU32(pSSM, &pCreateSurf->SurfInfo.PixelFormat.fourCC); AssertRC(rc);
4018
pCreateSurf->SurfInfo.cBackBuffers = cBackBuffers;
4019
pCreateSurf->SurfInfo.surfCaps |= VBOXVHWA_SCAPS_COMPLEX;
4022
pCmdList->push_back(pCmd);
4023
// vboxExecOnResize(&VBoxGLWidget::vboxDoVHWACmdAndFree, pCmd); AssertRC(rc);
4024
// if(RT_SUCCESS(rc))
4031
VBOXQGL_LOAD_SURFSTOP(pSSM);
4036
int VBoxGLWidget::vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible)
4038
VBOXQGL_SAVE_OVERLAYSTART(pSSM);
4041
const VBoxVHWAColorKey * dstCKey = pSurf->dstOverlayCKey();
4042
const VBoxVHWAColorKey * defaultDstCKey = pSurf->defaultDstOverlayCKey();
4043
const VBoxVHWAColorKey * srcCKey = pSurf->srcOverlayCKey();;
4044
const VBoxVHWAColorKey * defaultSrcCKey = pSurf->defaultSrcOverlayCKey();
4045
bool bSaveDstCKey = false;
4046
bool bSaveSrcCKey = false;
4050
flags |= VBOXVHWA_OVER_SHOW;
4054
flags |= VBOXVHWA_OVER_HIDE;
4059
flags |= VBOXVHWA_OVER_KEYDEST;
4061
else if(defaultDstCKey)
4063
flags |= VBOXVHWA_OVER_KEYDESTOVERRIDE;
4064
bSaveDstCKey = true;
4067
if(srcCKey == defaultSrcCKey)
4069
flags |= VBOXVHWA_OVER_KEYSRC;
4073
flags |= VBOXVHWA_OVER_KEYSRCOVERRIDE;
4074
bSaveSrcCKey = true;
4077
int rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
4079
rc = SSMR3PutU32(pSSM, mDisplay.getPrimary()->handle()); AssertRC(rc);
4080
rc = SSMR3PutU32(pSSM, pSurf->handle()); AssertRC(rc);
4084
rc = SSMR3PutU32(pSSM, dstCKey->lower()); AssertRC(rc);
4085
rc = SSMR3PutU32(pSSM, dstCKey->upper()); AssertRC(rc);
4089
rc = SSMR3PutU32(pSSM, srcCKey->lower()); AssertRC(rc);
4090
rc = SSMR3PutU32(pSSM, srcCKey->upper()); AssertRC(rc);
4094
pSurf->targRect().getCoords(&x1, &y1, &x2, &y2);
4095
rc = SSMR3PutS32(pSSM, x1); AssertRC(rc);
4096
rc = SSMR3PutS32(pSSM, x2+1); AssertRC(rc);
4097
rc = SSMR3PutS32(pSSM, y1); AssertRC(rc);
4098
rc = SSMR3PutS32(pSSM, y2+1); AssertRC(rc);
4100
pSurf->srcRect().getCoords(&x1, &y1, &x2, &y2);
4101
rc = SSMR3PutS32(pSSM, x1); AssertRC(rc);
4102
rc = SSMR3PutS32(pSSM, x2+1); AssertRC(rc);
4103
rc = SSMR3PutS32(pSSM, y1); AssertRC(rc);
4104
rc = SSMR3PutS32(pSSM, y2+1); AssertRC(rc);
4106
VBOXQGL_SAVE_OVERLAYSTOP(pSSM);
4111
int VBoxGLWidget::vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version)
4113
Q_UNUSED(u32Version);
4115
VBOXQGL_LOAD_OVERLAYSTART(pSSM);
4117
// char buf[VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_OVERLAY_UPDATE)];
4118
char *buf = new char[VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE)];
4119
memset(buf, 0, VBOXVHWACMD_SIZE(VBOXVHWACMD_SURF_CREATE));
4120
VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
4121
pCmd->enmCmd = VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE;
4122
pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
4124
VBOXVHWACMD_SURF_OVERLAY_UPDATE * pUpdateOverlay = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
4127
rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.flags); AssertRC(rc);
4128
uint32_t hSrc, hDst;
4129
rc = SSMR3GetU32(pSSM, &hDst); AssertRC(rc);
4130
rc = SSMR3GetU32(pSSM, &hSrc); AssertRC(rc);
4131
pUpdateOverlay->u.in.hSrcSurf = hSrc;
4132
pUpdateOverlay->u.in.hDstSurf = hDst;
4133
// Assert(hDst == mDisplay.getVGA()->handle());
4134
// VBoxVHWASurfaceBase *pDstSurf = handle2Surface(hDst);
4135
// VBoxVHWASurfaceBase *pSrcSurf = handle2Surface(hSrc);
4136
// Assert(pSrcSurf);
4137
// Assert(pDstSurf);
4138
// if(pSrcSurf && pDstSurf)
4140
pUpdateOverlay->u.in.offDstSurface = VBOXVHWA_OFFSET64_VOID;
4141
// vboxVRAMOffset(pDstSurf);
4142
pUpdateOverlay->u.in.offSrcSurface = VBOXVHWA_OFFSET64_VOID;
4143
// vboxVRAMOffset(pSrcSurf);
4145
if(pUpdateOverlay->u.in.flags & VBOXVHWA_OVER_KEYDESTOVERRIDE)
4147
rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.DstCK.low); AssertRC(rc);
4148
rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.DstCK.high); AssertRC(rc);
4151
if(pUpdateOverlay->u.in.flags & VBOXVHWA_OVER_KEYSRCOVERRIDE)
4153
rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.SrcCK.low); AssertRC(rc);
4154
rc = SSMR3GetU32(pSSM, &pUpdateOverlay->u.in.desc.SrcCK.high); AssertRC(rc);
4157
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.left); AssertRC(rc);
4158
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.right); AssertRC(rc);
4159
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.top); AssertRC(rc);
4160
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.dstRect.bottom); AssertRC(rc);
4162
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.left); AssertRC(rc);
4163
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.right); AssertRC(rc);
4164
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.top); AssertRC(rc);
4165
rc = SSMR3GetS32(pSSM, &pUpdateOverlay->u.in.srcRect.bottom); AssertRC(rc);
4167
pCmdList->push_back(pCmd);
4168
// vboxExecOnResize(&VBoxGLWidget::vboxDoVHWACmdAndFree, pCmd); AssertRC(rc);
4169
// if(RT_SUCCESS(rc))
4177
// rc = VERR_GENERAL_FAILURE;
4180
VBOXQGL_LOAD_OVERLAYSTOP(pSSM);
4185
void VBoxGLWidget::vhwaSaveExecVoid(struct SSMHANDLE * pSSM)
4187
VBOXQGL_SAVE_START(pSSM);
4188
int rc = SSMR3PutU32(pSSM, 0); AssertRC(rc); /* 0 primaries */
4189
VBOXQGL_SAVE_STOP(pSSM);
4192
void VBoxGLWidget::vhwaSaveExec(struct SSMHANDLE * pSSM)
4194
VBOXQGL_SAVE_START(pSSM);
4196
/* the mechanism of restoring data is based on generating VHWA commands that restore the surfaces state
4197
* the following commands are generated:
4201
* Data format is the following:
4202
* I. u32 - Num primary surfaces - (the current frontbuffer is detected in the stored surf flags which are posted to the generated CreateSurface cmd)
4203
* II. for each primary surf
4204
* II.1 generate & execute CreateSurface cmd (see below on the generation logic)
4205
* III. u32 - Num overlays
4206
* IV. for each overlay
4207
* 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)
4208
* IV.2 for each surface in overlay
4209
* IV.2.a generate & execute CreateSurface cmd (see below on the generation logic)
4210
* IV.2.b generate & execute UpdateOverlay cmd (see below on the generation logic)
4213
const SurfList & primaryList = mDisplay.primaries().surfaces();
4214
uint32_t cPrimary = (uint32_t)primaryList.size();
4216
(mDisplay.getVGA() == NULL || mDisplay.getVGA()->handle() == VBOXVHWA_SURFHANDLE_INVALID))
4221
int rc = SSMR3PutU32(pSSM, cPrimary); AssertRC(rc);
4224
for (SurfList::const_iterator pr = primaryList.begin();
4225
pr != primaryList.end(); ++ pr)
4227
VBoxVHWASurfaceBase *pSurf = *pr;
4228
// bool bVga = (pSurf == mDisplay.getVGA());
4229
bool bVisible = (pSurf == mDisplay.getPrimary());
4230
uint32_t flags = VBOXVHWA_SCAPS_PRIMARYSURFACE;
4232
flags |= VBOXVHWA_SCAPS_VISIBLE;
4234
if(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID)
4236
rc = vhwaSaveSurface(pSSM, *pr, flags); AssertRC(rc);
4239
Assert(cPrimary < UINT32_MAX / 2);
4244
Assert(pSurf == mDisplay.getVGA());
4252
const OverlayList & overlays = mDisplay.overlays();
4253
rc = SSMR3PutU32(pSSM, (uint32_t)overlays.size()); AssertRC(rc);
4255
for (OverlayList::const_iterator it = overlays.begin();
4256
it != overlays.end(); ++ it)
4258
VBoxVHWASurfList * pSurfList = *it;
4259
const SurfList & surfaces = pSurfList->surfaces();
4260
uint32_t cSurfs = (uint32_t)surfaces.size();
4261
uint32_t flags = VBOXVHWA_SCAPS_OVERLAY;
4263
flags |= VBOXVHWA_SCAPS_COMPLEX;
4264
rc = SSMR3PutU32(pSSM, cSurfs); AssertRC(rc);
4265
for (SurfList::const_iterator sit = surfaces.begin();
4266
sit != surfaces.end(); ++ sit)
4268
rc = vhwaSaveSurface(pSSM, *sit, flags); AssertRC(rc);
4271
bool bVisible = true;
4272
VBoxVHWASurfaceBase * pOverlayData = pSurfList->current();
4275
pOverlayData = surfaces.front();
4279
rc = vhwaSaveOverlayData(pSSM, pOverlayData, bVisible); AssertRC(rc);
4283
VBOXQGL_SAVE_STOP(pSSM);
4286
int VBoxGLWidget::vhwaLoadVHWAEnable(VHWACommandList * pCmdList)
4288
char *buf = (char*)malloc(sizeof(VBOXVHWACMD));
4292
memset(buf, 0, sizeof(VBOXVHWACMD));
4293
VBOXVHWACMD * pCmd = (VBOXVHWACMD*)buf;
4294
pCmd->enmCmd = VBOXVHWACMD_TYPE_ENABLE;
4295
pCmd->Flags = VBOXVHWACMD_FLAG_HH_CMD;
4296
pCmdList->push_back(pCmd);
4297
return VINF_SUCCESS;
4300
return VERR_OUT_OF_RESOURCES;
4303
int VBoxGLWidget::vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version)
4305
VBOXQGL_LOAD_START(pSSM);
4307
if(u32Version > VBOXQGL_STATE_VERSION)
4308
return VERR_VERSION_MISMATCH;
4313
rc = vhwaLoadVHWAEnable(pCmdList); AssertRC(rc);
4316
rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
4319
if(u32Version == 1 && u32 == (~0)) /* work around the v1 bug */
4323
for(uint32_t i = 0; i < u32; ++i)
4325
rc = vhwaLoadSurface(pCmdList, pSSM, 0, u32Version); AssertRC(rc);
4332
rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
4335
for(uint32_t i = 0; i < u32; ++i)
4338
rc = SSMR3GetU32(pSSM, &cSurfs); AssertRC(rc);
4339
for(uint32_t j = 0; j < cSurfs; ++j)
4341
rc = vhwaLoadSurface(pCmdList, pSSM, cSurfs - 1, u32Version); AssertRC(rc);
4348
rc = vhwaLoadOverlayData(pCmdList, pSSM, u32Version); AssertRC(rc);
4359
#ifdef VBOXQGL_STATE_DEBUG
4360
else if(u32Version == 1) /* read the 0 overlay count to ensure the following VBOXQGL_LOAD_STOP succeedes */
4362
rc = SSMR3GetU32(pSSM, &u32); AssertRC(rc);
4369
VBOXQGL_LOAD_STOP(pSSM);
4374
int VBoxGLWidget::vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd)
4376
PVM pVM = (PVM)pCmd->pVM;
4377
uint32_t intsId = 0; /* @todo: set the proper id */
4379
char nameFuf[sizeof(VBOXQGL_STATE_NAMEBASE) + 8];
4381
char * pszName = nameFuf;
4382
sprintf(pszName, "%s%d", VBOXQGL_STATE_NAMEBASE, intsId);
4383
int rc = SSMR3RegisterExternal(
4384
pVM, /* The VM handle*/
4385
pszName, /* Data unit name. */
4386
intsId, /* The instance identifier of the data unit.
4387
* This must together with the name be unique. */
4388
VBOXQGL_STATE_VERSION, /* Data layout version number. */
4389
128, /* The approximate amount of data in the unit.
4390
* Only for progress indicators. */
4391
NULL, NULL, NULL, /* pfnLiveXxx */
4392
NULL, /* Prepare save callback, optional. */
4393
vboxQGLSaveExec, /* Execute save callback, optional. */
4394
NULL, /* Done save callback, optional. */
4395
NULL, /* Prepare load callback, optional. */
4396
vboxQGLLoadExec, /* Execute load callback, optional. */
4397
NULL, /* Done load callback, optional. */
4398
this /* User argument. */
4400
Assert(RT_SUCCESS(rc));
4404
uchar * VBoxGLWidget::vboxVRAMAddressFromOffset(uint64_t offset)
4406
return ((offset != VBOXVHWA_OFFSET64_VOID) && vboxUsesGuestVRAM()) ? vboxAddress() + offset : NULL;
4409
uint64_t VBoxGLWidget::vboxVRAMOffsetFromAddress(uchar* addr)
4411
return uint64_t(addr - vboxAddress());
4414
uint64_t VBoxGLWidget::vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf)
4416
return pSurf->addressAlocated() ? VBOXVHWA_OFFSET64_VOID : vboxVRAMOffsetFromAddress(pSurf->address());
4421
void VBoxGLWidget::initializeGL()
4423
vboxVHWAGetSupportInfo(context());
4424
VBoxVHWASurfaceBase::globalInit();
4427
#ifdef VBOXQGL_DBG_SURF
4430
VBoxVHWASurfaceBase * g_apSurf[] = {NULL, NULL, NULL};
4432
void VBoxGLWidget::vboxDoTestSurfaces(void* context)
4434
// uint32_t width = 103;
4435
// uint32_t height = 47;
4436
// uint32_t rgbBitCount = 32;
4437
// uint32_t r = 0xff, g = 0xff00, b = 0xff0000;
4438
// QRect dstRect(10, 50, width, height);
4439
// QRect srcRect(0, 0, width, height);
4444
//// pSurf1 = new VBoxVHWASurfaceBase(this, width, height,
4445
//// VBoxVHWAColorFormat(rgbBitCount,
4449
//// NULL, NULL, NULL, NULL);
4450
// pSurf1 = new VBoxVHWASurfaceBase(this, &QSize(width, height),
4451
//// ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
4452
// &mDisplay.getPrimary()->rect().size(),
4453
// VBoxVHWAColorFormat(rgbBitCount,
4457
//// pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey);
4458
// NULL, NULL, NULL, NULL);
4460
// pSurf1->init(mDisplay.getVGA(), NULL);
4462
// VBoxVHWASurfList *pConstructingList = new VBoxVHWASurfList();
4463
// mDisplay.addOverlay(pConstructingList);
4464
// pConstructingList->add(pSurf1);
4465
// pConstructingList->setCurrentVisible(pSurf1);
4466
//// pSurf1->performDisplay();
4469
//// pDisplay->blt(&dstRect, pSurf1, &srcRect, NULL, NULL);
4470
//// pDisplay->performDisplay();
4471
if(g_iCur >= RT_ELEMENTS(g_apSurf))
4473
VBoxVHWASurfaceBase * pSurf1 = g_apSurf[g_iCur];
4476
pSurf1->getComplexList()->setCurrentVisible(pSurf1);
4481
void VBoxGLWidget::vboxDoUpdateViewport(const QRect & aRect)
4483
adjustViewport(mDisplay.getPrimary()->size(), aRect);
4486
const SurfList & primaryList = mDisplay.primaries().surfaces();
4488
for (SurfList::const_iterator pr = primaryList.begin();
4489
pr != primaryList.end(); ++ pr)
4491
VBoxVHWASurfaceBase *pSurf = *pr;
4492
pSurf->updateVisibility(NULL, aRect, false, false);
4495
const OverlayList & overlays = mDisplay.overlays();
4496
QRect overInter = overlaysRectIntersection();
4497
overInter = overInter.intersect(aRect);
4499
bool bDisplayPrimary = true;
4501
for (OverlayList::const_iterator it = overlays.begin();
4502
it != overlays.end(); ++ it)
4504
VBoxVHWASurfList * pSurfList = *it;
4505
const SurfList & surfaces = pSurfList->surfaces();
4508
bool bNotIntersected = !overInter.isEmpty() && surfaces.front()->targRect().contains(overInter);
4509
Assert(bNotIntersected);
4511
bDisplayPrimary &= !bNotIntersected;
4512
for (SurfList::const_iterator sit = surfaces.begin();
4513
sit != surfaces.end(); ++ sit)
4515
VBoxVHWASurfaceBase *pSurf = *sit;
4516
pSurf->updateVisibility(mDisplay.getPrimary(), aRect, bNotIntersected, false);
4521
Assert(!bDisplayPrimary);
4522
mDisplay.setDisplayPrimary(bDisplayPrimary);
4525
bool VBoxGLWidget::hasSurfaces() const
4527
if(mDisplay.overlays().size() != 0)
4529
if(mDisplay.primaries().size() > 1)
4531
return mDisplay.getVGA()->handle() != VBOXVHWA_SURFHANDLE_INVALID;
4534
bool VBoxGLWidget::hasVisibleOverlays()
4536
const OverlayList & overlays = mDisplay.overlays();
4537
for (OverlayList::const_iterator it = overlays.begin();
4538
it != overlays.end(); ++ it)
4540
VBoxVHWASurfList * pSurfList = *it;
4541
if(pSurfList->current() != NULL)
4547
QRect VBoxGLWidget::overlaysRectUnion()
4549
const OverlayList & overlays = mDisplay.overlays();
4550
VBoxVHWADirtyRect un;
4551
for (OverlayList::const_iterator it = overlays.begin();
4552
it != overlays.end(); ++ it)
4554
VBoxVHWASurfaceBase * pOverlay = (*it)->current();
4555
if(pOverlay != NULL)
4557
un.add(pOverlay->targRect());
4563
QRect VBoxGLWidget::overlaysRectIntersection()
4565
const OverlayList & overlays = mDisplay.overlays();
4567
VBoxVHWADirtyRect un;
4568
for (OverlayList::const_iterator it = overlays.begin();
4569
it != overlays.end(); ++ it)
4571
VBoxVHWASurfaceBase * pOverlay = (*it)->current();
4572
if(pOverlay != NULL)
4576
rect = pOverlay->targRect();
4580
rect = rect.intersected(pOverlay->targRect());
4589
//void VBoxGLWidget::vboxDoPaint(void *pe)
4593
//#ifdef VBOXQGL_DBG_SURF
4594
// vboxDoTestSurfaces(NULL);
4596
////#ifdef VBOXQGL_PROF_BASE
4597
//// vboxDoUpdateRect(&((QPaintEvent*)pe)->rect());
4599
//// mDisplay.performDisplay();
4602
void VBoxGLWidget::vboxDoUpdateRect(const QRect * pRect)
4604
mDisplay.getPrimary()->updatedMem(pRect);
4607
void VBoxGLWidget::vboxDoResize(void *resize)
4609
// Assert(!format().accum());
4610
// Assert(format().alpha());
4611
// Assert(format().alphaBufferSize() == 8);
4612
VBOXQGLLOG(("format().blueBufferSize()(%d)\n", format().blueBufferSize()));
4613
VBOXQGLLOG(("format().greenBufferSize()(%d)\n", format().greenBufferSize()));
4614
VBOXQGLLOG(("format().redBufferSize()(%d)\n", format().redBufferSize()));
4616
Assert(format().blueBufferSize() == 8);
4617
Assert(format().greenBufferSize() == 8);
4618
Assert(format().redBufferSize() == 8);
4621
// Assert(!format().depth());
4622
Assert(format().directRendering());
4623
Assert(format().doubleBuffer());
4624
Assert(format().hasOpenGL());
4625
VBOXQGLLOG(("hasOpenGLOverlays(%d), hasOverlay(%d)\n", format().hasOpenGLOverlays(), format().hasOverlay()));
4626
// Assert(format().hasOpenGLOverlays());
4627
// Assert(format().hasOverlay());
4628
Assert(format().plane() == 0);
4629
Assert(format().rgba());
4630
Assert(!format().sampleBuffers());
4631
// Assert(!format().stencil());
4632
Assert(!format().stereo());
4633
VBOXQGLLOG(("swapInterval(%d)\n", format().swapInterval()));
4634
// Assert(format().swapInterval() == 0);
4638
vboxglActiveTexture(GL_TEXTURE0);
4641
VBoxResizeEvent *re = (VBoxResizeEvent*)resize;
4642
bool remind = false;
4643
bool fallback = false;
4645
VBOXQGLLOG(("resizing: fmt=%d, vram=%p, bpp=%d, bpl=%d, width=%d, height=%d\n",
4646
re->pixelFormat(), re->VRAM(),
4647
re->bitsPerPixel(), re->bytesPerLine(),
4648
re->width(), re->height()));
4650
/* clean the old values first */
4653
uint32_t bitsPerPixel;
4654
uint32_t b = 0xff, g = 0xff00, r = 0xff0000;
4656
/* check if we support the pixel format and can use the guest VRAM directly */
4657
if (re->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
4660
bitsPerPixel = re->bitsPerPixel();
4661
bytesPerLine = re->bytesPerLine();
4662
ulong bitsPerLine = bytesPerLine * 8;
4664
switch (bitsPerPixel)
4667
// format = VBoxVHWAColorFormat(bitsPerPixel, 0xff, 0xff00, 0xff0000);
4673
// format = VBoxVHWAColorFormat(bitsPerPixel, 0xff, 0xff00, 0xff0000);
4708
/* QImage only supports 32-bit aligned scan lines... */
4709
Assert ((re->bytesPerLine() & 3) == 0);
4710
fallback = ((re->bytesPerLine() & 3) != 0);
4714
/* ...and the scan lines ought to be a whole number of pixels. */
4715
Assert ((bitsPerLine & (re->bitsPerPixel() - 1)) == 0);
4716
fallback = ((bitsPerLine & (re->bitsPerPixel() - 1)) != 0);
4720
// ulong virtWdt = bitsPerLine / re->bitsPerPixel();
4721
mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
4722
mUsesGuestVRAM = true;
4732
/* we don't support either the pixel format or the color depth,
4733
* fallback to a self-provided 32bpp RGB buffer */
4738
bytesPerLine = re->width()*bitsPerPixel/8;
4739
mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
4740
// internalformat = 3;//GL_RGB;
4741
// format = GL_BGRA_EXT;//GL_RGBA;
4742
// type = GL_UNSIGNED_BYTE;
4743
mUsesGuestVRAM = false;
4746
ulong bytesPerPixel = bitsPerPixel/8;
4747
ulong displayWidth = bytesPerLine/bytesPerPixel;
4748
ulong displayHeight = re->height();
4750
#ifdef VBOXQGL_DBG_SURF
4751
for(int i = 0; i < RT_ELEMENTS(g_apSurf); i++)
4753
VBoxVHWASurfaceBase * pSurf1 = g_apSurf[i];
4756
VBoxVHWASurfList *pConstructingList = pSurf1->getComplexList();
4758
if(pConstructingList)
4759
delete pConstructingList;
4761
// mDisplay.addOverlay(pConstructingList);
4762
// // pConstructingList->add(pSurf1);
4763
// // pConstructingList->setCurrentVisible(pSurf1);
4764
// //// pConstructingList->setCurrentVisible(NULL);
4769
VBoxVHWASurfaceBase * pDisplay = mDisplay.setVGA(NULL);
4773
VBoxVHWAColorFormat format(bitsPerPixel, r,g,b);
4774
QSize dispSize(displayWidth, displayHeight);
4775
QRect dispRect(0, 0, displayWidth, displayHeight);
4776
pDisplay = new VBoxVHWASurfaceBase(this,
4780
dispRect, /* we do not know viewport at the stage of recise, set as a disp rect, it will be updated on repaint */
4782
(VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL,
4783
#ifdef VBOXVHWA_USE_TEXGROUP
4787
pDisplay->init(NULL, mUsesGuestVRAM ? re->VRAM() : NULL);
4788
mDisplay.setVGA(pDisplay);
4789
// VBOXQGLLOG(("\n\n*******\n\n viewport size is: (%d):(%d)\n\n*******\n\n", size().width(), size().height()));
4790
mViewport = QRect(0,0,displayWidth, displayHeight);
4791
adjustViewport(dispSize, mViewport);
4792
setupMatricies(dispSize);
4794
#ifdef VBOXQGL_DBG_SURF
4796
uint32_t width = 100;
4797
uint32_t height = 60;
4798
// uint32_t rgbBitCount = 32;
4799
// uint32_t r = 0xff, g = 0xff00, b = 0xff0000;
4800
// QRect dstRect(150, 200, width, height);
4801
// QRect srcRect(0, 0, 720, 480);
4804
for(int i = 0; i < RT_ELEMENTS(g_apSurf); i++)
4806
VBoxVHWAColorFormat tmpFormat(FOURCC_YV12);
4807
QSize tmpSize(width, height) ;
4808
VBoxVHWASurfaceBase *pSurf1 = new VBoxVHWASurfaceBase(this, tmpSize,
4809
mDisplay.getPrimary()->rect(),
4810
QRect(0, 0, width, height),
4813
NULL, NULL, NULL, &VBoxVHWAColorKey(0,0),
4814
#ifdef VBOXVHWA_USE_TEXGROUP
4819
Assert(mDisplay.getVGA());
4820
pSurf1->init(mDisplay.getVGA(), NULL);
4821
uchar *addr = pSurf1->address();
4823
for(uint32_t k = 0; k < width*height; k++)
4828
pSurf1->updatedMem(&QRect(0,0,width, height));
4829
// VBOXQGL_CHECKERR(
4830
// vboxglActiveTexture(GL_TEXTURE0);
4833
VBoxVHWASurfList *pConstructingList = new VBoxVHWASurfList();
4834
mDisplay.addOverlay(pConstructingList);
4835
pConstructingList->add(pSurf1);
4836
// pConstructingList->setCurrentVisible(pSurf1);
4837
// pConstructingList->setCurrentVisible(NULL);
4838
g_apSurf[i] = pSurf1;
4840
// VBoxVHWAGlProgramVHWA * pProgram = vboxVHWAGetGlProgramMngr()->getProgram(true, false, &pSurf1->colorFormat(), &pDisplay->colorFormat());
4841
// pProgram->start();
4842
// pProgram->setSrcTexImgWidth(pSurf1->texRect().width());
4843
// pProgram->stop();
4847
// VBoxVHWASurfList *pConstructingList = pSurf1->getComplexList();
4848
// mDisplay.addOverlay(pConstructingList);
4849
// pConstructingList->add(pSurf1);
4850
// pConstructingList->setCurrentVisible(pSurf1);
4851
//// pConstructingList->setCurrentVisible(NULL);
4854
VBOXVHWACMD_SURF_OVERLAY_UPDATE updateCmd;
4855
memset(&updateCmd, 0, sizeof(updateCmd));
4856
updateCmd.u.in.hSrcSurf = (VBOXVHWA_SURFHANDLE)g_apSurf[0];
4857
updateCmd.u.in.hDstSurf = (VBOXVHWA_SURFHANDLE)pDisplay;
4858
updateCmd.u.in.flags =
4860
| VBOXVHWA_OVER_KEYDESTOVERRIDE;
4862
updateCmd.u.in.desc.DstCK.high = 1;
4863
updateCmd.u.in.desc.DstCK.low = 1;
4865
updateCmd.u.in.dstRect.left = 0;
4866
updateCmd.u.in.dstRect.right = pDisplay->width();
4867
updateCmd.u.in.dstRect.top = (pDisplay->height() - height)/2;
4868
updateCmd.u.in.dstRect.bottom = updateCmd.u.in.dstRect.top + height;
4870
updateCmd.u.in.srcRect.left = 0;
4871
updateCmd.u.in.srcRect.right = width;
4872
updateCmd.u.in.srcRect.top = 0;
4873
updateCmd.u.in.srcRect.bottom = height;
4875
updateCmd.u.in.offDstSurface = VBOXVHWA_OFFSET64_VOID; /* just a magic to avoid surf mem buffer change */
4876
updateCmd.u.in.offSrcSurface = VBOXVHWA_OFFSET64_VOID; /* just a magic to avoid surf mem buffer change */
4878
vhwaSurfaceOverlayUpdate(&updateCmd);
4882
if(!mOnResizeCmdList.empty())
4884
for (VHWACommandList::const_iterator it = mOnResizeCmdList.begin();
4885
it != mOnResizeCmdList.end(); ++ it)
4887
VBOXVHWACMD * pCmd = (*it);
4888
vboxDoVHWACmdExec(pCmd);
4891
mOnResizeCmdList.clear();
4895
// mDisplay.performDisplay();
4899
class RemindEvent : public VBoxAsyncEvent
4903
RemindEvent (ulong aRealBPP)
4904
: mRealBPP (aRealBPP) {}
4907
vboxProblem().remindAboutWrongColorDepth (mRealBPP, 32);
4910
(new RemindEvent (re->bitsPerPixel()))->post();
4914
VBoxVHWAColorFormat::VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b) :
4915
mWidthCompression(1),
4916
mHeightCompression(1)
4918
init(bitsPerPixel, r, g, b);
4921
VBoxVHWAColorFormat::VBoxVHWAColorFormat(uint32_t fourcc) :
4922
mWidthCompression(1),
4923
mHeightCompression(1)
4928
void VBoxVHWAColorFormat::init(uint32_t fourcc)
4930
mDataFormat = fourcc;
4931
mInternalFormat = GL_RGBA8;//GL_RGB;
4932
mFormat = GL_BGRA_EXT;//GL_RGBA;
4933
mType = GL_UNSIGNED_BYTE;
4934
mR = VBoxVHWAColorComponent(0xff);
4935
mG = VBoxVHWAColorComponent(0xff);
4936
mB = VBoxVHWAColorComponent(0xff);
4937
mA = VBoxVHWAColorComponent(0xff);
4938
mBitsPerPixelTex = 32;
4944
mWidthCompression = 1;
4949
mWidthCompression = 2;
4953
mWidthCompression = 4;
4958
mBitsPerPixelTex = 0;
4959
mWidthCompression = 0;
4964
void VBoxVHWAColorFormat::init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b)
4966
mBitsPerPixel = bitsPerPixel;
4967
mBitsPerPixelTex = bitsPerPixel;
4969
switch (bitsPerPixel)
4972
mInternalFormat = GL_RGB;//3;//GL_RGB;
4973
mFormat = GL_BGRA_EXT;//GL_RGBA;
4974
mType = GL_UNSIGNED_BYTE;
4975
mR = VBoxVHWAColorComponent(r);
4976
mG = VBoxVHWAColorComponent(g);
4977
mB = VBoxVHWAColorComponent(b);
4983
mInternalFormat = 3;//GL_RGB;
4984
mFormat = GL_BGR_EXT;
4985
mType = GL_UNSIGNED_BYTE;
4986
mR = VBoxVHWAColorComponent(r);
4987
mG = VBoxVHWAColorComponent(g);
4988
mB = VBoxVHWAColorComponent(b);
4994
mInternalFormat = GL_RGB5;
4995
mFormat = GL_BGR_EXT;
4996
mType = GL_UNSIGNED_BYTE; /* TODO" ??? */
4997
mR = VBoxVHWAColorComponent(r);
4998
mG = VBoxVHWAColorComponent(g);
4999
mB = VBoxVHWAColorComponent(b);
5005
mInternalFormat = 1;//GL_RGB;
5006
mFormat = GL_RED;//GL_RGB;
5007
mType = GL_UNSIGNED_BYTE;
5008
mR = VBoxVHWAColorComponent(0xff);
5014
mInternalFormat = 1;
5015
mFormat = GL_COLOR_INDEX;
5017
mR = VBoxVHWAColorComponent(0x1);
5024
mBitsPerPixelTex = 0;
5029
bool VBoxVHWAColorFormat::equals (const VBoxVHWAColorFormat & other) const
5032
return fourcc() == other.fourcc();
5036
return bitsPerPixel() == other.bitsPerPixel();
5039
VBoxVHWAColorComponent::VBoxVHWAColorComponent(uint32_t aMask)
5041
unsigned f = ASMBitFirstSetU32(aMask);
5045
f = ASMBitFirstSetU32(~(aMask >> mOffset));
5052
mcBits = 32 - mOffset;
5056
mMask = (((uint32_t)0xffffffff) >> (32 - mcBits)) << mOffset;
5057
Assert(mMask == aMask);
5059
mRange = (mMask >> mOffset) + 1;
5070
void VBoxVHWAColorFormat::pixel2Normalized (uint32_t pix, float *r, float *g, float *b) const
5072
*r = mR.colorValNorm(pix);
5073
*g = mG.colorValNorm(pix);
5074
*b = mB.colorValNorm(pix);
5077
VBoxQGLOverlay::VBoxQGLOverlay (VBoxConsoleView *aView, VBoxFrameBuffer * aContainer)
5078
: mpOverlayWidget(NULL),
5080
mContainer(aContainer),
5082
mOverlayWidgetVisible(false),
5083
mOverlayVisible(false),
5085
mProcessingCommands(false),
5086
mNeedOverlayRepaint(false),
5087
mNeedSetVisible(false),
5090
/* postpone the gl widget initialization to avoid conflict with 3D on Mac */
5093
void VBoxQGLOverlay::initGl()
5098
mpOverlayWidget = new VBoxGLWidget (mView, mView->viewport());
5100
VBoxGLContext *pc = (VBoxGLContext*)mpOverlayWidget->context();
5101
pc->allowDoneCurrent(false);
5103
mOverlayWidgetVisible = true; /* to ensure it is set hidden with vboxShowOverlay */
5104
vboxShowOverlay(false);
5106
mpOverlayWidget->setMouseTracking(true);
5109
int VBoxQGLOverlay::reset()
5111
VBoxVHWACommandElement * pHead, * pTail;
5112
mCmdPipe.reset(&pHead, &pTail);
5115
CDisplay display = mView->console().GetDisplay();
5116
Assert (!display.isNull());
5118
/* complete aborted commands */
5119
for(VBoxVHWACommandElement * pCur = pHead; pCur; pCur = pCur->mpNext)
5121
switch(pCur->type())
5123
#ifdef VBOX_WITH_VIDEOHWACCEL
5124
case VBOXVHWA_PIPECMD_VHWA:
5126
struct _VBOXVHWACMD * pCmd = pCur->vhwaCmd();
5127
pCmd->rc = VERR_INVALID_STATE;
5128
display.CompleteVHWACommand((BYTE*)pCmd);
5131
case VBOXVHWA_PIPECMD_OP:
5132
/* should not happen, don't handle this for now */
5135
case VBOXVHWA_PIPECMD_FUNC:
5136
/* should not happen, don't handle this for now */
5140
case VBOXVHWA_PIPECMD_PAINT:
5143
/* should not happen, don't handle this for now */
5149
VBoxVHWACommandElement *pTest = mCmdPipe.detachCmdList(pHead, pTail);
5156
return VINF_SUCCESS;
5159
static DECLCALLBACK(void) vbvaVHWAHHCommandFreeCmd(void * pContext)
5164
int VBoxQGLOverlay::resetGl()
5168
VHWACommandList list;
5169
int rc = mpOverlayWidget->reset(&list);
5172
for (VHWACommandList::const_iterator sIt = list.begin();
5173
sIt != list.end(); ++ sIt)
5175
VBOXVHWACMD *pCmd = (*sIt);
5176
VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandFreeCmd, pCmd);
5177
mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd, 0);
5181
return VINF_SUCCESS;
5184
int VBoxQGLOverlay::onVHWACommand(struct _VBOXVHWACMD * pCmd)
5187
switch(pCmd->enmCmd)
5189
case VBOXVHWACMD_TYPE_SURF_FLIP:
5190
case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
5191
case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
5192
flags |= VBOXVHWACMDPIPEC_COMPLETEEVENT;
5194
case VBOXVHWACMD_TYPE_HH_RESET:
5196
/* we do not post a reset command to the gui thread since this may lead to a deadlock
5197
* when reset is initiated by the gui thread*/
5198
pCmd->Flags &= ~VBOXVHWACMD_FLAG_HG_ASYNCH;
5200
return VINF_SUCCESS;
5205
/* indicate that we process and complete the command asynchronously */
5206
pCmd->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
5208
mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd, flags);
5209
return VINF_SUCCESS;
5213
void VBoxQGLOverlay::onVHWACommandEvent(QEvent * pEvent)
5216
Assert(!mProcessingCommands);
5217
mProcessingCommands = true;
5218
Assert(!mGlCurrent);
5219
mGlCurrent = false; /* just a fall-back */
5220
VBoxVHWACommandElement * pFirst = mCmdPipe.detachCmdList(NULL, NULL);
5221
while(pFirst) /* pFirst can be zero right after reset when all pending commands are flushed,
5222
* while events for those commands may still come along */
5224
VBoxVHWACommandElement * pLast = processCmdList(pFirst);
5226
pFirst = mCmdPipe.detachCmdList(pFirst, pLast);
5229
mProcessingCommands = false;
5235
bool VBoxQGLOverlay::onNotifyUpdate(ULONG aX, ULONG aY,
5239
QRect r(aX, aY, aW, aH);
5240
mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r, 0);
5243
/* We're not on the GUI thread and update() isn't thread safe in
5244
* Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
5245
* on Linux (didn't check Qt 4.x there) and probably on other
5246
* non-DOS platforms, so post the event instead. */
5247
QApplication::postEvent (mView,
5248
new VBoxRepaintEvent (aX, aY, aW, aH));
5254
//VBOXFBOVERLAY_RESUT VBoxQGLOverlay::onPaintEvent (const QPaintEvent *pe, QRect *pRect)
5259
//// if(mOverlayWidgetVisible && !mProcessingCommands)
5261
//// Assert(!mGlCurrent);
5262
//// vboxDoCheckUpdateViewport();
5265
// return VBOXFBOVERLAY_UNTOUCHED;
5268
void VBoxQGLOverlay::onResizeEvent (const VBoxResizeEvent *re)
5273
void VBoxQGLOverlay::onResizeEventPostprocess (const VBoxResizeEvent *re)
5279
Assert(!mGlCurrent);
5280
Assert(!mNeedOverlayRepaint);
5283
/* need to ensure we're in synch */
5284
mNeedOverlayRepaint = vboxSynchGl();
5287
if(!mOnResizeCmdList.empty())
5289
for (VHWACommandList::const_iterator it = mOnResizeCmdList.begin();
5290
it != mOnResizeCmdList.end(); ++ it)
5292
VBOXVHWACMD * pCmd = (*it);
5293
vboxDoVHWACmdExec(pCmd);
5296
mOnResizeCmdList.clear();
5303
void VBoxQGLOverlay::repaintMain()
5305
if(mMainDirtyRect.isClear())
5308
const QRect &rect = mMainDirtyRect.rect();
5309
if(mOverlayWidgetVisible)
5311
if(mOverlayViewport.contains(rect))
5315
mView->viewport()->repaint (rect.x() - mView->contentsX(),
5316
rect.y() - mView->contentsY(),
5317
rect.width(), rect.height());
5319
mMainDirtyRect.clear();
5322
void VBoxQGLOverlay::vboxDoVHWACmd(void *cmd)
5324
vboxDoVHWACmdExec(cmd);
5326
CDisplay display = mView->console().GetDisplay();
5327
Assert (!display.isNull());
5329
display.CompleteVHWACommand((BYTE*)cmd);
5332
//void VBoxQGLOverlay::vboxDoUpdateRect(const QRect * pRect)
5337
// mpOverlayWidget->vboxDoUpdateRect(pRect);
5341
// mView->viewport()->repaint (pRect->x() - mView->contentsX(),
5342
// pRect->y() - mView->contentsY(),
5343
// pRect->width(), pRect->height());
5345
// /* translate to widget coords
5346
// * @todo: may eliminate this */
5347
//// QPaintEvent pe(pRect->translated(-mView->contentsX(), -mView->contentsY()));
5348
//// VBoxQImageFrameBuffer::paintEvent (&pe);
5351
bool VBoxQGLOverlay::vboxSynchGl()
5353
if(mpOverlayWidget->vboxIsInitialized()
5354
&& mContainer->pixelFormat() == mpOverlayWidget->vboxPixelFormat()
5355
&& mContainer->address() == mpOverlayWidget->vboxAddress()
5356
&& mContainer->bitsPerPixel() == mpOverlayWidget->vboxBitsPerPixel()
5357
&& mContainer->bytesPerLine() == mpOverlayWidget->vboxBytesPerLine()
5358
&& (int)mContainer->width() == mpOverlayWidget->vboxFbWidth()
5359
&& (int)mContainer->height() == mpOverlayWidget->vboxFbHeight())
5363
/* create and issue a resize event to the gl widget to ensure we have all gl data initialized
5364
* and synchronized with the framebuffer */
5365
VBoxResizeEvent re(mContainer->pixelFormat(),
5366
mContainer->address(),
5367
mContainer->bitsPerPixel(),
5368
mContainer->bytesPerLine(),
5369
mContainer->width(),
5370
mContainer->height());
5372
mpOverlayWidget->vboxDoResize(&re);
5376
void VBoxQGLOverlay::vboxSetGlOn(bool on)
5385
/* need to ensure we have gl functions initialized */
5386
mpOverlayWidget->makeCurrent();
5387
vboxVHWAGetSupportInfo(mpOverlayWidget->context());
5389
VBOXQGLLOGREL(("Switching Gl mode on\n"));
5390
Assert(!mpOverlayWidget->isVisible());
5391
/* just to ensure */
5392
vboxShowOverlay(false);
5393
mOverlayVisible = false;
5398
VBOXQGLLOGREL(("Switching Gl mode off\n"));
5399
mOverlayVisible = false;
5400
vboxShowOverlay(false);
5401
/* for now just set the flag w/o destroying anything */
5405
void VBoxQGLOverlay::vboxDoCheckUpdateViewport()
5407
if(!mOverlayVisible)
5409
vboxShowOverlay(false);
5413
int cX = mView->contentsX();
5414
int cY = mView->contentsY();
5415
QRect fbVp(cX, cY, mView->viewport()->width(), mView->viewport()->height());
5416
QRect overVp = fbVp.intersected(mOverlayViewport);
5418
if(overVp.isEmpty())
5420
vboxShowOverlay(false);
5424
if(overVp != mpOverlayWidget->vboxViewport())
5427
mpOverlayWidget->vboxDoUpdateViewport(overVp);
5428
mNeedOverlayRepaint = true;
5431
QRect rect(overVp.x() - cX, overVp.y() - cY, overVp.width(), overVp.height());
5433
vboxCheckUpdateOverlay(rect);
5435
vboxShowOverlay(true);
5437
/* workaround for linux ATI issue: need to update gl viewport after widget becomes visible */
5438
mpOverlayWidget->vboxDoUpdateViewport(overVp);
5442
void VBoxQGLOverlay::vboxShowOverlay(bool show)
5444
if(mOverlayWidgetVisible != show)
5446
mpOverlayWidget->setVisible(show);
5447
mOverlayWidgetVisible = show;
5451
mMainDirtyRect.add(mpOverlayWidget->vboxViewport());
5456
//void VBoxQGLOverlayFrameBuffer::vboxUpdateOverlayPosition(const QPoint & pos)
5460
// mpOverlayWidget->move(pos);
5463
//// QRect rect = mpOverlayWidget->vboxViewport();
5464
//// rect.moveTo(pos);
5465
//// mpOverlayWidget->vboxDoUpdateViewport(rect);
5468
void VBoxQGLOverlay::vboxCheckUpdateOverlay(const QRect & rect)
5470
QRect overRect(mpOverlayWidget->pos(), mpOverlayWidget->size());
5471
if(overRect.x() != rect.x() || overRect.y() != rect.y())
5473
#if defined(RT_OS_WINDOWS)
5474
mpOverlayWidget->setVisible(false);
5475
mNeedSetVisible = true;
5477
VBOXQGLLOG_QRECT("moving wgt to " , &rect, "\n");
5478
mpOverlayWidget->move(rect.x(), rect.y());
5482
if(overRect.width() != rect.width() || overRect.height() != rect.height())
5484
#if defined(RT_OS_WINDOWS)
5485
mpOverlayWidget->setVisible(false);
5486
mNeedSetVisible = true;
5488
VBOXQGLLOG(("resizing wgt to w(%d) ,h(%d)\n" , rect.width(), rect.height()));
5489
mpOverlayWidget->resize(rect.width(), rect.height());
5493
// mpOverlayWidget->vboxDoUpdateViewport(rect);
5495
// vboxShowOverlay(show);
5498
void VBoxQGLOverlay::addMainDirtyRect(const QRect & aRect)
5500
mMainDirtyRect.add(aRect);
5503
mpOverlayWidget->vboxDoUpdateRect(&aRect);
5504
mNeedOverlayRepaint = true;
5508
int VBoxQGLOverlay::vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd)
5510
int rc = mpOverlayWidget->vhwaSurfaceUnlock(pCmd);
5511
VBoxVHWASurfaceBase * pVGA = mpOverlayWidget->vboxGetVGASurface();
5512
const VBoxVHWADirtyRect & rect = pVGA->getDirtyRect();
5513
mNeedOverlayRepaint = true;
5516
mMainDirtyRect.add(rect);
5521
void VBoxQGLOverlay::vboxDoVHWACmdExec(void *cmd)
5523
struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
5524
switch(pCmd->enmCmd)
5526
case VBOXVHWACMD_TYPE_SURF_CANCREATE:
5528
VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
5530
pCmd->rc = mpOverlayWidget->vhwaSurfaceCanCreate(pBody);
5532
case VBOXVHWACMD_TYPE_SURF_CREATE:
5534
VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
5537
pCmd->rc = mpOverlayWidget->vhwaSurfaceCreate(pBody);
5538
if(!mpOverlayWidget->hasSurfaces())
5544
mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
5547
mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
5549
vboxDoCheckUpdateViewport();
5550
mNeedOverlayRepaint = true;
5553
case VBOXVHWACMD_TYPE_SURF_DESTROY:
5555
VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
5557
pCmd->rc = mpOverlayWidget->vhwaSurfaceDestroy(pBody);
5558
if(!mpOverlayWidget->hasSurfaces())
5564
mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
5567
mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
5569
vboxDoCheckUpdateViewport();
5570
mNeedOverlayRepaint = true;
5573
case VBOXVHWACMD_TYPE_SURF_LOCK:
5575
VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
5577
pCmd->rc = mpOverlayWidget->vhwaSurfaceLock(pBody);
5579
case VBOXVHWACMD_TYPE_SURF_UNLOCK:
5581
VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
5583
pCmd->rc = vhwaSurfaceUnlock(pBody);
5584
/* mNeedOverlayRepaint is set inside the vhwaSurfaceUnlock */
5586
case VBOXVHWACMD_TYPE_SURF_BLT:
5588
VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
5590
pCmd->rc = mpOverlayWidget->vhwaSurfaceBlt(pBody);
5591
mNeedOverlayRepaint = true;
5593
case VBOXVHWACMD_TYPE_SURF_FLIP:
5595
VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
5597
pCmd->rc = mpOverlayWidget->vhwaSurfaceFlip(pBody);
5598
mNeedOverlayRepaint = true;
5600
case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
5602
VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
5604
pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlayUpdate(pBody);
5605
mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
5608
mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
5610
vboxDoCheckUpdateViewport();
5611
mNeedOverlayRepaint = true;
5613
case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
5615
VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
5617
pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlaySetPosition(pBody);
5618
mOverlayVisible = mpOverlayWidget->hasVisibleOverlays();
5621
mOverlayViewport = mpOverlayWidget->overlaysRectUnion();
5623
vboxDoCheckUpdateViewport();
5624
mNeedOverlayRepaint = true;
5626
case VBOXVHWACMD_TYPE_SURF_COLORKEY_SET:
5628
VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
5630
pCmd->rc = mpOverlayWidget->vhwaSurfaceColorkeySet(pBody);
5631
/* this is here to ensure we have color key changes picked up */
5632
vboxDoCheckUpdateViewport();
5633
mNeedOverlayRepaint = true;
5635
case VBOXVHWACMD_TYPE_QUERY_INFO1:
5637
VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
5640
pCmd->rc = mpOverlayWidget->vhwaQueryInfo1(pBody);
5642
case VBOXVHWACMD_TYPE_QUERY_INFO2:
5644
VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
5646
pCmd->rc = mpOverlayWidget->vhwaQueryInfo2(pBody);
5648
case VBOXVHWACMD_TYPE_ENABLE:
5650
case VBOXVHWACMD_TYPE_DISABLE:
5651
pCmd->rc = VINF_SUCCESS;
5653
case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
5655
VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
5656
pCmd->rc = vhwaConstruct(pBody);
5660
pCmd->rc = VERR_NOT_IMPLEMENTED;
5665
static DECLCALLBACK(void) vboxQGLOverlaySaveExec(PSSMHANDLE pSSM, void *pvUser)
5667
VBoxQGLOverlay * fb = (VBoxQGLOverlay*)pvUser;
5668
fb->vhwaSaveExec(pSSM);
5671
static DECLCALLBACK(int) vboxQGLOverlayLoadExec(PSSMHANDLE pSSM, void *pvUser, uint32_t u32Version, uint32_t uPass)
5673
Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
5674
VBoxQGLOverlay * fb = (VBoxQGLOverlay*)pvUser;
5675
return fb->vhwaLoadExec(pSSM, u32Version);
5678
int VBoxQGLOverlay::vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version)
5681
// int rc = SSMR3GetBool(pSSM, &bTmp /*&mGlOn*/); AssertRC(rc);
5682
// rc = SSMR3GetBool(pSSM, &bTmp /*&mOverlayVisible*/); AssertRC(rc);
5683
// if(RT_SUCCESS(rc))
5684
return VBoxGLWidget::vhwaLoadExec(&mOnResizeCmdList, pSSM, u32Version);
5688
void VBoxQGLOverlay::vhwaSaveExec(struct SSMHANDLE * pSSM)
5690
// int rc = SSMR3PutBool(pSSM, mGlOn); AssertRC(rc);
5691
// rc = SSMR3PutBool(pSSM, mOverlayVisible); AssertRC(rc);
5694
mpOverlayWidget->vhwaSaveExec(pSSM);
5696
VBoxGLWidget::vhwaSaveExecVoid(pSSM);
5699
int VBoxQGLOverlay::vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd)
5701
PVM pVM = (PVM)pCmd->pVM;
5702
uint32_t intsId = 0; /* @todo: set the proper id */
5704
char nameFuf[sizeof(VBOXQGL_STATE_NAMEBASE) + 8];
5706
char * pszName = nameFuf;
5707
sprintf(pszName, "%s%d", VBOXQGL_STATE_NAMEBASE, intsId);
5708
int rc = SSMR3RegisterExternal(
5709
pVM, /* The VM handle*/
5710
pszName, /* Data unit name. */
5711
intsId, /* The instance identifier of the data unit.
5712
* This must together with the name be unique. */
5713
VBOXQGL_STATE_VERSION, /* Data layout version number. */
5714
128, /* The approximate amount of data in the unit.
5715
* Only for progress indicators. */
5716
NULL, NULL, NULL, /* pfnLiveXxx */
5717
NULL, /* Prepare save callback, optional. */
5718
vboxQGLOverlaySaveExec, /* Execute save callback, optional. */
5719
NULL, /* Done save callback, optional. */
5720
NULL, /* Prepare load callback, optional. */
5721
vboxQGLOverlayLoadExec, /* Execute load callback, optional. */
5722
NULL, /* Done load callback, optional. */
5723
this /* User argument. */
5725
Assert(RT_SUCCESS(rc));
5730
bool VBoxQGLOverlay::isAcceleration2DVideoAvailable()
5733
if(!g_bVBoxVHWAChecked)
5736
g_bVBoxVHWAChecked = true;
5737
g_bVBoxVHWASupported = VBoxVHWAInfo::checkVHWASupport();
5739
return g_bVBoxVHWASupported;
5742
/** additional video memory required for the best 2D support performance
5743
* total amount of VRAM required is thus calculated as requiredVideoMemory + required2DOffscreenVideoMemory */
5745
quint64 VBoxQGLOverlay::required2DOffscreenVideoMemory()
5747
/* HDTV == 1920x1080 ~ 2M
5748
* for the 4:2:2 formats each pixel is 2Bytes
5749
* so each frame may be 4MB
5750
* so for triple-buffering we would need 12 MB */
5754
VBoxVHWACommandElement * VBoxQGLOverlay::processCmdList(VBoxVHWACommandElement * pCmd)
5756
VBoxVHWACommandElement * pCur;
5760
switch(pCmd->type())
5762
case VBOXVHWA_PIPECMD_PAINT:
5763
addMainDirtyRect(pCmd->rect());
5765
#ifdef VBOX_WITH_VIDEOHWACCEL
5766
case VBOXVHWA_PIPECMD_VHWA:
5767
vboxDoVHWACmd(pCmd->vhwaCmd());
5769
case VBOXVHWA_PIPECMD_OP:
5771
const VBOXVHWACALLBACKINFO & info = pCmd->op();
5772
(info.pThis->*(info.pfnCallback))(info.pContext);
5775
case VBOXVHWA_PIPECMD_FUNC:
5777
const VBOXVHWAFUNCCALLBACKINFO & info = pCmd->func();
5778
info.pfnCallback(info.pContext1, info.pContext2);
5785
pCmd = pCmd->mpNext;
5792
VBoxVHWACommandElementProcessor::VBoxVHWACommandElementProcessor(VBoxConsoleView *aView) :
5793
mpFirstEvent (NULL),
5796
mbProcessingList (false)
5798
int rc = RTCritSectInit(&mCritSect);
5803
for(int i = RT_ELEMENTS(mElementsBuffer) - 1; i >= 0; i--)
5805
mFreeElements.push(&mElementsBuffer[i]);
5809
VBoxVHWACommandElementProcessor::~VBoxVHWACommandElementProcessor()
5811
RTCritSectDelete(&mCritSect);
5814
void VBoxVHWACommandElementProcessor::completeCurrentEvent()
5816
RTCritSectEnter(&mCritSect);
5818
RTCritSectLeave(&mCritSect);
5821
void VBoxVHWACommandElementProcessor::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags)
5824
RTCritSectEnter(&mCritSect);
5825
VBoxVHWACommandElement * pCmd = mFreeElements.pop();
5828
VBOXQGLLOG(("!!!no more free elements!!!\n"));
5829
#ifdef VBOXQGL_PROF_BASE
5830
RTCritSectLeave(&mCritSect);
5836
pCmd->setData(aType, pvData);
5838
if((flags & VBOXVHWACMDPIPEC_NEWEVENT) != 0)
5843
/* 2. if can add to current*/
5846
/* 3. if event is being processed (event != 0) */
5849
/* 3.a add cmd to event */
5850
mpLastEvent->pipe().put(pCmd);
5851
/* 3.b unlock and return */
5852
if((flags & VBOXVHWACMDPIPEC_COMPLETEEVENT) != 0)
5856
RTCritSectLeave(&mCritSect);
5861
/* we're here because the cmd was NOT be added to the current event queue */
5863
RTCritSectLeave(&mCritSect);
5864
/* 5. create & initialize new Event */
5865
VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent(pCmd);
5866
pCurrentEvent->mpNext = NULL;
5869
RTCritSectEnter(&mCritSect);
5870
/* 7. if no current event set event as current */
5873
Assert(!mpFirstEvent);
5874
mpFirstEvent = pCurrentEvent;
5875
mpLastEvent = pCurrentEvent;
5879
mpLastEvent->mpNext = pCurrentEvent;
5880
mpLastEvent = pCurrentEvent;
5882
/* 8. reset blocking events counter */
5883
mbNewEvent = ((flags & VBOXVHWACMDPIPEC_COMPLETEEVENT) != 0);
5885
RTCritSectLeave(&mCritSect);
5886
/* 10. post event */
5887
QApplication::postEvent (mView, pCurrentEvent);
5890
VBoxVHWACommandElement * VBoxVHWACommandElementProcessor::detachCmdList(VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
5892
VBoxVHWACommandElement * pList = NULL;
5893
RTCritSectEnter(&mCritSect);
5896
mFreeElements.pusha(pFirst2Free, pLast2Free);
5900
pList = mpFirstEvent->pipe().detachList();
5903
/* assume the caller atimically calls detachCmdList to free the elements obtained now those and reset the state */
5904
mbProcessingList = true;
5905
RTCritSectLeave(&mCritSect);
5910
VBoxVHWACommandProcessEvent *pNext = mpFirstEvent->mpNext;
5913
mpFirstEvent = pNext;
5917
mpFirstEvent = NULL;
5923
/* assume the caller atimically calls detachCmdList to free the elements obtained now those and reset the state */
5924
mbProcessingList = false;
5925
RTCritSectLeave(&mCritSect);
5929
/* it is currently assumed no one sends any new commands while reset is in progress */
5930
void VBoxVHWACommandElementProcessor::reset(VBoxVHWACommandElement ** ppHead, VBoxVHWACommandElement ** ppTail)
5932
VBoxVHWACommandElement * pHead = NULL;
5933
VBoxVHWACommandElement * pTail = NULL;
5934
VBoxVHWACommandProcessEvent * pFirst;
5935
VBoxVHWACommandProcessEvent * pLast;
5936
RTCritSectEnter(&mCritSect);
5937
pFirst = mpFirstEvent;
5938
pLast = mpLastEvent;
5939
mpFirstEvent = NULL;
5942
if(mbProcessingList)
5946
RTCritSectLeave(&mCritSect);
5947
RTThreadSleep(2000); /* 2 ms */
5948
RTCritSectEnter(&mCritSect);
5949
/* it is assumed no one sends any new commands while reset is in progress */
5950
Assert(!mpFirstEvent);
5951
Assert(!mpLastEvent);
5952
if(!mbProcessingList)
5962
VBoxVHWACommandElement * pCurHead;
5963
for(VBoxVHWACommandProcessEvent * pCur = pFirst; pCur ; pCur = pCur->mpNext)
5965
pCurHead = pCur->pipe().detachList();
5971
pTail->mpNext = pCurHead;
5973
for(VBoxVHWACommandElement * pCurEl = pCurHead; pCurEl; pCurEl = pCurEl->mpNext)
5984
mbProcessingList = true;
5986
RTCritSectLeave(&mCritSect);
5992
void VBoxVHWACommandsQueue::enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2)
5994
VBoxVHWACommandElement *pCmd = new VBoxVHWACommandElement();
5995
VBOXVHWAFUNCCALLBACKINFO info;
5996
info.pfnCallback = pfn;
5997
info.pContext1 = pContext1;
5998
info.pContext2 = pContext2;
5999
pCmd->setFunc(info);
6003
VBoxVHWACommandElement * VBoxVHWACommandsQueue::detachList()
6005
return mCmds.detachList();
6008
void VBoxVHWACommandsQueue::freeList(VBoxVHWACommandElement * pList)
6012
VBoxVHWACommandElement * pCur = pList;
6013
pList = pCur->mpNext;