VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h@ 43138

Last change on this file since 43138 was 42524, checked in by vboxsync, 12 years ago

2d: LogRel

  • Property svn:eol-style set to native
File size: 57.7 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxFrameBuffer Overly classes declarations
5 */
6
7/*
8 * Copyright (C) 2006-2007 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18#ifndef __VBoxFBOverlay_h__
19#define __VBoxFBOverlay_h__
20#if defined (VBOX_GUI_USE_QGL) || defined(VBOX_WITH_VIDEOHWACCEL)
21
22/* Defines: */
23//#define VBOXQGL_PROF_BASE 1
24//#define VBOXQGL_DBG_SURF 1
25//#define VBOXVHWADBG_RENDERCHECK
26#define VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY 1
27
28/* Qt includes: */
29#include <QGLWidget>
30
31/* GUI includes: */
32#include "UIDefs.h"
33#include "VBoxFBOverlayCommon.h"
34
35/* COM includes: */
36#include "COMEnums.h"
37
38/* Other VBox includes: */
39#include <iprt/assert.h>
40#include <iprt/critsect.h>
41#include <iprt/asm.h>
42#include <iprt/err.h>
43#include <VBox/VBoxGL2D.h>
44#ifdef VBOXVHWA_PROFILE_FPS
45# include <iprt/stream.h>
46#endif /* VBOXVHWA_PROFILE_FPS */
47
48#ifdef DEBUG_misha
49# define VBOXVHWA_PROFILE_FPS
50#endif /* DEBUG_misha */
51
52/* Forward declarations: */
53class CSession;
54
55#ifdef DEBUG
56class VBoxVHWADbgTimer
57{
58public:
59 VBoxVHWADbgTimer(uint32_t cPeriods);
60 ~VBoxVHWADbgTimer();
61 void frame();
62 uint64_t everagePeriod() {return mPeriodSum / mcPeriods; }
63 double fps() {return ((double)1000000000.0) / everagePeriod(); }
64 uint64_t frames() {return mcFrames; }
65private:
66 uint64_t mPeriodSum;
67 uint64_t *mpaPeriods;
68 uint64_t mPrevTime;
69 uint64_t mcFrames;
70 uint32_t mcPeriods;
71 uint32_t miPeriod;
72};
73
74#endif /* DEBUG */
75
76class VBoxVHWASettings
77{
78public:
79 VBoxVHWASettings (CSession &session);
80
81 int fourccEnabledCount() const { return mFourccEnabledCount; }
82 const uint32_t * fourccEnabledList() const { return mFourccEnabledList; }
83
84 bool isStretchLinearEnabled() const { return mStretchLinearEnabled; }
85
86 static int calcIntersection (int c1, const uint32_t *a1, int c2, const uint32_t *a2, int cOut, uint32_t *aOut);
87
88 int getIntersection (const VBoxVHWAInfo &aInfo, int cOut, uint32_t *aOut)
89 {
90 return calcIntersection (mFourccEnabledCount, mFourccEnabledList, aInfo.getFourccSupportedCount(), aInfo.getFourccSupportedList(), cOut, aOut);
91 }
92
93 bool isSupported(const VBoxVHWAInfo &aInfo, uint32_t format)
94 {
95 return calcIntersection (mFourccEnabledCount, mFourccEnabledList, 1, &format, 0, NULL)
96 && calcIntersection (aInfo.getFourccSupportedCount(), aInfo.getFourccSupportedList(), 1, &format, 0, NULL);
97 }
98private:
99 uint32_t mFourccEnabledList[VBOXVHWA_NUMFOURCC];
100 int mFourccEnabledCount;
101 bool mStretchLinearEnabled;
102};
103
104class VBoxVHWADirtyRect
105{
106public:
107 VBoxVHWADirtyRect() :
108 mIsClear(true)
109 {}
110
111 VBoxVHWADirtyRect(const QRect & aRect)
112 {
113 if(aRect.isEmpty())
114 {
115 mIsClear = false;
116 mRect = aRect;
117 }
118 else
119 {
120 mIsClear = true;
121 }
122 }
123
124 bool isClear() const { return mIsClear; }
125
126 void add(const QRect & aRect)
127 {
128 if(aRect.isEmpty())
129 return;
130
131 mRect = mIsClear ? aRect : mRect.united(aRect);
132 mIsClear = false;
133 }
134
135 void add(const VBoxVHWADirtyRect & aRect)
136 {
137 if(aRect.isClear())
138 return;
139 add(aRect.rect());
140 }
141
142 void set(const QRect & aRect)
143 {
144 if(aRect.isEmpty())
145 {
146 mIsClear = true;
147 }
148 else
149 {
150 mRect = aRect;
151 mIsClear = false;
152 }
153 }
154
155 void clear() { mIsClear = true; }
156
157 const QRect & rect() const {return mRect;}
158
159 const QRect & toRect()
160 {
161 if(isClear())
162 {
163 mRect.setCoords(0, 0, -1, -1);
164 }
165 return mRect;
166 }
167
168 bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
169
170 bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
171
172 QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
173
174 bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
175
176 void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
177
178private:
179 QRect mRect;
180 bool mIsClear;
181};
182
183class VBoxVHWAColorKey
184{
185public:
186 VBoxVHWAColorKey() :
187 mUpper(0),
188 mLower(0)
189 {}
190
191 VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
192 mUpper(aUpper),
193 mLower(aLower)
194 {}
195
196 uint32_t upper() const {return mUpper; }
197 uint32_t lower() const {return mLower; }
198
199 bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
200 bool operator!=(const VBoxVHWAColorKey & other) const { return !(*this == other); }
201private:
202 uint32_t mUpper;
203 uint32_t mLower;
204};
205
206class VBoxVHWAColorComponent
207{
208public:
209 VBoxVHWAColorComponent() :
210 mMask(0),
211 mRange(0),
212 mOffset(32),
213 mcBits(0)
214 {}
215
216 VBoxVHWAColorComponent(uint32_t aMask);
217
218 uint32_t mask() const { return mMask; }
219 uint32_t range() const { return mRange; }
220 uint32_t offset() const { return mOffset; }
221 uint32_t cBits() const { return mcBits; }
222 uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
223 float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
224private:
225 uint32_t mMask;
226 uint32_t mRange;
227 uint32_t mOffset;
228 uint32_t mcBits;
229};
230
231class VBoxVHWAColorFormat
232{
233public:
234
235 VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
236 VBoxVHWAColorFormat(uint32_t fourcc);
237 VBoxVHWAColorFormat() :
238 mBitsPerPixel(0) /* needed for isValid() to work */
239 {}
240 GLint internalFormat() const {return mInternalFormat; }
241 GLenum format() const {return mFormat; }
242 GLenum type() const {return mType; }
243 bool isValid() const {return mBitsPerPixel != 0; }
244 uint32_t fourcc() const {return mDataFormat;}
245 uint32_t bitsPerPixel() const { return mBitsPerPixel; }
246 uint32_t bitsPerPixelTex() const { return mBitsPerPixelTex; }
247 void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
248 uint32_t widthCompression() const {return mWidthCompression;}
249 uint32_t heightCompression() const {return mHeightCompression;}
250 const VBoxVHWAColorComponent& r() const {return mR;}
251 const VBoxVHWAColorComponent& g() const {return mG;}
252 const VBoxVHWAColorComponent& b() const {return mB;}
253 const VBoxVHWAColorComponent& a() const {return mA;}
254
255 bool equals (const VBoxVHWAColorFormat & other) const;
256
257 ulong toVBoxPixelFormat() const
258 {
259 if (!mDataFormat)
260 {
261 /* RGB data */
262 switch (mFormat)
263 {
264 case GL_BGRA_EXT:
265 return FramebufferPixelFormat_FOURCC_RGB;
266 }
267 }
268 return FramebufferPixelFormat_Opaque;
269 }
270
271private:
272 void init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
273 void init(uint32_t fourcc);
274
275 GLint mInternalFormat;
276 GLenum mFormat;
277 GLenum mType;
278 uint32_t mDataFormat;
279
280 uint32_t mBitsPerPixel;
281 uint32_t mBitsPerPixelTex;
282 uint32_t mWidthCompression;
283 uint32_t mHeightCompression;
284 VBoxVHWAColorComponent mR;
285 VBoxVHWAColorComponent mG;
286 VBoxVHWAColorComponent mB;
287 VBoxVHWAColorComponent mA;
288};
289
290class VBoxVHWATexture
291{
292public:
293 VBoxVHWATexture() :
294 mAddress(NULL),
295 mTexture(0),
296 mBytesPerPixel(0),
297 mBytesPerPixelTex(0),
298 mBytesPerLine(0),
299 mScaleFuncttion(GL_NEAREST)
300{}
301 VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat, uint32_t bytesPerLine, GLint scaleFuncttion);
302 virtual ~VBoxVHWATexture();
303 virtual void init(uchar *pvMem);
304 void setAddress(uchar *pvMem) {mAddress = pvMem;}
305 void update(const QRect * pRect) { doUpdate(mAddress, pRect);}
306 void bind() {glBindTexture(texTarget(), mTexture);}
307
308 virtual void texCoord(int x, int y);
309 virtual void multiTexCoord(GLenum texUnit, int x, int y);
310
311 const QRect & texRect() {return mTexRect;}
312 const QRect & rect() {return mRect;}
313 uchar * address(){ return mAddress; }
314 uint32_t rectSizeTex(const QRect * pRect) {return pRect->width() * pRect->height() * mBytesPerPixelTex;}
315 uchar * pointAddress(int x, int y)
316 {
317 x = toXTex(x);
318 y = toYTex(y);
319 return pointAddressTex(x, y);
320 }
321 uint32_t pointOffsetTex(int x, int y) { return y*mBytesPerLine + x*mBytesPerPixelTex; }
322 uchar * pointAddressTex(int x, int y) { return mAddress + pointOffsetTex(x, y); }
323 int toXTex(int x) {return x/mColorFormat.widthCompression();}
324 int toYTex(int y) {return y/mColorFormat.heightCompression();}
325 ulong memSize(){ return mBytesPerLine * mRect.height(); }
326 uint32_t bytesPerLine() {return mBytesPerLine; }
327#ifdef DEBUG_misha
328 void dbgDump();
329#endif
330
331protected:
332 virtual void doUpdate(uchar * pAddress, const QRect * pRect);
333 virtual void initParams();
334 virtual void load();
335 virtual GLenum texTarget() {return GL_TEXTURE_2D; }
336 GLuint texture() {return mTexture;}
337
338 QRect mTexRect; /* texture size */
339 QRect mRect; /* img size */
340 uchar * mAddress;
341 GLuint mTexture;
342 uint32_t mBytesPerPixel;
343 uint32_t mBytesPerPixelTex;
344 uint32_t mBytesPerLine;
345 VBoxVHWAColorFormat mColorFormat;
346 GLint mScaleFuncttion;
347private:
348 void uninit();
349
350 friend class VBoxVHWAFBO;
351};
352
353class VBoxVHWATextureNP2 : public VBoxVHWATexture
354{
355public:
356 VBoxVHWATextureNP2() : VBoxVHWATexture() {}
357 VBoxVHWATextureNP2(const QRect & aRect, const VBoxVHWAColorFormat &aFormat, uint32_t bytesPerLine, GLint scaleFuncttion) :
358 VBoxVHWATexture(aRect, aFormat, bytesPerLine, scaleFuncttion){
359 mTexRect = QRect(0, 0, aRect.width()/aFormat.widthCompression(), aRect.height()/aFormat.heightCompression());
360 }
361};
362
363class VBoxVHWATextureNP2Rect : public VBoxVHWATextureNP2
364{
365public:
366 VBoxVHWATextureNP2Rect() : VBoxVHWATextureNP2() {}
367 VBoxVHWATextureNP2Rect(const QRect & aRect, const VBoxVHWAColorFormat &aFormat, uint32_t bytesPerLine, GLint scaleFuncttion) :
368 VBoxVHWATextureNP2(aRect, aFormat, bytesPerLine, scaleFuncttion){}
369
370 virtual void texCoord(int x, int y);
371 virtual void multiTexCoord(GLenum texUnit, int x, int y);
372protected:
373 virtual GLenum texTarget();
374};
375
376class VBoxVHWATextureNP2RectPBO : public VBoxVHWATextureNP2Rect
377{
378public:
379 VBoxVHWATextureNP2RectPBO() :
380 VBoxVHWATextureNP2Rect(),
381 mPBO(0)
382 {}
383 VBoxVHWATextureNP2RectPBO(const QRect & aRect, const VBoxVHWAColorFormat &aFormat, uint32_t bytesPerLine, GLint scaleFuncttion) :
384 VBoxVHWATextureNP2Rect(aRect, aFormat, bytesPerLine, scaleFuncttion),
385 mPBO(0)
386 {}
387
388 virtual ~VBoxVHWATextureNP2RectPBO();
389
390 virtual void init(uchar *pvMem);
391protected:
392 virtual void load();
393 virtual void doUpdate(uchar * pAddress, const QRect * pRect);
394 GLuint mPBO;
395};
396
397class VBoxVHWATextureNP2RectPBOMapped : public VBoxVHWATextureNP2RectPBO
398{
399public:
400 VBoxVHWATextureNP2RectPBOMapped() :
401 VBoxVHWATextureNP2RectPBO(),
402 mpMappedAllignedBuffer(NULL),
403 mcbAllignedBufferSize(0),
404 mcbOffset(0)
405 {}
406 VBoxVHWATextureNP2RectPBOMapped(const QRect & aRect, const VBoxVHWAColorFormat &aFormat, uint32_t bytesPerLine, GLint scaleFuncttion) :
407 VBoxVHWATextureNP2RectPBO(aRect, aFormat, bytesPerLine, scaleFuncttion),
408 mpMappedAllignedBuffer(NULL),
409 mcbOffset(0)
410 {
411 mcbAllignedBufferSize = alignSize((size_t)memSize());
412 mcbActualBufferSize = mcbAllignedBufferSize + 0x1fff;
413 }
414
415 uchar* mapAlignedBuffer();
416 void unmapBuffer();
417 size_t alignedBufferSize() { return mcbAllignedBufferSize; }
418
419 static size_t alignSize(size_t size)
420 {
421 size_t alSize = size & ~((size_t)0xfff);
422 return alSize == size ? alSize : alSize + 0x1000;
423 }
424
425 static void* alignBuffer(void* pvMem) { return (void*)(((uintptr_t)pvMem) & ~((uintptr_t)0xfff)); }
426 static size_t calcOffset(void* pvBase, void* pvOffset) { return (size_t)(((uintptr_t)pvBase) - ((uintptr_t)pvOffset)); }
427protected:
428 virtual void load();
429 virtual void doUpdate(uchar * pAddress, const QRect * pRect);
430private:
431 uchar* mpMappedAllignedBuffer;
432 size_t mcbAllignedBufferSize;
433 size_t mcbOffset;
434 size_t mcbActualBufferSize;
435};
436
437#define VBOXVHWAIMG_PBO 0x00000001U
438#define VBOXVHWAIMG_PBOIMG 0x00000002U
439#define VBOXVHWAIMG_FBO 0x00000004U
440#define VBOXVHWAIMG_LINEAR 0x00000008U
441typedef uint32_t VBOXVHWAIMG_TYPE;
442
443class VBoxVHWATextureImage
444{
445public:
446 VBoxVHWATextureImage(const QRect &size, const VBoxVHWAColorFormat &format, class VBoxVHWAGlProgramMngr * aMgr, VBOXVHWAIMG_TYPE flags);
447
448 virtual ~VBoxVHWATextureImage()
449 {
450 for(uint i = 0; i < mcTex; i++)
451 {
452 delete mpTex[i];
453 }
454 }
455
456 virtual void init(uchar *pvMem)
457 {
458 for(uint32_t i = 0; i < mcTex; i++)
459 {
460 mpTex[i]->init(pvMem);
461 pvMem += mpTex[i]->memSize();
462 }
463 }
464
465 virtual void update(const QRect * pRect)
466 {
467 mpTex[0]->update(pRect);
468 if(mColorFormat.fourcc() == FOURCC_YV12)
469 {
470 if(pRect)
471 {
472 QRect rect(pRect->x()/2, pRect->y()/2,
473 pRect->width()/2, pRect->height()/2);
474 mpTex[1]->update(&rect);
475 mpTex[2]->update(&rect);
476 }
477 else
478 {
479 mpTex[1]->update(NULL);
480 mpTex[2]->update(NULL);
481 }
482 }
483 }
484
485 virtual void display(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
486 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected);
487
488
489 virtual void display();
490
491 void deleteDisplay();
492
493 int initDisplay(VBoxVHWATextureImage *pDst,
494 const QRect * pDstRect, const QRect * pSrcRect,
495 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected);
496
497 bool displayInitialized() { return !!mVisibleDisplay;}
498
499 virtual void setAddress(uchar *pvMem)
500 {
501 for(uint32_t i = 0; i < mcTex; i++)
502 {
503 mpTex[i]->setAddress(pvMem);
504 pvMem += mpTex[i]->memSize();
505 }
506 }
507
508 const QRect &rect()
509 {
510 return mpTex[0]->rect();
511 }
512
513 size_t memSize()
514 {
515 size_t size = 0;
516 for(uint32_t i = 0; i < mcTex; i++)
517 {
518 size+=mpTex[i]->memSize();
519 }
520 return size;
521 }
522
523 uint32_t bytesPerLine() { return mpTex[0]->bytesPerLine(); }
524
525 const VBoxVHWAColorFormat &pixelFormat() { return mColorFormat; }
526
527 uint32_t numComponents() {return mcTex;}
528
529 VBoxVHWATexture* component(uint32_t i) {return mpTex[i]; }
530
531 const VBoxVHWATextureImage *dst() { return mpDst;}
532 const QRect& dstRect() { return mDstRect; }
533 const QRect& srcRect() { return mSrcRect; }
534 const VBoxVHWAColorKey* dstCKey() { return mpDstCKey; }
535 const VBoxVHWAColorKey* srcCKey() { return mpSrcCKey; }
536 bool notIntersectedMode() { return mbNotIntersected; }
537
538 static uint32_t calcBytesPerLine(const VBoxVHWAColorFormat & format, int width);
539 static uint32_t calcMemSize(const VBoxVHWAColorFormat & format, int width, int height);
540
541#ifdef DEBUG_misha
542 void dbgDump();
543#endif
544
545protected:
546 static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
547
548 static bool matchCKeys(const VBoxVHWAColorKey * pCKey1, const VBoxVHWAColorKey * pCKey2)
549 {
550 return (pCKey1 == NULL && pCKey2 == NULL)
551 || (*pCKey1 == *pCKey2);
552 }
553
554 void runDisplay(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect)
555 {
556 bind(pDst);
557
558 draw(pDst, pDstRect, pSrcRect);
559 }
560
561 virtual void draw(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect);
562
563 virtual uint32_t texCoord(GLenum tex, int x, int y)
564 {
565 uint32_t c = 1;
566 mpTex[0]->multiTexCoord(tex, x, y);
567 if(mColorFormat.fourcc() == FOURCC_YV12)
568 {
569 int x2 = x/2;
570 int y2 = y/2;
571 mpTex[1]->multiTexCoord(tex + 1, x2, y2);
572 ++c;
573 }
574 return c;
575 }
576
577 virtual void bind(VBoxVHWATextureImage * pPrimary);
578
579 virtual uint32_t calcProgramType(VBoxVHWATextureImage *pDst, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected);
580
581 virtual class VBoxVHWAGlProgramVHWA * calcProgram(VBoxVHWATextureImage *pDst, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected);
582
583 virtual int createDisplay(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
584 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected,
585 GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram);
586
587 int createSetDisplay(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
588 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected);
589
590 virtual int createDisplayList(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
591 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected,
592 GLuint *pDisplay);
593
594 virtual void deleteDisplayList();
595
596 virtual void updateCKeys(VBoxVHWATextureImage * pDst, class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey);
597 virtual void updateSetCKeys(const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey);
598
599 void internalSetDstCKey(const VBoxVHWAColorKey * pDstCKey);
600 void internalSetSrcCKey(const VBoxVHWAColorKey * pSrcCKey);
601
602 VBoxVHWATexture *mpTex[3];
603 uint32_t mcTex;
604 GLuint mVisibleDisplay;
605 class VBoxVHWAGlProgramVHWA * mpProgram;
606 class VBoxVHWAGlProgramMngr * mProgramMngr;
607 VBoxVHWAColorFormat mColorFormat;
608
609 /* display info */
610 VBoxVHWATextureImage *mpDst;
611 QRect mDstRect;
612 QRect mSrcRect;
613 VBoxVHWAColorKey * mpDstCKey;
614 VBoxVHWAColorKey * mpSrcCKey;
615 VBoxVHWAColorKey mDstCKey;
616 VBoxVHWAColorKey mSrcCKey;
617 bool mbNotIntersected;
618};
619
620class VBoxVHWATextureImagePBO : public VBoxVHWATextureImage
621{
622public:
623 VBoxVHWATextureImagePBO(const QRect &size, const VBoxVHWAColorFormat &format, class VBoxVHWAGlProgramMngr * aMgr, VBOXVHWAIMG_TYPE flags) :
624 VBoxVHWATextureImage(size, format, aMgr, flags & (~VBOXVHWAIMG_PBO)),
625 mPBO(0)
626 {
627 }
628
629 virtual ~VBoxVHWATextureImagePBO()
630 {
631 if(mPBO)
632 {
633 VBOXQGL_CHECKERR(
634 vboxglDeleteBuffers(1, &mPBO);
635 );
636 }
637 }
638
639 virtual void init(uchar *pvMem)
640 {
641 VBoxVHWATextureImage::init(pvMem);
642
643 VBOXQGL_CHECKERR(
644 vboxglGenBuffers(1, &mPBO);
645 );
646 mAddress = pvMem;
647
648 VBOXQGL_CHECKERR(
649 vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
650 );
651
652 VBOXQGL_CHECKERR(
653 vboxglBufferData(GL_PIXEL_UNPACK_BUFFER, memSize(), NULL, GL_STREAM_DRAW);
654 );
655
656 GLvoid *buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
657 Assert(buf);
658 if(buf)
659 {
660 memcpy(buf, mAddress, memSize());
661
662 bool unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
663 Assert(unmapped); NOREF(unmapped);
664 }
665
666 vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
667
668 }
669
670 virtual void update(const QRect * pRect)
671 {
672 VBOXQGL_CHECKERR(
673 vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
674 );
675
676 GLvoid *buf;
677
678 VBOXQGL_CHECKERR(
679 buf = vboxglMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
680 );
681 Assert(buf);
682 if(buf)
683 {
684#ifdef VBOXVHWADBG_RENDERCHECK
685 uint32_t * pBuf32 = (uint32_t*)buf;
686 uchar * pBuf8 = (uchar*)buf;
687 for(uint32_t i = 0; i < mcTex; i++)
688 {
689 uint32_t dbgSetVal = 0x40404040 * (i+1);
690 for(uint32_t k = 0; k < mpTex[i]->memSize()/sizeof(pBuf32[0]); k++)
691 {
692 pBuf32[k] = dbgSetVal;
693 }
694
695 pBuf8 += mpTex[i]->memSize();
696 pBuf32 = (uint32_t *)pBuf8;
697 }
698#else
699 memcpy(buf, mAddress, memSize());
700#endif
701
702 bool unmapped;
703 VBOXQGL_CHECKERR(
704 unmapped = vboxglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
705 );
706
707 Assert(unmapped); NOREF(unmapped);
708
709 VBoxVHWATextureImage::setAddress(0);
710
711 VBoxVHWATextureImage::update(NULL);
712
713 VBoxVHWATextureImage::setAddress(mAddress);
714
715 vboxglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
716 }
717 else
718 {
719 VBOXQGLLOGREL(("failed to map PBO, trying fallback to non-PBO approach\n"));
720
721 VBoxVHWATextureImage::setAddress(mAddress);
722
723 VBoxVHWATextureImage::update(pRect);
724 }
725 }
726
727 virtual void setAddress(uchar *pvMem)
728 {
729 mAddress = pvMem;
730 }
731private:
732 GLuint mPBO;
733 uchar* mAddress;
734};
735
736class VBoxVHWAHandleTable
737{
738public:
739 VBoxVHWAHandleTable(uint32_t initialSize);
740 ~VBoxVHWAHandleTable();
741 uint32_t put(void * data);
742 bool mapPut(uint32_t h, void * data);
743 void* get(uint32_t h);
744 void* remove(uint32_t h);
745private:
746 void doPut(uint32_t h, void * data);
747 void doRemove(uint32_t h);
748 void** mTable;
749 uint32_t mcSize;
750 uint32_t mcUsage;
751 uint32_t mCursor;
752};
753
754/* data flow:
755 * I. NON-Yinverted surface:
756 * 1.direct memory update (paint, lock/unlock):
757 * mem->tex->fb
758 * 2.blt
759 * srcTex->invFB->tex->fb
760 * |->mem
761 *
762 * II. Yinverted surface:
763 * 1.direct memory update (paint, lock/unlock):
764 * mem->tex->fb
765 * 2.blt
766 * srcTex->fb->tex
767 * |->mem
768 *
769 * III. flip support:
770 * 1. Yinverted<->NON-YInverted conversion :
771 * mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
772 * fb-->| |->mem
773 * */
774class VBoxVHWASurfaceBase
775{
776public:
777 VBoxVHWASurfaceBase (class VBoxVHWAImage *pImage,
778 const QSize & aSize,
779 const QRect & aTargRect,
780 const QRect & aSrcRect,
781 const QRect & aVisTargRect,
782 VBoxVHWAColorFormat & aColorFormat,
783 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
784 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
785 VBOXVHWAIMG_TYPE aImgFlags);
786
787 virtual ~VBoxVHWASurfaceBase();
788
789 void init (VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
790
791 void uninit();
792
793 static void globalInit();
794
795 int lock (const QRect * pRect, uint32_t flags);
796
797 int unlock();
798
799 void updatedMem (const QRect * aRect);
800
801 bool performDisplay (VBoxVHWASurfaceBase *pPrimary, bool bForce);
802
803 void setRects (const QRect & aTargRect, const QRect & aSrcRect);
804 void setTargRectPosition (const QPoint & aPoint);
805
806 void updateVisibility (VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect, bool bNotIntersected, bool bForce);
807
808 static ulong calcBytesPerPixel (GLenum format, GLenum type);
809
810 static GLsizei makePowerOf2 (GLsizei val);
811
812 bool addressAlocated() const { return mFreeAddress; }
813 uchar * address() { return mAddress; }
814
815 ulong memSize();
816
817 ulong width() const { return mRect.width(); }
818 ulong height() const { return mRect.height(); }
819 const QSize size() const {return mRect.size();}
820
821 uint32_t fourcc() const {return mImage->pixelFormat().fourcc(); }
822
823 ulong bitsPerPixel() const { return mImage->pixelFormat().bitsPerPixel(); }
824 ulong bytesPerLine() const { return mImage->bytesPerLine(); }
825
826 const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
827 const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
828 const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
829 const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
830 const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
831 const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
832 void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
833 void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
834
835 void setDstBltCKey (const VBoxVHWAColorKey * ckey)
836 {
837 if(ckey)
838 {
839 mDstBltCKey = *ckey;
840 mpDstBltCKey = &mDstBltCKey;
841 }
842 else
843 {
844 mpDstBltCKey = NULL;
845 }
846 }
847
848 void setSrcBltCKey (const VBoxVHWAColorKey * ckey)
849 {
850 if(ckey)
851 {
852 mSrcBltCKey = *ckey;
853 mpSrcBltCKey = &mSrcBltCKey;
854 }
855 else
856 {
857 mpSrcBltCKey = NULL;
858 }
859 }
860
861 void setDefaultDstOverlayCKey (const VBoxVHWAColorKey * ckey)
862 {
863 if(ckey)
864 {
865 mDefaultDstOverlayCKey = *ckey;
866 mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
867 }
868 else
869 {
870 mpDefaultDstOverlayCKey = NULL;
871 }
872 }
873
874 void setDefaultSrcOverlayCKey (const VBoxVHWAColorKey * ckey)
875 {
876 if(ckey)
877 {
878 mDefaultSrcOverlayCKey = *ckey;
879 mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
880 }
881 else
882 {
883 mpDefaultSrcOverlayCKey = NULL;
884 }
885 }
886
887 void setOverriddenDstOverlayCKey (const VBoxVHWAColorKey * ckey)
888 {
889 if(ckey)
890 {
891 mOverriddenDstOverlayCKey = *ckey;
892 mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
893 }
894 else
895 {
896 mpDstOverlayCKey = NULL;
897 }
898 }
899
900 void setOverriddenSrcOverlayCKey (const VBoxVHWAColorKey * ckey)
901 {
902 if(ckey)
903 {
904 mOverriddenSrcOverlayCKey = *ckey;
905 mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
906 }
907 else
908 {
909 mpSrcOverlayCKey = NULL;
910 }
911 }
912
913 const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
914 {
915 return mpSrcOverlayCKey;
916 }
917
918 const VBoxVHWAColorKey * getActiveDstOverlayCKey (VBoxVHWASurfaceBase * pPrimary)
919 {
920 return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : (pPrimary ? pPrimary->mpDstOverlayCKey : NULL);
921 }
922
923 const VBoxVHWAColorFormat & pixelFormat() const { return mImage->pixelFormat(); }
924
925 void setAddress(uchar * addr);
926
927 const QRect& rect() const {return mRect;}
928 const QRect& srcRect() const {return mSrcRect; }
929 const QRect& targRect() const {return mTargRect; }
930 class VBoxVHWASurfList * getComplexList() {return mComplexList; }
931
932 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
933
934 uint32_t handle() const {return mHGHandle;}
935 void setHandle(uint32_t h) {mHGHandle = h;}
936
937 const VBoxVHWADirtyRect & getDirtyRect() { return mUpdateMem2TexRect; }
938
939 VBoxVHWASurfaceBase * primary() { return mpPrimary; }
940 void setPrimary(VBoxVHWASurfaceBase *apPrimary) { mpPrimary = apPrimary; }
941private:
942 void setRectValues (const QRect & aTargRect, const QRect & aSrcRect);
943 void setVisibleRectValues (const QRect & aVisTargRect);
944
945 void setComplexList (VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
946 void initDisplay();
947
948 bool synchTexMem (const QRect * aRect);
949
950 int performBlt (const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
951
952 QRect mRect; /* == Inv FB size */
953
954 QRect mSrcRect;
955 QRect mTargRect; /* == Vis FB size */
956
957 QRect mVisibleTargRect;
958 QRect mVisibleSrcRect;
959
960 class VBoxVHWATextureImage * mImage;
961
962 uchar * mAddress;
963
964 VBoxVHWAColorKey *mpSrcBltCKey;
965 VBoxVHWAColorKey *mpDstBltCKey;
966 VBoxVHWAColorKey *mpSrcOverlayCKey;
967 VBoxVHWAColorKey *mpDstOverlayCKey;
968
969 VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
970 VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
971
972 VBoxVHWAColorKey mSrcBltCKey;
973 VBoxVHWAColorKey mDstBltCKey;
974 VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
975 VBoxVHWAColorKey mOverriddenDstOverlayCKey;
976 VBoxVHWAColorKey mDefaultDstOverlayCKey;
977 VBoxVHWAColorKey mDefaultSrcOverlayCKey;
978
979 int mLockCount;
980 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
981 VBoxVHWADirtyRect mUpdateMem2TexRect;
982
983 bool mFreeAddress;
984 bool mbNotIntersected;
985
986 class VBoxVHWASurfList *mComplexList;
987
988 VBoxVHWASurfaceBase *mpPrimary;
989
990 uint32_t mHGHandle;
991
992 class VBoxVHWAImage *mpImage;
993
994#ifdef DEBUG
995public:
996 uint64_t cFlipsCurr;
997 uint64_t cFlipsTarg;
998#endif
999 friend class VBoxVHWASurfList;
1000};
1001
1002typedef std::list <VBoxVHWASurfaceBase*> SurfList;
1003typedef std::list <VBoxVHWASurfList*> OverlayList;
1004typedef std::list <struct VBOXVHWACMD *> VHWACommandList;
1005
1006class VBoxVHWASurfList
1007{
1008public:
1009
1010 VBoxVHWASurfList() : mCurrent(NULL) {}
1011 void add(VBoxVHWASurfaceBase *pSurf)
1012 {
1013 VBoxVHWASurfList * pOld = pSurf->getComplexList();
1014 if(pOld)
1015 {
1016 pOld->remove(pSurf);
1017 }
1018 mSurfaces.push_back(pSurf);
1019 pSurf->setComplexList(this);
1020 }
1021
1022 void clear()
1023 {
1024 for (SurfList::iterator it = mSurfaces.begin();
1025 it != mSurfaces.end(); ++ it)
1026 {
1027 (*it)->setComplexList(NULL);
1028 }
1029 mSurfaces.clear();
1030 mCurrent = NULL;
1031 }
1032
1033 size_t size() const {return mSurfaces.size(); }
1034
1035 void remove(VBoxVHWASurfaceBase *pSurf)
1036 {
1037 mSurfaces.remove(pSurf);
1038 pSurf->setComplexList(NULL);
1039 if(mCurrent == pSurf)
1040 mCurrent = NULL;
1041 }
1042
1043 bool empty() { return mSurfaces.empty(); }
1044
1045 void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
1046 {
1047 mCurrent = pSurf;
1048 }
1049
1050 VBoxVHWASurfaceBase * current() { return mCurrent; }
1051 const SurfList & surfaces() const {return mSurfaces;}
1052
1053private:
1054
1055 SurfList mSurfaces;
1056 VBoxVHWASurfaceBase* mCurrent;
1057};
1058
1059class VBoxVHWADisplay
1060{
1061public:
1062 VBoxVHWADisplay() :
1063 mSurfVGA(NULL),
1064 mbDisplayPrimary(true)
1065// ,
1066// mSurfPrimary(NULL)
1067 {}
1068
1069 VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
1070 {
1071 VBoxVHWASurfaceBase * old = mSurfVGA;
1072 mSurfVGA = pVga;
1073 mPrimary.clear();
1074 if(pVga)
1075 {
1076 Assert(!pVga->getComplexList());
1077 mPrimary.add(pVga);
1078 mPrimary.setCurrentVisible(pVga);
1079 }
1080 mOverlays.clear();
1081 return old;
1082 }
1083
1084 VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
1085 {
1086 VBoxVHWASurfaceBase * old = mSurfVGA;
1087 Assert(old);
1088 mSurfVGA = pVga;
1089 return old;
1090 }
1091
1092 VBoxVHWASurfaceBase * getVGA() const
1093 {
1094 return mSurfVGA;
1095 }
1096
1097 VBoxVHWASurfaceBase * getPrimary()
1098 {
1099 return mPrimary.current();
1100 }
1101
1102 void addOverlay(VBoxVHWASurfList * pSurf)
1103 {
1104 mOverlays.push_back(pSurf);
1105 }
1106
1107 void checkAddOverlay(VBoxVHWASurfList * pSurf)
1108 {
1109 if(!hasOverlay(pSurf))
1110 addOverlay(pSurf);
1111 }
1112
1113 bool hasOverlay(VBoxVHWASurfList * pSurf)
1114 {
1115 for (OverlayList::iterator it = mOverlays.begin();
1116 it != mOverlays.end(); ++ it)
1117 {
1118 if((*it) == pSurf)
1119 {
1120 return true;
1121 }
1122 }
1123 return false;
1124 }
1125
1126 void removeOverlay(VBoxVHWASurfList * pSurf)
1127 {
1128 mOverlays.remove(pSurf);
1129 }
1130
1131 bool performDisplay(bool bForce)
1132 {
1133 VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
1134
1135 if(mbDisplayPrimary)
1136 {
1137#ifdef DEBUG_misha
1138 /* should only display overlay now */
1139 AssertBreakpoint();
1140#endif
1141 bForce |= pPrimary->performDisplay(NULL, bForce);
1142 }
1143
1144 for (OverlayList::const_iterator it = mOverlays.begin();
1145 it != mOverlays.end(); ++ it)
1146 {
1147 VBoxVHWASurfaceBase * pOverlay = (*it)->current();
1148 if(pOverlay)
1149 {
1150 bForce |= pOverlay->performDisplay(pPrimary, bForce);
1151 }
1152 }
1153 return bForce;
1154 }
1155
1156 bool isPrimary(VBoxVHWASurfaceBase * pSurf) { return pSurf->getComplexList() == &mPrimary; }
1157
1158 void setDisplayPrimary(bool bDisplay) { mbDisplayPrimary = bDisplay; }
1159
1160 const OverlayList & overlays() const {return mOverlays;}
1161 const VBoxVHWASurfList & primaries() const { return mPrimary; }
1162
1163private:
1164 VBoxVHWASurfaceBase *mSurfVGA;
1165 VBoxVHWASurfList mPrimary;
1166
1167 OverlayList mOverlays;
1168
1169 bool mbDisplayPrimary;
1170};
1171
1172typedef void (*PFNVBOXQGLFUNC)(void*, void*);
1173
1174typedef enum
1175{
1176 VBOXVHWA_PIPECMD_PAINT = 1,
1177 VBOXVHWA_PIPECMD_VHWA,
1178 VBOXVHWA_PIPECMD_FUNC
1179}VBOXVHWA_PIPECMD_TYPE;
1180
1181typedef struct VBOXVHWAFUNCCALLBACKINFO
1182{
1183 PFNVBOXQGLFUNC pfnCallback;
1184 void * pContext1;
1185 void * pContext2;
1186}VBOXVHWAFUNCCALLBACKINFO;
1187
1188class VBoxVHWACommandElement
1189{
1190public:
1191 VBoxVHWACommandElement() :
1192 bNewEvent(false)
1193 {}
1194
1195 void setVHWACmd(struct VBOXVHWACMD * pCmd)
1196 {
1197 mType = VBOXVHWA_PIPECMD_VHWA;
1198 u.mpCmd = pCmd;
1199 }
1200
1201 void setPaintCmd(const QRect & aRect)
1202 {
1203 mType = VBOXVHWA_PIPECMD_PAINT;
1204 mRect = aRect;
1205 }
1206
1207 void setFunc(const VBOXVHWAFUNCCALLBACKINFO & aOp)
1208 {
1209 mType = VBOXVHWA_PIPECMD_FUNC;
1210 u.mFuncCallback = aOp;
1211 }
1212
1213 void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
1214 {
1215 switch(aType)
1216 {
1217 case VBOXVHWA_PIPECMD_PAINT:
1218 setPaintCmd(*((QRect*)pvData));
1219 break;
1220 case VBOXVHWA_PIPECMD_VHWA:
1221 setVHWACmd((struct VBOXVHWACMD *)pvData);
1222 break;
1223 case VBOXVHWA_PIPECMD_FUNC:
1224 setFunc(*((VBOXVHWAFUNCCALLBACKINFO *)pvData));
1225 break;
1226 default:
1227 Assert(0);
1228 break;
1229 }
1230 }
1231
1232 void setNewEvent(bool bNew) {bNewEvent = bNew;}
1233 bool isNewEvent() const { return bNewEvent; }
1234
1235 VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
1236 const QRect & rect() const {return mRect;}
1237 struct VBOXVHWACMD * vhwaCmd() const {return u.mpCmd;}
1238 const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
1239
1240 VBoxVHWACommandElement * mpNext;
1241private:
1242 VBOXVHWA_PIPECMD_TYPE mType;
1243 union
1244 {
1245 struct VBOXVHWACMD * mpCmd;
1246 VBOXVHWAFUNCCALLBACKINFO mFuncCallback;
1247 }u;
1248 QRect mRect;
1249 bool bNewEvent;
1250};
1251
1252class VBoxVHWACommandElementPipe
1253{
1254public:
1255 VBoxVHWACommandElementPipe() :
1256 mpFirst(NULL),
1257 mpLast(NULL)
1258 {}
1259
1260 void put(VBoxVHWACommandElement *pCmd)
1261 {
1262 if (mpLast)
1263 {
1264 Assert(mpFirst);
1265 mpLast->mpNext = pCmd;
1266 mpLast = pCmd;
1267 }
1268 else
1269 {
1270 Assert(!mpFirst);
1271 mpFirst = pCmd;
1272 mpLast = pCmd;
1273 }
1274 pCmd->mpNext= NULL;
1275
1276 }
1277
1278 void setFrom(VBoxVHWACommandElementPipe *pOther)
1279 {
1280 mpFirst = pOther->detachList(&mpLast);
1281 }
1282
1283 void set(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1284 {
1285 mpFirst = pFirst;
1286 mpLast = pLast;
1287 if (mpLast)
1288 mpLast->mpNext = NULL;
1289 }
1290
1291 void prepend(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1292 {
1293 if (!mpFirst)
1294 set(pFirst, pLast);
1295 else if (pLast)
1296 {
1297 pLast->mpNext = mpFirst;
1298 mpFirst = pFirst;
1299 }
1300 }
1301
1302 void prependFrom(VBoxVHWACommandElementPipe *pOther)
1303 {
1304 VBoxVHWACommandElement *pFirst;
1305 VBoxVHWACommandElement *pLast;
1306 pFirst = pOther->detachList(&pLast);
1307 prepend(pFirst, pLast);
1308 }
1309
1310 void append(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1311 {
1312 if (!mpLast)
1313 set(pFirst, pLast);
1314 else if (pLast)
1315 {
1316 mpLast->mpNext = pFirst;
1317 mpLast = pLast;
1318 pLast->mpNext = NULL;
1319 }
1320 }
1321
1322 VBoxVHWACommandElement * detachList(VBoxVHWACommandElement **ppLast)
1323 {
1324 if (mpLast)
1325 {
1326 VBoxVHWACommandElement * pHead = mpFirst;
1327 if (ppLast)
1328 *ppLast = mpLast;
1329 mpFirst = NULL;
1330 mpLast = NULL;
1331 return pHead;
1332 }
1333 if (ppLast)
1334 *ppLast = NULL;
1335 return NULL;
1336 }
1337
1338
1339
1340 const VBoxVHWACommandElement * contentsRo (const VBoxVHWACommandElement **ppLast) const
1341 {
1342 if (ppLast)
1343 *ppLast = mpLast;
1344 return mpFirst;
1345 }
1346
1347 bool isEmpty() const { return !mpLast; }
1348
1349private:
1350 VBoxVHWACommandElement *mpFirst;
1351 VBoxVHWACommandElement *mpLast;
1352};
1353
1354class VBoxVHWACommandElementStack
1355{
1356public:
1357 VBoxVHWACommandElementStack() :
1358 mpFirst(NULL) {}
1359
1360 void push(VBoxVHWACommandElement *pCmd)
1361 {
1362 pCmd->mpNext = mpFirst;
1363 mpFirst = pCmd;
1364 }
1365
1366 void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1367 {
1368 pLast->mpNext = mpFirst;
1369 mpFirst = pFirst;
1370 }
1371
1372 VBoxVHWACommandElement * pop()
1373 {
1374 if(mpFirst)
1375 {
1376 VBoxVHWACommandElement * ret = mpFirst;
1377 mpFirst = ret->mpNext;
1378 return ret;
1379 }
1380 return NULL;
1381 }
1382private:
1383 VBoxVHWACommandElement *mpFirst;
1384};
1385
1386class VBoxVHWARefCounter
1387{
1388#define VBOXVHWA_INIFITE_WAITCOUNT (~0U)
1389public:
1390 VBoxVHWARefCounter() : m_cRefs(0) {}
1391 VBoxVHWARefCounter(uint32_t cRefs) : m_cRefs(cRefs) {}
1392 void inc() { ASMAtomicIncU32(&m_cRefs); }
1393 uint32_t dec()
1394 {
1395 uint32_t cRefs = ASMAtomicDecU32(&m_cRefs);
1396 Assert(cRefs < UINT32_MAX / 2);
1397 return cRefs;
1398 }
1399
1400 uint32_t refs() { return ASMAtomicReadU32(&m_cRefs); }
1401
1402 int wait0(RTMSINTERVAL ms = 1000, uint32_t cWaits = VBOXVHWA_INIFITE_WAITCOUNT)
1403 {
1404 int rc = VINF_SUCCESS;
1405 do
1406 {
1407 if (!refs())
1408 break;
1409 if (!cWaits)
1410 {
1411 rc = VERR_TIMEOUT;
1412 break;
1413 }
1414 if (cWaits != VBOXVHWA_INIFITE_WAITCOUNT)
1415 --cWaits;
1416 rc = RTThreadSleep(ms);
1417 AssertRC(rc);
1418 if (!RT_SUCCESS(rc))
1419 break;
1420 } while(1);
1421 return rc;
1422 }
1423private:
1424 volatile uint32_t m_cRefs;
1425};
1426
1427#define VBOXVHWACMDPIPEC_NEWEVENT 0x00000001
1428#define VBOXVHWACMDPIPEC_COMPLETEEVENT 0x00000002
1429class VBoxVHWACommandElementProcessor
1430{
1431public:
1432 VBoxVHWACommandElementProcessor(QObject *pNotifyObject);
1433 ~VBoxVHWACommandElementProcessor();
1434 void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags);
1435 bool completeCurrentEvent();
1436 class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement ** ppLast,
1437 class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
1438 void putBack(class VBoxVHWACommandElement * pFirst2Put, VBoxVHWACommandElement * pLast2Put,
1439 class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
1440 void reset(class VBoxVHWACommandElement ** ppHead, class VBoxVHWACommandElement ** ppTail);
1441 void setNotifyObject(QObject *pNotifyObject);
1442 int loadExec (struct SSMHANDLE * pSSM, uint32_t u32Version, void *pvVRAM);
1443 void saveExec (struct SSMHANDLE * pSSM, void *pvVRAM);
1444 void disable();
1445 void enable();
1446 void lock();
1447 void unlock();
1448#ifdef DEBUG_misha
1449 void checkConsistence(uint32_t cEvents2Submit = 0, const VBoxVHWACommandElementPipe *pPipe = NULL);
1450#endif
1451private:
1452 RTCRITSECT mCritSect;
1453 VBoxVHWACommandElementPipe m_CmdPipe;
1454 QObject *m_pNotifyObject;
1455 VBoxVHWARefCounter m_NotifyObjectRefs;
1456 bool mbNewEvent;
1457 bool mbProcessingList;
1458 uint32_t mcDisabled;
1459 VBoxVHWACommandElementStack mFreeElements;
1460 VBoxVHWACommandElement mElementsBuffer[2048];
1461};
1462
1463/* added to workaround this ** [VBox|UI] duplication */
1464class VBoxFBSizeInfo
1465{
1466public:
1467 VBoxFBSizeInfo() {}
1468 template<class T> VBoxFBSizeInfo(T * fb) :
1469 mPixelFormat(fb->pixelFormat()), mVRAM(fb->address()), mBitsPerPixel(fb->bitsPerPixel()),
1470 mBytesPerLine(fb->bytesPerLine()), mWidth(fb->width()), mHeight(fb->height()),
1471 mUsesGuestVram(fb->usesGuestVRAM()) {}
1472
1473 VBoxFBSizeInfo(ulong aPixelFormat, uchar *aVRAM,
1474 ulong aBitsPerPixel, ulong aBytesPerLine,
1475 ulong aWidth, ulong aHeight,
1476 bool bUsesGuestVram) :
1477 mPixelFormat (aPixelFormat), mVRAM (aVRAM), mBitsPerPixel (aBitsPerPixel),
1478 mBytesPerLine (aBytesPerLine), mWidth (aWidth), mHeight (aHeight),
1479 mUsesGuestVram(bUsesGuestVram) {}
1480 ulong pixelFormat() const { return mPixelFormat; }
1481 uchar *VRAM() const { return mVRAM; }
1482 ulong bitsPerPixel() const { return mBitsPerPixel; }
1483 ulong bytesPerLine() const { return mBytesPerLine; }
1484 ulong width() const { return mWidth; }
1485 ulong height() const { return mHeight; }
1486 bool usesGuestVram() const {return mUsesGuestVram;}
1487
1488private:
1489 ulong mPixelFormat;
1490 uchar *mVRAM;
1491 ulong mBitsPerPixel;
1492 ulong mBytesPerLine;
1493 ulong mWidth;
1494 ulong mHeight;
1495 bool mUsesGuestVram;
1496};
1497
1498class VBoxVHWAImage
1499{
1500public:
1501 VBoxVHWAImage ();
1502 ~VBoxVHWAImage();
1503
1504 int init(VBoxVHWASettings *aSettings);
1505#ifdef VBOX_WITH_VIDEOHWACCEL
1506 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
1507 uint64_t vboxVRAMOffsetFromAddress(uchar* addr);
1508 uint64_t vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf);
1509
1510 void vhwaSaveExec(struct SSMHANDLE * pSSM);
1511 static void vhwaSaveExecVoid(struct SSMHANDLE * pSSM);
1512 static int vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1513
1514 int vhwaSurfaceCanCreate(struct VBOXVHWACMD_SURF_CANCREATE *pCmd);
1515 int vhwaSurfaceCreate(struct VBOXVHWACMD_SURF_CREATE *pCmd);
1516#ifdef VBOX_WITH_WDDM
1517 int vhwaSurfaceGetInfo(struct VBOXVHWACMD_SURF_GETINFO *pCmd);
1518#endif
1519 int vhwaSurfaceDestroy(struct VBOXVHWACMD_SURF_DESTROY *pCmd);
1520 int vhwaSurfaceLock(struct VBOXVHWACMD_SURF_LOCK *pCmd);
1521 int vhwaSurfaceUnlock(struct VBOXVHWACMD_SURF_UNLOCK *pCmd);
1522 int vhwaSurfaceBlt(struct VBOXVHWACMD_SURF_BLT *pCmd);
1523 int vhwaSurfaceFlip(struct VBOXVHWACMD_SURF_FLIP *pCmd);
1524 int vhwaSurfaceColorFill(struct VBOXVHWACMD_SURF_COLORFILL *pCmd);
1525 int vhwaSurfaceOverlayUpdate(struct VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
1526 int vhwaSurfaceOverlaySetPosition(struct VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
1527 int vhwaSurfaceColorkeySet(struct VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
1528 int vhwaQueryInfo1(struct VBOXVHWACMD_QUERYINFO1 *pCmd);
1529 int vhwaQueryInfo2(struct VBOXVHWACMD_QUERYINFO2 *pCmd);
1530 int vhwaConstruct(struct VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1531
1532 void *vramBase() { return mpvVRAM; }
1533 uint32_t vramSize() { return mcbVRAM; }
1534
1535 bool hasSurfaces() const;
1536 bool hasVisibleOverlays();
1537 QRect overlaysRectUnion();
1538 QRect overlaysRectIntersection();
1539#endif
1540
1541 static const QGLFormat & vboxGLFormat();
1542
1543 int reset(VHWACommandList * pCmdList);
1544
1545 int vboxFbWidth() {return mDisplay.getVGA()->width(); }
1546 int vboxFbHeight() {return mDisplay.getVGA()->height(); }
1547 bool isInitialized() {return mDisplay.getVGA() != NULL; }
1548
1549 void resize(const VBoxFBSizeInfo & size);
1550
1551 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
1552
1553 VBoxVHWASurfaceBase * vgaSurface() { return mDisplay.getVGA(); }
1554
1555#ifdef VBOXVHWA_OLD_COORD
1556 static void doSetupMatrix(const QSize & aSize, bool bInverted);
1557#endif
1558
1559 void vboxDoUpdateViewport(const QRect & aRect);
1560 void vboxDoUpdateRect(const QRect * pRect);
1561
1562 const QRect & vboxViewport() const {return mViewport;}
1563
1564#ifdef VBOXVHWA_PROFILE_FPS
1565 void reportNewFrame() { mbNewFrame = true; }
1566#endif
1567
1568 bool performDisplay(bool bForce)
1569 {
1570 bForce = mDisplay.performDisplay(bForce | mRepaintNeeded);
1571
1572#ifdef VBOXVHWA_PROFILE_FPS
1573 if(mbNewFrame)
1574 {
1575 mFPSCounter.frame();
1576 double fps = mFPSCounter.fps();
1577 if(!(mFPSCounter.frames() % 31))
1578 {
1579 LogRel(("fps: %f\n", fps));
1580 }
1581 mbNewFrame = false;
1582 }
1583#endif
1584 return bForce;
1585 }
1586
1587 static void pushSettingsAndSetupViewport(const QSize &display, const QRect &viewport)
1588 {
1589 glPushAttrib(GL_ALL_ATTRIB_BITS);
1590 glMatrixMode(GL_PROJECTION);
1591 glPushMatrix();
1592 setupMatricies(display, false);
1593 adjustViewport(display, viewport);
1594 }
1595
1596 static void popSettingsAfterSetupViewport()
1597 {
1598 glPopAttrib();
1599 glMatrixMode(GL_PROJECTION);
1600 glPopMatrix();
1601 glMatrixMode(GL_MODELVIEW);
1602 }
1603
1604private:
1605 static void setupMatricies(const QSize &display, bool bInvert);
1606 static void adjustViewport(const QSize &display, const QRect &viewport);
1607
1608
1609#ifdef VBOXQGL_DBG_SURF
1610 void vboxDoTestSurfaces(void *context);
1611#endif
1612#ifdef VBOX_WITH_VIDEOHWACCEL
1613
1614 void vboxCheckUpdateAddress(VBoxVHWASurfaceBase * pSurface, uint64_t offset)
1615 {
1616 if (pSurface->addressAlocated())
1617 {
1618 Assert(!mDisplay.isPrimary(pSurface));
1619 uchar * addr = vboxVRAMAddressFromOffset(offset);
1620 if (addr)
1621 {
1622 pSurface->setAddress(addr);
1623 }
1624 }
1625 }
1626
1627 int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
1628 static int vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t cBackBuffers, uint32_t u32Version);
1629 int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
1630 static int vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1631 static int vhwaLoadVHWAEnable(VHWACommandList * pCmdList);
1632
1633 void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
1634#endif
1635
1636 VBoxVHWADisplay mDisplay;
1637
1638 VBoxVHWASurfaceBase* handle2Surface(uint32_t h)
1639 {
1640 VBoxVHWASurfaceBase* pSurf = (VBoxVHWASurfaceBase*)mSurfHandleTable.get(h);
1641 Assert(pSurf);
1642 return pSurf;
1643 }
1644
1645 VBoxVHWAHandleTable mSurfHandleTable;
1646
1647 bool mRepaintNeeded;
1648
1649 QRect mViewport;
1650
1651 VBoxVHWASurfList *mConstructingList;
1652 int32_t mcRemaining2Contruct;
1653
1654 class VBoxVHWAGlProgramMngr *mpMngr;
1655
1656 VBoxVHWASettings *mSettings;
1657
1658 void *mpvVRAM;
1659 uint32_t mcbVRAM;
1660
1661#ifdef VBOXVHWA_PROFILE_FPS
1662 VBoxVHWADbgTimer mFPSCounter;
1663 bool mbNewFrame;
1664#endif
1665};
1666
1667class VBoxGLWgt : public QGLWidget
1668{
1669public:
1670 VBoxGLWgt(VBoxVHWAImage * pImage,
1671 QWidget* parent, const QGLWidget* shareWidget);
1672
1673protected:
1674 void paintGL()
1675 {
1676 mpImage->performDisplay(true);
1677 }
1678private:
1679 VBoxVHWAImage * mpImage;
1680};
1681
1682class VBoxVHWAFBO
1683{
1684public:
1685 VBoxVHWAFBO() :
1686 mFBO(0)
1687 {}
1688
1689 ~VBoxVHWAFBO()
1690 {
1691 if(mFBO)
1692 {
1693 vboxglDeleteFramebuffers(1, &mFBO);
1694 }
1695 }
1696
1697 void init()
1698 {
1699 VBOXQGL_CHECKERR(
1700 vboxglGenFramebuffers(1, &mFBO);
1701 );
1702 }
1703
1704 void bind()
1705 {
1706 VBOXQGL_CHECKERR(
1707 vboxglBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1708 );
1709 }
1710
1711 void unbind()
1712 {
1713 VBOXQGL_CHECKERR(
1714 vboxglBindFramebuffer(GL_FRAMEBUFFER, 0);
1715 );
1716 }
1717
1718 void attachBound(VBoxVHWATexture *pTex)
1719 {
1720 VBOXQGL_CHECKERR(
1721 vboxglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pTex->texTarget(), pTex->texture(), 0);
1722 );
1723 }
1724
1725private:
1726 GLuint mFBO;
1727};
1728
1729template <class T>
1730class VBoxVHWATextureImageFBO : public T
1731{
1732public:
1733 VBoxVHWATextureImageFBO(const QRect &size, const VBoxVHWAColorFormat &format, class VBoxVHWAGlProgramMngr * aMgr, VBOXVHWAIMG_TYPE flags) :
1734 T(size, format, aMgr, flags & (~(VBOXVHWAIMG_FBO | VBOXVHWAIMG_LINEAR))),
1735 mFBOTex(size, VBoxVHWAColorFormat(32, 0xff0000, 0xff00, 0xff), aMgr, (flags & (~VBOXVHWAIMG_FBO))),
1736 mpvFBOTexMem(NULL)
1737 {
1738 }
1739
1740 virtual ~VBoxVHWATextureImageFBO()
1741 {
1742 if(mpvFBOTexMem)
1743 free(mpvFBOTexMem);
1744 }
1745
1746 virtual void init(uchar *pvMem)
1747 {
1748 mFBO.init();
1749 mpvFBOTexMem = (uchar*)malloc(mFBOTex.memSize());
1750 mFBOTex.init(mpvFBOTexMem);
1751 T::init(pvMem);
1752 mFBO.bind();
1753 mFBO.attachBound(mFBOTex.component(0));
1754 mFBO.unbind();
1755 }
1756
1757 virtual int createDisplay(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
1758 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected,
1759 GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram)
1760 {
1761 T::createDisplay(NULL, &mFBOTex.rect(), &rect(),
1762 NULL, NULL, false,
1763 pDisplay, ppProgram);
1764
1765 return mFBOTex.initDisplay(pDst, pDstRect, pSrcRect,
1766 pDstCKey, pSrcCKey, bNotIntersected);
1767 }
1768
1769 virtual void update(const QRect * pRect)
1770 {
1771 T::update(pRect);
1772
1773 VBoxVHWAImage::pushSettingsAndSetupViewport(rect().size(), rect());
1774 mFBO.bind();
1775 T::display();
1776 mFBO.unbind();
1777 VBoxVHWAImage::popSettingsAfterSetupViewport();
1778 }
1779
1780 virtual void display(VBoxVHWATextureImage *pDst, const QRect * pDstRect, const QRect * pSrcRect,
1781 const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool bNotIntersected)
1782 {
1783 mFBOTex.display(pDst, pDstRect, pSrcRect, pDstCKey, pSrcCKey, bNotIntersected);
1784 }
1785
1786 virtual void display()
1787 {
1788 mFBOTex.display();
1789 }
1790
1791 const QRect &rect() { return T::rect(); }
1792private:
1793 VBoxVHWAFBO mFBO;
1794 VBoxVHWATextureImage mFBOTex;
1795 uchar * mpvFBOTexMem;
1796};
1797
1798class VBoxQGLOverlay
1799{
1800public:
1801 VBoxQGLOverlay(QWidget *pViewport, QObject *pPostEventObject, CSession * aSession, uint32_t id);
1802 ~VBoxQGLOverlay()
1803 {
1804 if (mpShareWgt)
1805 delete mpShareWgt;
1806 }
1807
1808 void updateAttachment(QWidget *pViewport, QObject *pPostEventObject);
1809
1810 int onVHWACommand (struct VBOXVHWACMD * pCommand);
1811
1812 void onVHWACommandEvent (QEvent * pEvent);
1813
1814 /**
1815 * to be called on NotifyUpdate framebuffer call
1816 * @return true if the request was processed & should not be forwarded to the framebuffer
1817 * false - otherwise */
1818 bool onNotifyUpdate (ULONG aX, ULONG aY,
1819 ULONG aW, ULONG aH);
1820
1821 /**
1822 * to be called on RequestResize framebuffer call
1823 * @return true if the request was processed & should not be forwarded to the framebuffer
1824 * false - otherwise */
1825 bool onRequestResize (ULONG aScreenId, ULONG uPixelFormat,
1826 BYTE * pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
1827 ULONG uWidth, ULONG uHeight,
1828 HRESULT *pResult,
1829 BOOL * pbFinished)
1830 {
1831 Q_UNUSED(aScreenId);
1832 Q_UNUSED(uPixelFormat);
1833 Q_UNUSED(pVRAM);
1834 Q_UNUSED(uBitsPerPixel);
1835 Q_UNUSED(uBytesPerLine);
1836 Q_UNUSED(uWidth);
1837 Q_UNUSED(uHeight);
1838 Q_UNUSED(pbFinished);
1839
1840 if (mCmdPipe.completeCurrentEvent())
1841 return false;
1842
1843 /* TODO: more graceful resize handling */
1844 *pResult = E_FAIL;
1845
1846 return true;
1847 }
1848
1849 void onResizeEventPostprocess (const VBoxFBSizeInfo &re, const QPoint & topLeft);
1850
1851 void onViewportResized (QResizeEvent * /*re*/)
1852 {
1853 vboxDoCheckUpdateViewport();
1854 mGlCurrent = false;
1855 }
1856
1857 void onViewportScrolled (const QPoint & newTopLeft)
1858 {
1859 mContentsTopLeft = newTopLeft;
1860 vboxDoCheckUpdateViewport();
1861 mGlCurrent = false;
1862 }
1863
1864 static bool isAcceleration2DVideoAvailable();
1865
1866 /** additional video memory required for the best 2D support performance
1867 * total amount of VRAM required is thus calculated as requiredVideoMemory + required2DOffscreenVideoMemory */
1868 static quint64 required2DOffscreenVideoMemory();
1869
1870 /* not supposed to be called by clients */
1871 int vhwaLoadExec (struct SSMHANDLE * pSSM, uint32_t u32Version);
1872 void vhwaSaveExec (struct SSMHANDLE * pSSM);
1873private:
1874 int vhwaSurfaceUnlock (struct VBOXVHWACMD_SURF_UNLOCK *pCmd);
1875
1876 void repaintMain();
1877 void repaintOverlay()
1878 {
1879 if(mNeedOverlayRepaint)
1880 {
1881 mNeedOverlayRepaint = false;
1882 performDisplayOverlay();
1883 }
1884 if(mNeedSetVisible)
1885 {
1886 mNeedSetVisible = false;
1887 mpOverlayWgt->setVisible (true);
1888 }
1889 }
1890 void repaint()
1891 {
1892 repaintOverlay();
1893 repaintMain();
1894 }
1895
1896 void makeCurrent()
1897 {
1898 if (!mGlCurrent)
1899 {
1900 mGlCurrent = true;
1901 mpOverlayWgt->makeCurrent();
1902 }
1903 }
1904
1905 void performDisplayOverlay()
1906 {
1907 if (mOverlayVisible)
1908 {
1909 makeCurrent();
1910 if (mOverlayImage.performDisplay(false))
1911 mpOverlayWgt->swapBuffers();
1912 }
1913 }
1914
1915 void vboxSetGlOn (bool on);
1916 bool vboxGetGlOn() { return mGlOn; }
1917 bool vboxSynchGl();
1918 void vboxDoVHWACmdExec(void *cmd);
1919 void vboxShowOverlay (bool show);
1920 void vboxDoCheckUpdateViewport();
1921 void vboxDoVHWACmd (void *cmd);
1922 void addMainDirtyRect (const QRect & aRect);
1923 void vboxCheckUpdateOverlay (const QRect & rect);
1924 VBoxVHWACommandElement * processCmdList (VBoxVHWACommandElement * pCmd, bool bFirst);
1925
1926 int vhwaConstruct (struct VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1927
1928 int reset();
1929
1930 int resetGl();
1931
1932 void initGl();
1933
1934 VBoxGLWgt *mpOverlayWgt;
1935 VBoxVHWAImage mOverlayImage;
1936 QWidget *mpViewport;
1937 bool mGlOn;
1938 bool mOverlayWidgetVisible;
1939 bool mOverlayVisible;
1940 bool mGlCurrent;
1941 bool mProcessingCommands;
1942 bool mNeedOverlayRepaint;
1943 bool mNeedSetVisible;
1944 QRect mOverlayViewport;
1945 VBoxVHWADirtyRect mMainDirtyRect;
1946
1947 VBoxVHWACommandElementProcessor mCmdPipe;
1948
1949 /* this is used in saved state restore to postpone surface restoration
1950 * till the framebuffer size is restored */
1951 VHWACommandList mOnResizeCmdList;
1952
1953 VBoxVHWASettings mSettings;
1954 CSession * mpSession;
1955
1956 VBoxFBSizeInfo mSizeInfo;
1957 VBoxFBSizeInfo mPostponedResize;
1958 QPoint mContentsTopLeft;
1959
1960 QGLWidget *mpShareWgt;
1961
1962 uint32_t m_id;
1963};
1964
1965/* these two additional class V, class R are to workaround the [VBox|UI] duplication,
1966 * @todo: remove them once VBox stuff is removed */
1967template <class T, class V, class R>
1968class VBoxOverlayFrameBuffer : public T
1969{
1970public:
1971 VBoxOverlayFrameBuffer (V *pView, CSession * aSession, uint32_t id)
1972 : T (pView),
1973 mOverlay(pView->viewport(), pView, aSession, id),
1974 mpView (pView)
1975 {
1976 /* sync with framebuffer */
1977 mOverlay.onResizeEventPostprocess (VBoxFBSizeInfo(this), QPoint(mpView->contentsX(), mpView->contentsY()));
1978 }
1979
1980 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand)
1981 {
1982 return mOverlay.onVHWACommand ((struct VBOXVHWACMD*)pCommand);
1983 }
1984
1985 void doProcessVHWACommand (QEvent * pEvent)
1986 {
1987 mOverlay.onVHWACommandEvent (pEvent);
1988 }
1989
1990 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
1991 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
1992 ULONG aWidth, ULONG aHeight,
1993 BOOL *aFinished)
1994 {
1995 HRESULT result;
1996 if (mOverlay.onRequestResize (aScreenId, aPixelFormat,
1997 aVRAM, aBitsPerPixel, aBytesPerLine,
1998 aWidth, aHeight,
1999 &result,
2000 aFinished))
2001 {
2002 return result;
2003 }
2004 return T::RequestResize (aScreenId, aPixelFormat,
2005 aVRAM, aBitsPerPixel, aBytesPerLine,
2006 aWidth, aHeight,
2007 aFinished);
2008 }
2009
2010 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
2011 ULONG aW, ULONG aH)
2012 {
2013 if (mOverlay.onNotifyUpdate (aX, aY, aW, aH))
2014 return S_OK;
2015 return T::NotifyUpdate (aX, aY, aW, aH);
2016 }
2017
2018 STDMETHOD(VideoModeSupported) (ULONG uWidth, ULONG uHeight, ULONG uBPP,
2019 BOOL *pbSupported)
2020 {
2021 /* TODO: tmp workaround: the lock should be moved to the calling code??
2022 * otherwise we may end up calling a null View */
2023 /* Todo: can we call VideoModeSupported with the lock held?
2024 * if not we can introduce a ref counting for the mpView usage
2025 * to ensure it stays alive till we need it*/
2026 HRESULT hr = T::Lock();
2027 HRESULT retHr = S_OK;
2028 Assert(hr == S_OK);
2029 if (SUCCEEDED(hr))
2030 {
2031 if (mpView)
2032 retHr = T::VideoModeSupported(uWidth, uHeight, uBPP, pbSupported);
2033 hr = T::Unlock();
2034 Assert(hr == S_OK);
2035 }
2036 return retHr;
2037 }
2038
2039 void resizeEvent (R *re)
2040 {
2041 T::resizeEvent (re);
2042 mOverlay.onResizeEventPostprocess (VBoxFBSizeInfo(this),
2043 QPoint(mpView->contentsX(), mpView->contentsY()));
2044 }
2045
2046 void viewportResized (QResizeEvent * re)
2047 {
2048 mOverlay.onViewportResized (re);
2049 T::viewportResized (re);
2050 }
2051
2052 void viewportScrolled (int dx, int dy)
2053 {
2054 mOverlay.onViewportScrolled (QPoint(mpView->contentsX(), mpView->contentsY()));
2055 T::viewportScrolled (dx, dy);
2056 }
2057
2058 void setView(V * pView)
2059 {
2060 /* lock to ensure we do not collide with the EMT thread passing commands to us */
2061 HRESULT hr = T::Lock();
2062 Assert(hr == S_OK);
2063 if (SUCCEEDED(hr))
2064 {
2065 T::setView(pView);
2066 mpView = pView;
2067 mOverlay.updateAttachment(pView ? pView->viewport() : NULL, pView);
2068 hr = T::Unlock();
2069 Assert(hr == S_OK);
2070 }
2071 }
2072private:
2073 VBoxQGLOverlay mOverlay;
2074 V *mpView;
2075};
2076
2077#endif
2078
2079#endif /* #ifndef __VBoxFBOverlay_h__ */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use