VirtualBox

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

Last change on this file since 25045 was 24925, checked in by vboxsync, 15 years ago

2d video: fix VM reset issues

File size: 41.5 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxFrameBuffer Overly classes declarations
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22#ifndef __VBoxFBOverlay_h__
23#define __VBoxFBOverlay_h__
24#if defined (VBOX_GUI_USE_QGL) || defined(VBOX_WITH_VIDEOHWACCEL)
25
26//#define VBOXQGL_PROF_BASE 1
27//#define VBOXQGL_DBG_SURF 1
28
29#include "COMDefs.h"
30#include <QGLWidget>
31#include <iprt/assert.h>
32#include <iprt/critsect.h>
33
34#include <VBox/VBoxGL2D.h>
35#include "VBoxFBOverlayCommon.h"
36
37#define VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY 1
38
39#ifdef DEBUG_misha
40# define VBOXVHWA_PROFILE_FPS
41#endif
42
43#ifdef DEBUG
44class VBoxVHWADbgTimer
45{
46public:
47 VBoxVHWADbgTimer(uint32_t cPeriods);
48 ~VBoxVHWADbgTimer();
49 void frame();
50 uint64_t everagePeriod() {return mPeriodSum / mcPeriods; }
51 double fps() {return ((double)1000000000.0) / everagePeriod(); }
52 uint64_t frames() {return mcFrames; }
53private:
54 uint64_t mPeriodSum;
55 uint64_t *mpaPeriods;
56 uint64_t mPrevTime;
57 uint64_t mcFrames;
58 uint32_t mcPeriods;
59 uint32_t miPeriod;
60};
61
62#endif
63
64class VBoxVHWADirtyRect
65{
66public:
67 VBoxVHWADirtyRect() :
68 mIsClear(true)
69 {}
70
71 VBoxVHWADirtyRect(const QRect & aRect)
72 {
73 if(aRect.isEmpty())
74 {
75 mIsClear = false;
76 mRect = aRect;
77 }
78 else
79 {
80 mIsClear = true;
81 }
82 }
83
84 bool isClear() const { return mIsClear; }
85
86 void add(const QRect & aRect)
87 {
88 if(aRect.isEmpty())
89 return;
90
91 mRect = mIsClear ? aRect : mRect.united(aRect);
92 mIsClear = false;
93 }
94
95 void add(const VBoxVHWADirtyRect & aRect)
96 {
97 if(aRect.isClear())
98 return;
99 add(aRect.rect());
100 }
101
102 void set(const QRect & aRect)
103 {
104 if(aRect.isEmpty())
105 {
106 mIsClear = true;
107 }
108 else
109 {
110 mRect = aRect;
111 mIsClear = false;
112 }
113 }
114
115 void clear() { mIsClear = true; }
116
117 const QRect & rect() const {return mRect;}
118
119 const QRect & toRect()
120 {
121 if(isClear())
122 {
123 mRect.setCoords(0, 0, -1, -1);
124 }
125 return mRect;
126 }
127
128 bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
129
130 bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
131
132 QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
133
134 bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
135
136 void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
137
138private:
139 QRect mRect;
140 bool mIsClear;
141};
142
143class VBoxVHWAColorKey
144{
145public:
146 VBoxVHWAColorKey() :
147 mUpper(0),
148 mLower(0)
149 {}
150
151 VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
152 mUpper(aUpper),
153 mLower(aLower)
154 {}
155
156 uint32_t upper() const {return mUpper; }
157 uint32_t lower() const {return mLower; }
158
159 bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
160private:
161 uint32_t mUpper;
162 uint32_t mLower;
163};
164
165class VBoxVHWAColorComponent
166{
167public:
168 VBoxVHWAColorComponent() :
169 mMask(0),
170 mRange(0),
171 mOffset(32),
172 mcBits(0)
173 {}
174
175 VBoxVHWAColorComponent(uint32_t aMask);
176
177 uint32_t mask() const { return mMask; }
178 uint32_t range() const { return mRange; }
179 uint32_t offset() const { return mOffset; }
180 uint32_t cBits() const { return mcBits; }
181 uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
182 float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
183private:
184 uint32_t mMask;
185 uint32_t mRange;
186 uint32_t mOffset;
187 uint32_t mcBits;
188};
189
190class VBoxVHWAColorFormat
191{
192public:
193
194// VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
195 VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
196 VBoxVHWAColorFormat(uint32_t fourcc);
197 VBoxVHWAColorFormat(){}
198 GLint internalFormat() const {return mInternalFormat; }
199 GLenum format() const {return mFormat; }
200 GLenum type() const {return mType; }
201 bool isValid() const {return mBitsPerPixel != 0; }
202 uint32_t fourcc() const {return mDataFormat;}
203 uint32_t bitsPerPixel() const { return mBitsPerPixel; }
204 uint32_t bitsPerPixelTex() const { return mBitsPerPixelTex; }
205// uint32_t bitsPerPixelDd() const { return mBitsPerPixelDd; }
206 void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
207 uint32_t widthCompression() const {return mWidthCompression;}
208 uint32_t heightCompression() const {return mHeightCompression;}
209 const VBoxVHWAColorComponent& r() const {return mR;}
210 const VBoxVHWAColorComponent& g() const {return mG;}
211 const VBoxVHWAColorComponent& b() const {return mB;}
212 const VBoxVHWAColorComponent& a() const {return mA;}
213
214 bool equals (const VBoxVHWAColorFormat & other) const;
215
216private:
217 void init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
218 void init(uint32_t fourcc);
219
220 GLint mInternalFormat;
221 GLenum mFormat;
222 GLenum mType;
223 uint32_t mDataFormat;
224
225 uint32_t mBitsPerPixel;
226 uint32_t mBitsPerPixelTex;
227// uint32_t mBitsPerPixelDd;
228 uint32_t mWidthCompression;
229 uint32_t mHeightCompression;
230 VBoxVHWAColorComponent mR;
231 VBoxVHWAColorComponent mG;
232 VBoxVHWAColorComponent mB;
233 VBoxVHWAColorComponent mA;
234};
235
236class VBoxVHWATexture
237{
238public:
239 VBoxVHWATexture() {}
240 VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat);
241 virtual ~VBoxVHWATexture();
242 virtual void init(uchar *pvMem);
243 void setAddress(uchar *pvMem) {mAddress = pvMem;}
244 void update(const QRect * pRect) { doUpdate(mAddress, pRect);}
245 void bind() {glBindTexture(texTarget(), mTexture);}
246
247 virtual void texCoord(int x, int y);
248 virtual void multiTexCoord(GLenum texUnit, int x, int y);
249
250// GLuint texture() {return mTexture;}
251 const QRect & texRect() {return mTexRect;}
252 const QRect & rect() {return mRect;}
253 uchar * address(){ return mAddress; }
254 uint32_t rectSizeTex(const QRect * pRect) {return pRect->width() * pRect->height() * mBytesPerPixelTex;}
255 uchar * pointAddress(int x, int y)
256 {
257 x = toXTex(x);
258 y = toYTex(y);
259 return pointAddressTex(x, y);
260 }
261 uint32_t pointOffsetTex(int x, int y) { return y*mBytesPerLine + x*mBytesPerPixelTex; }
262 uchar * pointAddressTex(int x, int y) { return mAddress + pointOffsetTex(x, y); }
263 int toXTex(int x) {return x/mColorFormat.widthCompression();}
264 int toYTex(int y) {return y/mColorFormat.heightCompression();}
265 ulong memSize(){ return mBytesPerLine * mRect.height(); }
266 uint32_t bytesPerLine() {return mBytesPerLine; }
267
268protected:
269 virtual void doUpdate(uchar * pAddress, const QRect * pRect);
270 virtual void initParams();
271 virtual void load();
272 virtual GLenum texTarget() {return GL_TEXTURE_2D; }
273
274
275 QRect mTexRect; /* texture size */
276 QRect mRect; /* img size */
277 uchar * mAddress;
278 GLuint mTexture;
279 uint32_t mBytesPerPixel;
280 uint32_t mBytesPerPixelTex;
281 uint32_t mBytesPerLine;
282 VBoxVHWAColorFormat mColorFormat;
283private:
284 void uninit();
285};
286
287class VBoxVHWATextureNP2 : public VBoxVHWATexture
288{
289public:
290 VBoxVHWATextureNP2() : VBoxVHWATexture() {}
291 VBoxVHWATextureNP2(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
292 VBoxVHWATexture(aRect, aFormat){
293 mTexRect = QRect(0, 0, aRect.width()/aFormat.widthCompression(), aRect.height()/aFormat.heightCompression());
294 }
295};
296
297class VBoxVHWATextureNP2Rect : public VBoxVHWATextureNP2
298{
299public:
300 VBoxVHWATextureNP2Rect() : VBoxVHWATextureNP2() {}
301 VBoxVHWATextureNP2Rect(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
302 VBoxVHWATextureNP2(aRect, aFormat){}
303
304 virtual void texCoord(int x, int y);
305 virtual void multiTexCoord(GLenum texUnit, int x, int y);
306protected:
307 virtual GLenum texTarget();
308};
309
310class VBoxVHWATextureNP2RectPBO : public VBoxVHWATextureNP2Rect
311{
312public:
313 VBoxVHWATextureNP2RectPBO() : VBoxVHWATextureNP2Rect() {}
314 VBoxVHWATextureNP2RectPBO(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
315 VBoxVHWATextureNP2Rect(aRect, aFormat){}
316 virtual ~VBoxVHWATextureNP2RectPBO();
317
318 virtual void init(uchar *pvMem);
319protected:
320 virtual void load();
321 virtual void doUpdate(uchar * pAddress, const QRect * pRect);
322private:
323 GLuint mPBO;
324};
325
326#ifdef VBOXVHWA_USE_TEXGROUP
327class VBoxVHWATextureGroup
328{
329public:
330 VBoxVHWATextureGroup()
331 {
332 init(0, 0);
333 }
334
335 VBoxVHWATextureGroup(uint32_t cTextures, uint32_t cBacks)
336 {
337 init(cTextures, cBacks);
338 }
339
340 ~VBoxVHWATextureGroup()
341 {
342 delete[] mppTextures;
343 delete[] mpDisplays;
344 }
345
346 VBoxVHWATexture*& operator[] (size_t i) { return mppCurTextures[i]; }
347 void swap()
348 {
349 mCur = ((++mCur) % mcSets);
350 if(mCur)
351 mppCurTextures += mcTextures;
352 else
353 mppCurTextures = mppTextures;
354 }
355 uint32_t numSets() { return mcSets; }
356
357 void init(uint32_t cTextures, uint32_t cBacks)
358 {
359 mCur = 0;
360 mcTextures = cTextures;
361 mcSets = cBacks + 1;
362 if(mcTextures)
363 {
364 mppTextures = new VBoxVHWATexture*[mcSets * cTextures];
365 mppCurTextures = mppTextures;
366 memset(mppTextures, 0, sizeof(mppTextures[0]) * mcSets * cTextures);
367 mpDisplays = new GLuint[mcSets];
368 memset(mpDisplays, 0, sizeof(mpDisplays[0]) * mcSets);
369 }
370 else
371 {
372 mppTextures = mppCurTextures = NULL;
373 mpDisplays = NULL;
374 }
375 }
376
377 GLuint& display() {return mpDisplays[mCur];}
378private:
379 VBoxVHWATexture **mppTextures;
380 VBoxVHWATexture **mppCurTextures;
381 GLuint * mpDisplays;
382 uint32_t mCur;
383 uint32_t mcTextures;
384 uint32_t mcSets;
385};
386#endif
387
388class VBoxVHWAHandleTable
389{
390public:
391 VBoxVHWAHandleTable(uint32_t initialSize);
392 ~VBoxVHWAHandleTable();
393 uint32_t put(void * data);
394 bool mapPut(uint32_t h, void * data);
395 void* get(uint32_t h);
396 void* remove(uint32_t h);
397private:
398 void doPut(uint32_t h, void * data);
399 void doRemove(uint32_t h);
400 void** mTable;
401 uint32_t mcSize;
402 uint32_t mcUsage;
403 uint32_t mCursor;
404};
405
406/* data flow:
407 * I. NON-Yinverted surface:
408 * 1.direct memory update (paint, lock/unlock):
409 * mem->tex->fb
410 * 2.blt
411 * srcTex->invFB->tex->fb
412 * |->mem
413 *
414 * II. Yinverted surface:
415 * 1.direct memory update (paint, lock/unlock):
416 * mem->tex->fb
417 * 2.blt
418 * srcTex->fb->tex
419 * |->mem
420 *
421 * III. flip support:
422 * 1. Yinverted<->NON-YInverted conversion :
423 * mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
424 * fb-->| |->mem
425 * */
426class VBoxVHWASurfaceBase
427{
428public:
429 VBoxVHWASurfaceBase(
430 class VBoxGLWidget *mWidget,
431#if 0
432 class VBoxVHWAGlContextState *aState,
433 bool aIsYInverted,
434#endif
435 const QSize & aSize,
436 const QRect & aTargRect,
437 const QRect & aSrcRect,
438 const QRect & aVisTargRect,
439 VBoxVHWAColorFormat & aColorFormat,
440 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
441 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
442#ifdef VBOXVHWA_USE_TEXGROUP
443 uint32_t cBackTex,
444#endif
445 bool bVGA);
446
447 virtual ~VBoxVHWASurfaceBase();
448
449 void init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
450
451 void uninit();
452
453 static void globalInit();
454
455// int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
456
457 int lock(const QRect * pRect, uint32_t flags);
458
459 int unlock();
460
461 void updatedMem(const QRect * aRect);
462
463 bool performDisplay(VBoxVHWASurfaceBase *pPrimary, bool bForce);
464
465 void setRects (const QRect & aTargRect, const QRect & aSrcRect);
466 void setTargRectPosition (const QPoint & aPoint);
467 void setVisibilityReinitFlag() { mNeedVisibilityReinit = true; }
468 void updateVisibility (VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect, bool bNotIntersected, bool bForce);
469
470 static ulong calcBytesPerPixel(GLenum format, GLenum type);
471
472 static GLsizei makePowerOf2(GLsizei val);
473
474 bool addressAlocated() const { return mFreeAddress; }
475 uchar * address(){ return mAddress; }
476
477 ulong memSize();
478
479 ulong width() { return mRect.width(); }
480 ulong height() { return mRect.height(); }
481 const QSize size() {return mRect.size();}
482
483 GLenum format() {return mColorFormat.format(); }
484 GLint internalFormat() { return mColorFormat.internalFormat(); }
485 GLenum type() { return mColorFormat.type(); }
486 uint32_t fourcc() {return mColorFormat.fourcc(); }
487
488// ulong bytesPerPixel() { return mpTex[0]->bytesPerPixel(); }
489 ulong bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
490// ulong bitsPerPixelDd() { return mColorFormat.bitsPerPixelDd(); }
491 ulong bytesPerLine() { return mpTex[0]->bytesPerLine(); }
492
493 const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
494 const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
495 const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
496 const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
497 const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
498 const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
499 void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
500 void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
501
502 void setDstBltCKey(const VBoxVHWAColorKey * ckey)
503 {
504 if(ckey)
505 {
506 mDstBltCKey = *ckey;
507 mpDstBltCKey = &mDstBltCKey;
508 }
509 else
510 {
511 mpDstBltCKey = NULL;
512 }
513 }
514
515 void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
516 {
517 if(ckey)
518 {
519 mSrcBltCKey = *ckey;
520 mpSrcBltCKey = &mSrcBltCKey;
521 }
522 else
523 {
524 mpSrcBltCKey = NULL;
525 }
526 }
527
528 void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
529 {
530 if(ckey)
531 {
532 mDefaultDstOverlayCKey = *ckey;
533 mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
534 }
535 else
536 {
537 mpDefaultDstOverlayCKey = NULL;
538 }
539 }
540
541 void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
542 {
543 if(ckey)
544 {
545 mDefaultSrcOverlayCKey = *ckey;
546 mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
547 }
548 else
549 {
550 mpDefaultSrcOverlayCKey = NULL;
551 }
552 }
553
554 void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
555 {
556 if(ckey)
557 {
558 mOverriddenDstOverlayCKey = *ckey;
559 mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
560 }
561 else
562 {
563 mpDstOverlayCKey = NULL;
564 }
565 }
566
567 void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
568 {
569 if(ckey)
570 {
571 mOverriddenSrcOverlayCKey = *ckey;
572 mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
573 }
574 else
575 {
576 mpSrcOverlayCKey = NULL;
577 }
578 }
579
580 const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
581 {
582 return mpSrcOverlayCKey;
583 }
584
585 const VBoxVHWAColorKey * getActiveDstOverlayCKey(VBoxVHWASurfaceBase * pPrimary)
586 {
587 return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : pPrimary->mpDstOverlayCKey;
588 }
589
590 const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
591
592 void setAddress(uchar * addr);
593
594 const QRect& rect() const {return mRect;}
595 const QRect& srcRect() const {return mSrcRect; }
596 const QRect& targRect() const {return mTargRect; }
597 class VBoxVHWASurfList * getComplexList() {return mComplexList; }
598
599 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
600 static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
601
602 uint32_t handle() const {return mHGHandle;}
603 void setHandle(uint32_t h) {mHGHandle = h;}
604
605 const VBoxVHWADirtyRect & getDirtyRect() { return mUpdateMem2TexRect; }
606
607 class VBoxVHWAGlProgramVHWA * getProgram(VBoxVHWASurfaceBase * pPrimary)
608 {
609 if(mVisibleDisplayInitialized)
610 return mpProgram;
611 return calcProgram(pPrimary);
612 }
613private:
614 class VBoxVHWAGlProgramVHWA * calcProgram(VBoxVHWASurfaceBase * pPrimary);
615 void setRectValues (const QRect & aTargRect, const QRect & aSrcRect);
616 void setVisibleRectValues (const QRect & aVisTargRect);
617
618 void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
619 void initDisplay(VBoxVHWASurfaceBase *pPrimary);
620 void deleteDisplay();
621
622 int createDisplay(VBoxVHWASurfaceBase *pPrimary, GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram);
623 void doDisplay(VBoxVHWASurfaceBase *pPrimary, bool bProgram, bool bBindDst);
624 bool synchTexMem(const QRect * aRect);
625
626 int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
627
628 void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
629 void doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex);
630 void doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex);
631
632 QRect mRect; /* == Inv FB size */
633
634 QRect mSrcRect;
635 QRect mTargRect; /* == Vis FB size */
636
637 QRect mVisibleTargRect;
638 QRect mVisibleSrcRect;
639
640#ifndef VBOXVHWA_USE_TEXGROUP
641 GLuint mVisibleDisplay;
642#endif
643 class VBoxVHWAGlProgramVHWA * mpProgram;
644
645 bool mVisibleDisplayInitialized;
646 bool mNeedVisibilityReinit;
647 bool mNotIntersected;
648
649 uchar * mAddress;
650#ifdef VBOXVHWA_USE_TEXGROUP
651 VBoxVHWATextureGroup mpTex;
652#else
653 VBoxVHWATexture *mpTex[3];
654#endif
655
656 VBoxVHWAColorFormat mColorFormat;
657
658 VBoxVHWAColorKey *mpSrcBltCKey;
659 VBoxVHWAColorKey *mpDstBltCKey;
660 VBoxVHWAColorKey *mpSrcOverlayCKey;
661 VBoxVHWAColorKey *mpDstOverlayCKey;
662
663 VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
664 VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
665
666 VBoxVHWAColorKey mSrcBltCKey;
667 VBoxVHWAColorKey mDstBltCKey;
668 VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
669 VBoxVHWAColorKey mOverriddenDstOverlayCKey;
670 VBoxVHWAColorKey mDefaultDstOverlayCKey;
671 VBoxVHWAColorKey mDefaultSrcOverlayCKey;
672
673 int mLockCount;
674 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
675 VBoxVHWADirtyRect mUpdateMem2TexRect;
676
677 bool mFreeAddress;
678
679 class VBoxVHWASurfList *mComplexList;
680
681 class VBoxGLWidget *mWidget;
682
683 uint32_t mHGHandle;
684
685#ifdef DEBUG
686public:
687 uint64_t cFlipsCurr;
688 uint64_t cFlipsTarg;
689#endif
690 friend class VBoxVHWASurfList;
691};
692
693typedef std::list <VBoxVHWASurfaceBase*> SurfList;
694typedef std::list <VBoxVHWASurfList*> OverlayList;
695typedef std::list <struct _VBOXVHWACMD *> VHWACommandList;
696
697class VBoxVHWASurfList
698{
699public:
700
701 VBoxVHWASurfList() : mCurrent(NULL) {}
702 void add(VBoxVHWASurfaceBase *pSurf)
703 {
704 VBoxVHWASurfList * pOld = pSurf->getComplexList();
705 if(pOld)
706 {
707 pOld->remove(pSurf);
708 }
709 mSurfaces.push_back(pSurf);
710 pSurf->setComplexList(this);
711 }
712
713 void clear()
714 {
715 for (SurfList::iterator it = mSurfaces.begin();
716 it != mSurfaces.end(); ++ it)
717 {
718 (*it)->setComplexList(NULL);
719 }
720 mSurfaces.clear();
721 mCurrent = NULL;
722 }
723
724 size_t size() const {return mSurfaces.size(); }
725
726 void remove(VBoxVHWASurfaceBase *pSurf)
727 {
728 mSurfaces.remove(pSurf);
729 pSurf->setComplexList(NULL);
730 if(mCurrent == pSurf)
731 mCurrent = NULL;
732 }
733
734 bool empty() { return mSurfaces.empty(); }
735
736 void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
737 {
738 mCurrent = pSurf;
739 }
740
741 VBoxVHWASurfaceBase * current() { return mCurrent; }
742 const SurfList & surfaces() const {return mSurfaces;}
743
744private:
745
746 SurfList mSurfaces;
747 VBoxVHWASurfaceBase* mCurrent;
748};
749
750class VBoxVHWADisplay
751{
752public:
753 VBoxVHWADisplay() :
754 mSurfVGA(NULL),
755 mbDisplayPrimary(true)
756// ,
757// mSurfPrimary(NULL)
758 {}
759
760 VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
761 {
762 VBoxVHWASurfaceBase * old = mSurfVGA;
763 mSurfVGA = pVga;
764 mPrimary.clear();
765 if(pVga)
766 {
767 Assert(!pVga->getComplexList());
768 mPrimary.add(pVga);
769 mPrimary.setCurrentVisible(pVga);
770 }
771// mSurfPrimary = pVga;
772 mOverlays.clear();
773 return old;
774 }
775
776 VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
777 {
778 VBoxVHWASurfaceBase * old = mSurfVGA;
779 Assert(old);
780 mSurfVGA = pVga;
781 return old;
782 }
783
784 VBoxVHWASurfaceBase * getVGA() const
785 {
786 return mSurfVGA;
787 }
788
789 VBoxVHWASurfaceBase * getPrimary()
790 {
791 return mPrimary.current();
792 }
793
794 void addOverlay(VBoxVHWASurfList * pSurf)
795 {
796 mOverlays.push_back(pSurf);
797 }
798
799 void checkAddOverlay(VBoxVHWASurfList * pSurf)
800 {
801 if(!hasOverlay(pSurf))
802 addOverlay(pSurf);
803 }
804
805 bool hasOverlay(VBoxVHWASurfList * pSurf)
806 {
807 for (OverlayList::iterator it = mOverlays.begin();
808 it != mOverlays.end(); ++ it)
809 {
810 if((*it) == pSurf)
811 {
812 return true;
813 }
814 }
815 return false;
816 }
817
818 void removeOverlay(VBoxVHWASurfList * pSurf)
819 {
820 mOverlays.remove(pSurf);
821 }
822
823 bool performDisplay(bool bForce)
824 {
825 VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
826
827 if(mbDisplayPrimary)
828 {
829#ifdef DEBUG_misha
830 /* should only display overlay now */
831 AssertBreakpoint();
832#endif
833 bForce |= pPrimary->performDisplay(NULL, bForce);
834 }
835
836 for (OverlayList::const_iterator it = mOverlays.begin();
837 it != mOverlays.end(); ++ it)
838 {
839 VBoxVHWASurfaceBase * pOverlay = (*it)->current();
840 if(pOverlay)
841 {
842 bForce |= pOverlay->performDisplay(pPrimary, bForce);
843 }
844 }
845 return bForce;
846 }
847
848 bool isPrimary(VBoxVHWASurfaceBase * pSurf) { return pSurf->getComplexList() == &mPrimary; }
849
850 void setDisplayPrimary(bool bDisplay) { mbDisplayPrimary = bDisplay; }
851
852 const OverlayList & overlays() const {return mOverlays;}
853 const VBoxVHWASurfList & primaries() const { return mPrimary; }
854
855private:
856 VBoxVHWASurfaceBase *mSurfVGA;
857 VBoxVHWASurfList mPrimary;
858
859 OverlayList mOverlays;
860
861 bool mbDisplayPrimary;
862};
863
864typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
865
866typedef void (*PFNVBOXQGLFUNC)(void*, void*);
867
868typedef enum
869{
870 VBOXVHWA_PIPECMD_PAINT = 1,
871 VBOXVHWA_PIPECMD_VHWA,
872 VBOXVHWA_PIPECMD_OP,
873 VBOXVHWA_PIPECMD_FUNC,
874}VBOXVHWA_PIPECMD_TYPE;
875
876typedef struct VBOXVHWACALLBACKINFO
877{
878 VBoxGLWidget *pThis;
879 PFNVBOXQGLOP pfnCallback;
880 void * pContext;
881}VBOXVHWACALLBACKINFO;
882
883typedef struct VBOXVHWAFUNCCALLBACKINFO
884{
885 PFNVBOXQGLFUNC pfnCallback;
886 void * pContext1;
887 void * pContext2;
888}VBOXVHWAFUNCCALLBACKINFO;
889
890class VBoxVHWACommandElement
891{
892public:
893 void setVHWACmd(struct _VBOXVHWACMD * pCmd)
894 {
895 mType = VBOXVHWA_PIPECMD_VHWA;
896 u.mpCmd = pCmd;
897 }
898
899 void setPaintCmd(const QRect & aRect)
900 {
901 mType = VBOXVHWA_PIPECMD_PAINT;
902 mRect = aRect;
903 }
904
905 void setOp(const VBOXVHWACALLBACKINFO & aOp)
906 {
907 mType = VBOXVHWA_PIPECMD_OP;
908 u.mCallback = aOp;
909 }
910
911 void setFunc(const VBOXVHWAFUNCCALLBACKINFO & aOp)
912 {
913 mType = VBOXVHWA_PIPECMD_FUNC;
914 u.mFuncCallback = aOp;
915 }
916
917 void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
918 {
919 switch(aType)
920 {
921 case VBOXVHWA_PIPECMD_PAINT:
922 setPaintCmd(*((QRect*)pvData));
923 break;
924 case VBOXVHWA_PIPECMD_VHWA:
925 setVHWACmd((struct _VBOXVHWACMD *)pvData);
926 break;
927 case VBOXVHWA_PIPECMD_OP:
928 setOp(*((VBOXVHWACALLBACKINFO *)pvData));
929 break;
930 case VBOXVHWA_PIPECMD_FUNC:
931 setFunc(*((VBOXVHWAFUNCCALLBACKINFO *)pvData));
932 break;
933 default:
934 Assert(0);
935 break;
936 }
937 }
938
939 VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
940 const QRect & rect() const {return mRect;}
941 struct _VBOXVHWACMD * vhwaCmd() const {return u.mpCmd;}
942 const VBOXVHWACALLBACKINFO & op() const {return u.mCallback; }
943 const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
944
945 VBoxVHWACommandElement * mpNext;
946private:
947 VBOXVHWA_PIPECMD_TYPE mType;
948 union
949 {
950 struct _VBOXVHWACMD * mpCmd;
951 VBOXVHWACALLBACKINFO mCallback;
952 VBOXVHWAFUNCCALLBACKINFO mFuncCallback;
953 }u;
954 QRect mRect;
955};
956
957class VBoxVHWACommandElementPipe
958{
959public:
960 VBoxVHWACommandElementPipe() :
961 mpFirst(NULL),
962 mpLast(NULL)
963 {}
964
965 void put(VBoxVHWACommandElement *pCmd)
966 {
967 if(mpLast)
968 {
969 Assert(mpFirst);
970 mpLast->mpNext = pCmd;
971 mpLast = pCmd;
972 }
973 else
974 {
975 Assert(!mpFirst);
976 mpFirst = pCmd;
977 mpLast = pCmd;
978 }
979 pCmd->mpNext= NULL;
980
981 }
982
983 VBoxVHWACommandElement * detachList()
984 {
985 if(mpLast)
986 {
987 VBoxVHWACommandElement * pHead = mpFirst;
988 mpFirst = NULL;
989 mpLast = NULL;
990 return pHead;
991 }
992 return NULL;
993 }
994private:
995 VBoxVHWACommandElement *mpFirst;
996 VBoxVHWACommandElement *mpLast;
997};
998
999class VBoxVHWACommandElementStack
1000{
1001public:
1002 VBoxVHWACommandElementStack() :
1003 mpFirst(NULL) {}
1004
1005 void push(VBoxVHWACommandElement *pCmd)
1006 {
1007 pCmd->mpNext = mpFirst;
1008 mpFirst = pCmd;
1009 }
1010
1011 void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
1012 {
1013 pLast->mpNext = mpFirst;
1014 mpFirst = pFirst;
1015 }
1016
1017 VBoxVHWACommandElement * pop()
1018 {
1019 if(mpFirst)
1020 {
1021 VBoxVHWACommandElement * ret = mpFirst;
1022 mpFirst = ret->mpNext;
1023 return ret;
1024 }
1025 return NULL;
1026 }
1027private:
1028 VBoxVHWACommandElement *mpFirst;
1029};
1030
1031#define VBOXVHWACMDPIPEC_NEWEVENT 0x00000001
1032#define VBOXVHWACMDPIPEC_COMPLETEEVENT 0x00000002
1033class VBoxVHWACommandElementProcessor
1034{
1035public:
1036 VBoxVHWACommandElementProcessor(class VBoxConsoleView *aView);
1037 ~VBoxVHWACommandElementProcessor();
1038 void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags);
1039 void completeCurrentEvent();
1040 class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
1041 void reset(class VBoxVHWACommandElement ** ppHead, class VBoxVHWACommandElement ** ppTail);
1042private:
1043 RTCRITSECT mCritSect;
1044 class VBoxVHWACommandProcessEvent *mpFirstEvent;
1045 class VBoxVHWACommandProcessEvent *mpLastEvent;
1046 class VBoxConsoleView *mView;
1047 bool mbNewEvent;
1048 bool mbProcessingList;
1049 VBoxVHWACommandElementStack mFreeElements;
1050 VBoxVHWACommandElement mElementsBuffer[2048];
1051};
1052
1053class VBoxVHWACommandsQueue
1054{
1055public:
1056 void enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2);
1057
1058 VBoxVHWACommandElement * detachList();
1059
1060 void freeList(VBoxVHWACommandElement * pList);
1061
1062private:
1063 VBoxVHWACommandElementPipe mCmds;
1064};
1065
1066class VBoxGLWidget : public QGLWidget
1067{
1068public:
1069 VBoxGLWidget (class VBoxConsoleView *aView, QWidget *aParent);
1070 ~VBoxGLWidget();
1071
1072 ulong vboxPixelFormat() { return mPixelFormat; }
1073 bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
1074
1075 uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
1076
1077#ifdef VBOX_WITH_VIDEOHWACCEL
1078 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
1079 uint64_t vboxVRAMOffsetFromAddress(uchar* addr);
1080 uint64_t vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf);
1081
1082 void vhwaSaveExec(struct SSMHANDLE * pSSM);
1083 static void vhwaSaveExecVoid(struct SSMHANDLE * pSSM);
1084 static int vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1085
1086 int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
1087 int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
1088 int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
1089 int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
1090 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1091 int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
1092 int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
1093 int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
1094 int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
1095 int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
1096 int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
1097 int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
1098 int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1099
1100 bool hasSurfaces() const;
1101 bool hasVisibleOverlays();
1102 QRect overlaysRectUnion();
1103 QRect overlaysRectIntersection();
1104#endif
1105
1106 int reset(VHWACommandList * pCmdList);
1107
1108 ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
1109 ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
1110 int vboxFbWidth() {return mDisplay.getVGA()->width(); }
1111 int vboxFbHeight() {return mDisplay.getVGA()->height(); }
1112 bool vboxIsInitialized() {return mDisplay.getVGA() != NULL; }
1113
1114 void vboxDoResize(void *re);
1115
1116// void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
1117 void vboxResizeEvent (class VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
1118
1119 void vboxProcessVHWACommands(class VBoxVHWACommandElementProcessor * pPipe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pPipe);}
1120
1121 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
1122
1123 VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
1124
1125#ifdef VBOXVHWA_OLD_COORD
1126 static void doSetupMatrix(const QSize & aSize, bool bInverted);
1127#endif
1128
1129 void vboxDoUpdateViewport(const QRect & aRect);
1130 void vboxDoUpdateRect(const QRect * pRect);
1131
1132 const QRect & vboxViewport() const {return mViewport;}
1133
1134#ifdef VBOXVHWA_PROFILE_FPS
1135 void reportNewFrame() { mbNewFrame = true; }
1136#endif
1137
1138 bool performDisplayAndSwap(bool bForce)
1139 {
1140// VBOXQGLLOG_METHODTIME("t:");
1141
1142 bForce = mDisplay.performDisplay(bForce | mRepaintNeeded);
1143 if(bForce)
1144 {
1145 swapBuffers();
1146 }
1147
1148#ifdef VBOXVHWA_PROFILE_FPS
1149 if(mbNewFrame)
1150 {
1151 mFPSCounter.frame();
1152 double fps = mFPSCounter.fps();
1153 if(!(mFPSCounter.frames() % 31))
1154 {
1155 printf("fps: %f\n", fps);
1156 }
1157 mbNewFrame = false;
1158 }
1159#endif
1160 return bForce;
1161 }
1162
1163 VHWACommandList &onResizeCmdList() { return mOnResizeCmdList; }
1164protected:
1165
1166 void paintGL()
1167 {
1168 if(mpfnOp)
1169 {
1170 (this->*mpfnOp)(mOpContext);
1171 mpfnOp = NULL;
1172 }
1173 VBOXQGLLOG(("paintGL\n"));
1174// else
1175// {
1176 mDisplay.performDisplay(true);
1177// }
1178 }
1179
1180 void initializeGL();
1181
1182private:
1183 static void setupMatricies(const QSize &display);
1184 static void adjustViewport(const QSize &display, const QRect &viewport);
1185// void vboxDoPaint(void *rec);
1186
1187
1188#ifdef VBOXQGL_DBG_SURF
1189 void vboxDoTestSurfaces(void *context);
1190#endif
1191#ifdef VBOX_WITH_VIDEOHWACCEL
1192 void vboxDoVHWACmdExec(void *cmd);
1193 void vboxDoVHWACmdAndFree(void *cmd);
1194 void vboxDoVHWACmd(void *cmd);
1195
1196 void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
1197 {
1198 if (pSurface->addressAlocated())
1199 {
1200 uchar * addr = vboxVRAMAddressFromOffset(offset);
1201 if(addr)
1202 {
1203 pSurface->setAddress(addr);
1204 }
1205 }
1206 }
1207
1208 int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
1209 static int vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t cBackBuffers, uint32_t u32Version);
1210 int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
1211 static int vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
1212 static int vhwaLoadVHWAEnable(VHWACommandList * pCmdList);
1213
1214 void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
1215#endif
1216 static const QGLFormat & vboxGLFormat();
1217
1218 VBoxVHWADisplay mDisplay;
1219
1220
1221 /* we do all opengl stuff in the paintGL context,
1222 * submit the operation to be performed
1223 * @todo: could be moved outside the updateGL */
1224 void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext)
1225 {
1226 mpfnOp = pfn;
1227 mOpContext = pContext;
1228 updateGL();
1229 }
1230
1231// /* posts op to UI thread */
1232// int vboxExecOpSynch(PFNVBOXQGLOP pfn, void* pContext);
1233// void vboxExecOnResize(PFNVBOXQGLOP pfn, void* pContext);
1234
1235 void vboxDoProcessVHWACommands(void *pContext);
1236
1237 class VBoxVHWACommandElement * processCmdList(class VBoxVHWACommandElement * pCmd);
1238
1239 VBoxVHWASurfaceBase* handle2Surface(uint32_t h)
1240 {
1241 VBoxVHWASurfaceBase* pSurf = (VBoxVHWASurfaceBase*)mSurfHandleTable.get(h);
1242 Assert(pSurf);
1243 return pSurf;
1244 }
1245
1246 VBoxVHWAHandleTable mSurfHandleTable;
1247
1248 PFNVBOXQGLOP mpfnOp;
1249 void *mOpContext;
1250
1251 ulong mPixelFormat;
1252 bool mUsesGuestVRAM;
1253
1254 bool mRepaintNeeded;
1255
1256// bool mbVGASurfCreated;
1257 QRect mViewport;
1258
1259 class VBoxConsoleView *mView;
1260
1261 VBoxVHWASurfList *mConstructingList;
1262 int32_t mcRemaining2Contruct;
1263
1264 /* this is used in saved state restore to postpone surface restoration
1265 * till the framebuffer size is restored */
1266 VHWACommandList mOnResizeCmdList;
1267
1268 class VBoxVHWAGlProgramMngr *mpMngr;
1269
1270#ifdef VBOXVHWA_PROFILE_FPS
1271 VBoxVHWADbgTimer mFPSCounter;
1272 bool mbNewFrame;
1273#endif
1274};
1275
1276
1277//typedef enum
1278//{
1279// VBOXFBOVERLAY_DONE = 1,
1280// VBOXFBOVERLAY_MODIFIED,
1281// VBOXFBOVERLAY_UNTOUCHED
1282//} VBOXFBOVERLAY_RESUT;
1283
1284class VBoxQGLOverlay
1285{
1286public:
1287 VBoxQGLOverlay (class VBoxConsoleView *aView, class VBoxFrameBuffer * aContainer);
1288
1289 int onVHWACommand(struct _VBOXVHWACMD * pCommand);
1290
1291 void onVHWACommandEvent(QEvent * pEvent);
1292
1293 /**
1294 * to be called on NotifyUpdate framebuffer call
1295 * @return true if the request was processed & should not be forwarded to the framebuffer
1296 * false - otherwise */
1297 bool onNotifyUpdate (ULONG aX, ULONG aY,
1298 ULONG aW, ULONG aH);
1299
1300 /**
1301 * to be called on RequestResize framebuffer call
1302 * @return true if the request was processed & should not be forwarded to the framebuffer
1303 * false - otherwise */
1304 bool onRequestResize (ULONG /*aScreenId*/, ULONG /*aPixelFormat*/,
1305 BYTE * /*aVRAM*/, ULONG /*aBitsPerPixel*/, ULONG /*aBytesPerLine*/,
1306 ULONG /*aWidth*/, ULONG /*aHeight*/,
1307 BOOL * /*aFinished*/)
1308 {
1309 mCmdPipe.completeCurrentEvent();
1310 return false;
1311 }
1312
1313// VBOXFBOVERLAY_RESUT onPaintEvent (const QPaintEvent *pe, QRect *pRect);
1314
1315 void onResizeEvent (const class VBoxResizeEvent *re);
1316 void onResizeEventPostprocess (const class VBoxResizeEvent *re);
1317
1318 void onViewportResized(QResizeEvent * /*re*/)
1319 {
1320 vboxDoCheckUpdateViewport();
1321 mGlCurrent = false;
1322 }
1323
1324 void onViewportScrolled(int /*dx*/, int /*dy*/)
1325 {
1326 vboxDoCheckUpdateViewport();
1327 mGlCurrent = false;
1328 }
1329
1330 static bool isAcceleration2DVideoAvailable();
1331
1332 /** additional video memory required for the best 2D support performance
1333 * total amount of VRAM required is thus calculated as requiredVideoMemory + required2DOffscreenVideoMemory */
1334 static quint64 required2DOffscreenVideoMemory();
1335
1336 /* not supposed to be called by clients */
1337 int vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version);
1338 void vhwaSaveExec(struct SSMHANDLE * pSSM);
1339private:
1340 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1341
1342 void repaintMain();
1343 void repaintOverlay()
1344 {
1345 if(mNeedOverlayRepaint)
1346 {
1347 mNeedOverlayRepaint = false;
1348 performDisplayOverlay();
1349 }
1350 if(mNeedSetVisible)
1351 {
1352 mNeedSetVisible = false;
1353 mpOverlayWidget->setVisible(true);
1354 }
1355 }
1356 void repaint()
1357 {
1358 repaintOverlay();
1359 repaintMain();
1360 }
1361
1362 void makeCurrent()
1363 {
1364 if(!mGlCurrent)
1365 {
1366 mGlCurrent = true;
1367 mpOverlayWidget->makeCurrent();
1368 }
1369 }
1370
1371 void performDisplayOverlay()
1372 {
1373 if(mOverlayVisible)
1374 {
1375#if 0
1376 mpOverlayWidget->updateGL();
1377#else
1378 makeCurrent();
1379 mpOverlayWidget->performDisplayAndSwap(false);
1380#endif
1381 }
1382 }
1383
1384// void vboxOpExit()
1385// {
1386// performDisplayOverlay();
1387// mGlCurrent = false;
1388// }
1389
1390
1391 void vboxSetGlOn(bool on);
1392 bool vboxGetGlOn() { return mGlOn; }
1393 bool vboxSynchGl();
1394 void vboxDoVHWACmdExec(void *cmd);
1395 void vboxShowOverlay(bool show);
1396 void vboxDoCheckUpdateViewport();
1397 void vboxDoVHWACmd(void *cmd);
1398 void addMainDirtyRect(const QRect & aRect);
1399// void vboxUpdateOverlayPosition(const QPoint & pos);
1400 void vboxCheckUpdateOverlay(const QRect & rect);
1401 VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
1402
1403 int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
1404
1405 int reset();
1406
1407 int resetGl();
1408
1409 void initGl();
1410
1411 VBoxGLWidget *mpOverlayWidget;
1412 class VBoxConsoleView *mView;
1413 class VBoxFrameBuffer *mContainer;
1414 bool mGlOn;
1415 bool mOverlayWidgetVisible;
1416 bool mOverlayVisible;
1417 bool mGlCurrent;
1418 bool mProcessingCommands;
1419 bool mNeedOverlayRepaint;
1420 bool mNeedSetVisible;
1421 QRect mOverlayViewport;
1422 VBoxVHWADirtyRect mMainDirtyRect;
1423
1424 VBoxVHWACommandElementProcessor mCmdPipe;
1425
1426 /* this is used in saved state restore to postpone surface restoration
1427 * till the framebuffer size is restored */
1428 VHWACommandList mOnResizeCmdList;
1429};
1430
1431
1432template <class T>
1433class VBoxOverlayFrameBuffer : public T
1434{
1435public:
1436 VBoxOverlayFrameBuffer (class VBoxConsoleView *aView)
1437 : T(aView),
1438 mOverlay(aView, this)
1439 {}
1440
1441
1442 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand)
1443 {
1444 return mOverlay.onVHWACommand((struct _VBOXVHWACMD*)pCommand);
1445 }
1446
1447 void doProcessVHWACommand(QEvent * pEvent)
1448 {
1449 mOverlay.onVHWACommandEvent(pEvent);
1450 }
1451
1452 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
1453 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
1454 ULONG aWidth, ULONG aHeight,
1455 BOOL *aFinished)
1456 {
1457 if(mOverlay.onRequestResize (aScreenId, aPixelFormat,
1458 aVRAM, aBitsPerPixel, aBytesPerLine,
1459 aWidth, aHeight,
1460 aFinished))
1461 {
1462 return S_OK;
1463 }
1464 return T::RequestResize (aScreenId, aPixelFormat,
1465 aVRAM, aBitsPerPixel, aBytesPerLine,
1466 aWidth, aHeight,
1467 aFinished);
1468 }
1469
1470 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1471 ULONG aW, ULONG aH)
1472 {
1473 if(mOverlay.onNotifyUpdate(aX, aY, aW, aH))
1474 return S_OK;
1475 return T::NotifyUpdate(aX, aY, aW, aH);
1476 }
1477
1478// void paintEvent (QPaintEvent *pe)
1479// {
1480// QRect rect;
1481// VBOXFBOVERLAY_RESUT res = mOverlay.onPaintEvent(pe, &rect);
1482// switch(res)
1483// {
1484// case VBOXFBOVERLAY_MODIFIED:
1485// {
1486// QPaintEvent modified(rect);
1487// T::paintEvent(&modified);
1488// } break;
1489// case VBOXFBOVERLAY_UNTOUCHED:
1490// T::paintEvent(pe);
1491// break;
1492// default:
1493// break;
1494// }
1495// }
1496
1497 void resizeEvent (VBoxResizeEvent *re)
1498 {
1499 mOverlay.onResizeEvent(re);
1500 T::resizeEvent(re);
1501 mOverlay.onResizeEventPostprocess(re);
1502 }
1503
1504 void viewportResized(QResizeEvent * re)
1505 {
1506 mOverlay.onViewportResized(re);
1507 T::viewportResized(re);
1508 }
1509
1510 void viewportScrolled(int dx, int dy)
1511 {
1512 mOverlay.onViewportScrolled(dx, dy);
1513 T::viewportScrolled(dx, dy);
1514 }
1515private:
1516 VBoxQGLOverlay mOverlay;
1517};
1518
1519#endif
1520
1521#endif /* #ifndef __VBoxFBOverlay_h__ */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette