VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h@ 21939

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

Video Hw Accel: debugging & better color support (still debugging & perf enhancements needed)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.6 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxFrameBuffer class and subclasses 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
23#ifndef ___VBoxFrameBuffer_h___
24#define ___VBoxFrameBuffer_h___
25
26#include "COMDefs.h"
27#include <iprt/critsect.h>
28
29/* Qt includes */
30#include <QImage>
31#include <QPixmap>
32#include <QMutex>
33#include <QPaintEvent>
34#include <QMoveEvent>
35#if defined (VBOX_GUI_USE_QGL)
36#include <QGLWidget>
37#endif
38
39#if defined (VBOX_GUI_USE_SDL)
40#include <SDL.h>
41#include <signal.h>
42#endif
43
44#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
45// VBox/cdefs.h defines these:
46#undef LOWORD
47#undef HIWORD
48#undef LOBYTE
49#undef HIBYTE
50#include <ddraw.h>
51#endif
52
53class VBoxConsoleView;
54
55/////////////////////////////////////////////////////////////////////////////
56
57/**
58 * Frame buffer resize event.
59 */
60class VBoxResizeEvent : public QEvent
61{
62public:
63
64 VBoxResizeEvent (ulong aPixelFormat, uchar *aVRAM,
65 ulong aBitsPerPixel, ulong aBytesPerLine,
66 ulong aWidth, ulong aHeight) :
67 QEvent ((QEvent::Type) VBoxDefs::ResizeEventType),
68 mPixelFormat (aPixelFormat), mVRAM (aVRAM), mBitsPerPixel (aBitsPerPixel),
69 mBytesPerLine (aBytesPerLine), mWidth (aWidth), mHeight (aHeight) {}
70 ulong pixelFormat() { return mPixelFormat; }
71 uchar *VRAM() { return mVRAM; }
72 ulong bitsPerPixel() { return mBitsPerPixel; }
73 ulong bytesPerLine() { return mBytesPerLine; }
74 ulong width() { return mWidth; }
75 ulong height() { return mHeight; }
76
77private:
78
79 ulong mPixelFormat;
80 uchar *mVRAM;
81 ulong mBitsPerPixel;
82 ulong mBytesPerLine;
83 ulong mWidth;
84 ulong mHeight;
85};
86
87/**
88 * Frame buffer repaint event.
89 */
90class VBoxRepaintEvent : public QEvent
91{
92public:
93 VBoxRepaintEvent (int x, int y, int w, int h) :
94 QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
95 ex (x), ey (y), ew (w), eh (h)
96 {}
97 int x() { return ex; }
98 int y() { return ey; }
99 int width() { return ew; }
100 int height() { return eh; }
101private:
102 int ex, ey, ew, eh;
103};
104
105/**
106 * Frame buffer set region event.
107 */
108class VBoxSetRegionEvent : public QEvent
109{
110public:
111 VBoxSetRegionEvent (const QRegion &aReg)
112 : QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
113 , mReg (aReg) {}
114 QRegion region() { return mReg; }
115private:
116 QRegion mReg;
117};
118
119#ifdef VBOX_GUI_USE_QGL
120typedef enum
121{
122 VBOXVHWA_PIPECMD_PAINT = 1,
123 VBOXVHWA_PIPECMD_VHWA,
124
125}VBOXVHWA_PIPECMD_TYPE;
126class VBoxVHWACommandElement
127{
128public:
129 void setVHWACmd(struct _VBOXVHWACMD * pCmd)
130 {
131 mType = VBOXVHWA_PIPECMD_VHWA;
132 mpCmd = pCmd;
133 }
134
135 void setPaintCmd(const QRect & aRect)
136 {
137 mType = VBOXVHWA_PIPECMD_PAINT;
138 mRect = aRect;
139 }
140
141 void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
142 {
143 switch(aType)
144 {
145 case VBOXVHWA_PIPECMD_PAINT:
146 setPaintCmd(*((QRect*)pvData));
147 break;
148 case VBOXVHWA_PIPECMD_VHWA:
149 setVHWACmd((struct _VBOXVHWACMD *)pvData);
150 break;
151 }
152 }
153
154 VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
155 const QRect & rect() const {return mRect;}
156 struct _VBOXVHWACMD * vhwaCmd() const {return mpCmd;}
157
158private:
159 VBoxVHWACommandElement * mpNext;
160 VBOXVHWA_PIPECMD_TYPE mType;
161 struct _VBOXVHWACMD * mpCmd;
162 QRect mRect;
163
164 friend class VBoxVHWACommandElementPipe;
165 friend class VBoxVHWACommandElementStack;
166 friend class VBoxGLWidget;
167};
168
169class VBoxVHWACommandElementPipe
170{
171public:
172 VBoxVHWACommandElementPipe() :
173 mpFirst(NULL),
174 mpLast(NULL)
175 {}
176
177 void put(VBoxVHWACommandElement *pCmd)
178 {
179 if(mpLast)
180 {
181 Assert(mpFirst);
182 mpLast->mpNext = pCmd;
183 mpLast = pCmd;
184 }
185 else
186 {
187 Assert(!mpFirst);
188 mpFirst = pCmd;
189 mpLast = pCmd;
190 }
191 pCmd->mpNext= NULL;
192
193 }
194
195 VBoxVHWACommandElement * detachList()
196 {
197 if(mpLast)
198 {
199 VBoxVHWACommandElement * pHead = mpFirst;
200 mpFirst = NULL;
201 mpLast = NULL;
202 return pHead;
203 }
204 return NULL;
205 }
206private:
207 VBoxVHWACommandElement *mpFirst;
208 VBoxVHWACommandElement *mpLast;
209};
210
211class VBoxVHWACommandElementStack
212{
213public:
214 VBoxVHWACommandElementStack() :
215 mpFirst(NULL) {}
216
217 void push(VBoxVHWACommandElement *pCmd)
218 {
219 pCmd->mpNext = mpFirst;
220 mpFirst = pCmd;
221 }
222
223 void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
224 {
225 pLast->mpNext = mpFirst;
226 mpFirst = pFirst;
227 }
228
229 VBoxVHWACommandElement * pop()
230 {
231 if(mpFirst)
232 {
233 VBoxVHWACommandElement * ret = mpFirst;
234 mpFirst = ret->mpNext;
235 return ret;
236 }
237 return NULL;
238 }
239private:
240 VBoxVHWACommandElement *mpFirst;
241};
242
243class VBoxVHWACommandProcessEvent : public QEvent
244{
245public:
246 VBoxVHWACommandProcessEvent (VBoxVHWACommandElement *pEl)
247 : QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
248 {
249 mCmdPipe.put(pEl);
250 }
251 VBoxVHWACommandElementPipe & pipe() { return mCmdPipe; }
252private:
253 VBoxVHWACommandElementPipe mCmdPipe;
254 VBoxVHWACommandProcessEvent *mpNext;
255
256 friend class VBoxGLWidget;
257};
258
259#endif
260
261/////////////////////////////////////////////////////////////////////////////
262
263/**
264 * Common IFramebuffer implementation for all methods used by GUI to maintain
265 * the VM display video memory.
266 *
267 * Note that although this class can be called from multiple threads
268 * (in particular, the GUI thread and EMT) it doesn't protect access to every
269 * data field using its mutex lock. This is because all synchronization between
270 * the GUI and the EMT thread is supposed to be done using the
271 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
272 * (in particular, the \a aFinished parameter of these methods is responsible
273 * for the synchronization). These methods are always called on EMT and
274 * therefore always follow one another but never in parallel.
275 *
276 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
277 * IFramebuffer::Unlock() implementations) usually makes sense only if some
278 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
279 * *no* VM display update or resize event can occur while it is accessing
280 * IFramebuffer properties or the underlying display memory storage area.
281 *
282 * See IFramebuffer documentation for more info.
283 */
284
285class VBoxFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
286{
287public:
288
289 VBoxFrameBuffer (VBoxConsoleView *aView);
290 virtual ~VBoxFrameBuffer();
291
292 NS_DECL_ISUPPORTS
293
294#if defined (Q_OS_WIN32)
295
296 STDMETHOD_(ULONG, AddRef)()
297 {
298 return ::InterlockedIncrement (&refcnt);
299 }
300
301 STDMETHOD_(ULONG, Release)()
302 {
303 long cnt = ::InterlockedDecrement (&refcnt);
304 if (cnt == 0)
305 delete this;
306 return cnt;
307 }
308#endif
309 VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer)
310
311 // IFramebuffer COM methods
312 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
313 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
314 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
315 STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *aBitsPerPixel);
316 STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *aBytesPerLine);
317 STDMETHOD(COMGETTER(PixelFormat)) (ULONG *aPixelFormat);
318 STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *aUsesGuestVRAM);
319 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
320 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
321 STDMETHOD(COMGETTER(WinId)) (ULONG64 *winId);
322
323 STDMETHOD(Lock)();
324 STDMETHOD(Unlock)();
325
326 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
327 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
328 ULONG aWidth, ULONG aHeight,
329 BOOL *aFinished);
330
331 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
332 BOOL *aSupported);
333
334 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
335 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
336
337 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
338
339 ulong width() { return mWdt; }
340 ulong height() { return mHgt; }
341
342 virtual ulong pixelFormat()
343 {
344 return FramebufferPixelFormat_FOURCC_RGB;
345 }
346
347 virtual bool usesGuestVRAM()
348 {
349 return false;
350 }
351
352 void lock() { RTCritSectEnter(&mCritSect); }
353 void unlock() { RTCritSectLeave(&mCritSect); }
354
355 virtual uchar *address() = 0;
356 virtual ulong bitsPerPixel() = 0;
357 virtual ulong bytesPerLine() = 0;
358
359 /**
360 * Called on the GUI thread (from VBoxConsoleView) when some part of the
361 * VM display viewport needs to be repainted on the host screen.
362 */
363 virtual void paintEvent (QPaintEvent *pe) = 0;
364
365 /**
366 * Called on the GUI thread (from VBoxConsoleView) after it gets a
367 * VBoxResizeEvent posted from the RequestResize() method implementation.
368 */
369 virtual void resizeEvent (VBoxResizeEvent *re)
370 {
371 mWdt = re->width();
372 mHgt = re->height();
373 }
374
375 /**
376 * Called on the GUI thread (from VBoxConsoleView) when the VM console
377 * window is moved.
378 */
379 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
380
381#ifdef VBOX_GUI_USE_QGL
382 /* this method is called from the GUI thread
383 * to perform the actual Video HW Acceleration command processing */
384 virtual void doProcessVHWACommand(VBoxVHWACommandProcessEvent * pEvent);
385#endif
386
387protected:
388
389 VBoxConsoleView *mView;
390 RTCRITSECT mCritSect;
391 int mWdt;
392 int mHgt;
393 uint64_t mWinId;
394
395#if defined (Q_OS_WIN32)
396private:
397 long refcnt;
398#endif
399};
400
401/////////////////////////////////////////////////////////////////////////////
402
403#if defined (VBOX_GUI_USE_QIMAGE)
404
405class VBoxQImageFrameBuffer : public VBoxFrameBuffer
406{
407public:
408
409 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
410
411 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
412 ULONG aW, ULONG aH);
413
414 ulong pixelFormat() { return mPixelFormat; }
415 bool usesGuestVRAM() { return mUsesGuestVRAM; }
416
417 uchar *address() { return mImg.bits(); }
418 ulong bitsPerPixel() { return mImg.depth(); }
419 ulong bytesPerLine() { return mImg.bytesPerLine(); }
420
421 void paintEvent (QPaintEvent *pe);
422 void resizeEvent (VBoxResizeEvent *re);
423
424private:
425
426 QPixmap mPM;
427 QImage mImg;
428 ulong mPixelFormat;
429 bool mUsesGuestVRAM;
430};
431
432#endif
433
434/////////////////////////////////////////////////////////////////////////////
435
436#if defined (VBOX_GUI_USE_QGL)
437
438#ifdef DEBUG
439#include "iprt/stream.h"
440#define VBOXQGLLOG(_m) RTPrintf _m
441#else
442#define VBOXQGLLOG(_m)
443#endif
444#define VBOXQGLLOG_ENTER(_m)
445//do{VBOXQGLLOG(("==>[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
446#define VBOXQGLLOG_EXIT(_m)
447//do{VBOXQGLLOG(("<==[%s]:", __FUNCTION__)); VBOXQGLLOG(_m);}while(0)
448#ifdef DEBUG
449#define VBOXQGL_ASSERTNOERR() \
450 do { GLenum err = glGetError(); \
451 if(err != GL_NO_ERROR) VBOXQGLLOG(("gl error ocured (0x%x)\n", err)); \
452 Assert(err == GL_NO_ERROR); \
453 }while(0)
454
455#define VBOXQGL_CHECKERR(_op) \
456 do { \
457 glGetError(); \
458 _op \
459 VBOXQGL_ASSERTNOERR(); \
460 }while(0)
461#else
462#define VBOXQGL_ASSERTNOERR() \
463 do {}while(0)
464
465#define VBOXQGL_CHECKERR(_op) \
466 do { \
467 _op \
468 }while(0)
469#endif
470
471#ifdef DEBUG
472#include <iprt/time.h>
473
474#define VBOXGETTIME() RTTimeNanoTS()
475
476#define VBOXPRINTDIF(_nano, _m) do{\
477 uint64_t cur = VBOXGETTIME(); \
478 VBOXQGLLOG(_m); \
479 VBOXQGLLOG(("(%Lu)\n", cur - (_nano))); \
480 }while(0)
481
482class VBoxVHWADbgTimeCounter
483{
484public:
485 VBoxVHWADbgTimeCounter(const char* msg) {mTime = VBOXGETTIME(); mMsg=msg;}
486 ~VBoxVHWADbgTimeCounter() {VBOXPRINTDIF(mTime, (mMsg));}
487private:
488 uint64_t mTime;
489 const char* mMsg;
490};
491
492#define VBOXQGLLOG_METHODTIME(_m) VBoxVHWADbgTimeCounter _dbgTimeCounter(_m)
493#else
494#define VBOXQGLLOG_METHODTIME(_m)
495#endif
496
497#define VBOXQGLLOG_QRECT(_p, _pr, _s) do{\
498 VBOXQGLLOG((_p " x(%d), y(%d), w(%d), h(%d)" _s, (_pr)->x(), (_pr)->y(), (_pr)->width(), (_pr)->height()));\
499 }while(0)
500
501#define VBOXQGLLOG_CKEY(_p, _pck, _s) do{\
502 VBOXQGLLOG((_p " l(%d), u(%d)" _s, (_pck)->lower(), (_pck)->upper()));\
503 }while(0)
504
505class VBoxVHWADirtyRect
506{
507public:
508 VBoxVHWADirtyRect() :
509 mIsClear(true)
510 {}
511
512 VBoxVHWADirtyRect(const QRect & aRect)
513 {
514 if(aRect.isEmpty())
515 {
516 mIsClear = false;
517 mRect = aRect;
518 }
519 else
520 {
521 mIsClear = true;
522 }
523 }
524
525 bool isClear() const { return mIsClear; }
526
527 void add(const QRect & aRect)
528 {
529 if(aRect.isEmpty())
530 return;
531
532 mRect = mIsClear ? aRect : mRect.united(aRect);
533 mIsClear = false;
534 }
535
536 void add(const VBoxVHWADirtyRect & aRect)
537 {
538 if(aRect.isClear())
539 return;
540 add(aRect.rect());
541 }
542
543 void set(const QRect & aRect)
544 {
545 if(aRect.isEmpty())
546 {
547 mIsClear = true;
548 }
549 else
550 {
551 mRect = aRect;
552 mIsClear = false;
553 }
554 }
555
556 void clear() { mIsClear = true; }
557
558 const QRect & rect() const {return mRect;}
559
560 bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
561
562 bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
563
564 QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
565
566 bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
567
568 void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
569
570private:
571 QRect mRect;
572 bool mIsClear;
573};
574
575class VBoxVHWAColorKey
576{
577public:
578 VBoxVHWAColorKey() :
579 mUpper(0),
580 mLower(0)
581 {}
582
583 VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
584 mUpper(aUpper),
585 mLower(aLower)
586 {}
587
588 uint32_t upper() const {return mUpper; }
589 uint32_t lower() const {return mLower; }
590
591 bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
592private:
593 uint32_t mUpper;
594 uint32_t mLower;
595};
596
597class VBoxVHWAColorComponent
598{
599public:
600 VBoxVHWAColorComponent() :
601 mMask(0),
602 mRange(0),
603 mOffset(32),
604 mcBits(0)
605 {}
606
607 VBoxVHWAColorComponent(uint32_t aMask);
608
609 uint32_t mask() const { return mMask; }
610 uint32_t range() const { return mRange; }
611 uint32_t offset() const { return mOffset; }
612 uint32_t cBits() const { return mcBits; }
613 uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
614 float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
615private:
616 uint32_t mMask;
617 uint32_t mRange;
618 uint32_t mOffset;
619 uint32_t mcBits;
620};
621
622class VBoxVHWAColorFormat
623{
624public:
625
626// VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
627 VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
628 VBoxVHWAColorFormat(uint32_t fourcc);
629 VBoxVHWAColorFormat(){}
630 GLint internalFormat() const {return mInternalFormat; }
631 GLenum format() const {return mFormat; }
632 GLenum type() const {return mType; }
633 bool isValid() const {return mBitsPerPixel != 0; }
634 uint32_t fourcc() const {return mDataFormat;}
635 uint32_t bitsPerPixel() const { return mBitsPerPixel; }
636 uint32_t bitsPerPixelDd() const { return mBitsPerPixelDd; }
637 void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
638 uint32_t widthCompression() const {return mWidthCompression;}
639 uint32_t heightCompression() const {return mHeightCompression;}
640// uint32_t r(uint32_t pix);
641// uint32_t g(uint32_t pix);
642// uint32_t b(uint32_t pix);
643
644private:
645 void VBoxVHWAColorFormat::init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
646 void VBoxVHWAColorFormat::init(uint32_t fourcc);
647
648 GLint mInternalFormat;
649 GLenum mFormat;
650 GLenum mType;
651 uint32_t mDataFormat;
652
653 uint32_t mBitsPerPixel;
654 uint32_t mBitsPerPixelDd;
655 uint32_t mWidthCompression;
656 uint32_t mHeightCompression;
657 VBoxVHWAColorComponent mR;
658 VBoxVHWAColorComponent mG;
659 VBoxVHWAColorComponent mB;
660 VBoxVHWAColorComponent mA;
661};
662
663class VBoxVHWATexture
664{
665public:
666 VBoxVHWATexture() {}
667 VBoxVHWATexture(const QRect * pRect, const VBoxVHWAColorFormat *pFormat);
668 void init(uchar *pvMem);
669 void setAddress(uchar *pvMem) {mAddress = pvMem;}
670 void uninit();
671 void update(const QRect * pRect);
672 GLuint texture() {return mTexture;}
673 const QRect & texRect() {return mTexRect;}
674 const QRect & rect() {return mRect;}
675 uchar * address(){ return mAddress; }
676 uchar * pointAddress(int x, int y)
677 {
678 x = toXTex(x);
679 y = toYTex(y);
680 return pointAddressTex(x, y);
681 }
682 uchar * pointAddressTex(int x, int y) { return mAddress + y*mBytesPerLine + x*mBytesPerPixel; }
683 int toXTex(int x) {return x/mColorFormat.widthCompression();}
684 int toYTex(int y) {return y/mColorFormat.heightCompression();}
685 ulong memSize(){ return mBytesPerLine * mRect.height()/mColorFormat.heightCompression(); }
686private:
687 uchar * mAddress;
688 GLuint mTexture;
689 uint32_t mBytesPerPixel;
690 uint32_t mBytesPerLine;
691 QRect mTexRect; /* texture size */
692 QRect mRect; /* img size */
693 VBoxVHWAColorFormat mColorFormat;
694};
695
696/* data flow:
697 * I. NON-Yinverted surface:
698 * 1.direct memory update (paint, lock/unlock):
699 * mem->tex->fb
700 * 2.blt
701 * srcTex->invFB->tex->fb
702 * |->mem
703 *
704 * II. Yinverted surface:
705 * 1.direct memory update (paint, lock/unlock):
706 * mem->tex->fb
707 * 2.blt
708 * srcTex->fb->tex
709 * |->mem
710 *
711 * III. flip support:
712 * 1. Yinverted<->NON-YInverted conversion :
713 * mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
714 * fb-->| |->mem
715 * */
716class VBoxVHWASurfaceBase
717{
718public:
719 VBoxVHWASurfaceBase(
720 class VBoxGLWidget *mWidget,
721#if 0
722 class VBoxVHWAGlContextState *aState,
723 bool aIsYInverted,
724#endif
725 const QSize * aSize, const QSize * aTargetSize,
726 VBoxVHWAColorFormat & aColorFormat,
727 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
728 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey);
729
730 virtual ~VBoxVHWASurfaceBase();
731
732 void init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
733 void setupMatricies(VBoxVHWASurfaceBase *pPrimary);
734
735 void uninit();
736
737 static void globalInit();
738
739// int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
740// int overlay(VBoxVHWASurfaceBase * aOverlaySurface);
741
742 int lock(const QRect * pRect, uint32_t flags);
743
744 int unlock();
745
746 void updatedMem(const QRect * aRect);
747
748 void performDisplay(VBoxVHWASurfaceBase *pPrimary);
749
750 void setRects(VBoxVHWASurfaceBase *pPrimary, const QRect * aTargRect, const QRect * aSrcRect);
751 void setTargetRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint * aPoint);
752
753 static ulong calcBytesPerPixel(GLenum format, GLenum type);
754
755 static GLsizei makePowerOf2(GLsizei val);
756
757 bool addressAlocated() const { return mFreeAddress; }
758 uchar * address(){ return mAddress; }
759
760 ulong memSize();
761
762 ulong width() { return mRect.width(); }
763 ulong height() { return mRect.height(); }
764
765 GLenum format() {return mColorFormat.format(); }
766 GLint internalFormat() { return mColorFormat.internalFormat(); }
767 GLenum type() { return mColorFormat.type(); }
768 uint32_t fourcc() {return mColorFormat.fourcc(); }
769
770 ulong bytesPerPixel() { return mBytesPerPixel; }
771 ulong bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
772 ulong bitsPerPixelDd() { return mColorFormat.bitsPerPixelDd(); }
773 ulong bytesPerLine() { return mBytesPerLine; }
774
775 const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
776 const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
777 const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
778 const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
779 const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
780 const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
781 void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
782 void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
783
784 void setDstBltCKey(const VBoxVHWAColorKey * ckey)
785 {
786 if(ckey)
787 {
788 mDstBltCKey = *ckey;
789 mpDstBltCKey = &mDstBltCKey;
790 }
791 else
792 {
793 mpDstBltCKey = NULL;
794 }
795 }
796
797 void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
798 {
799 if(ckey)
800 {
801 mSrcBltCKey = *ckey;
802 mpSrcBltCKey = &mSrcBltCKey;
803 }
804 else
805 {
806 mpSrcBltCKey = NULL;
807 }
808 }
809
810 void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
811 {
812 if(ckey)
813 {
814 mDefaultDstOverlayCKey = *ckey;
815 mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
816 }
817 else
818 {
819 mpDefaultDstOverlayCKey = NULL;
820 }
821 }
822
823 void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
824 {
825 if(ckey)
826 {
827 mDefaultSrcOverlayCKey = *ckey;
828 mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
829 }
830 else
831 {
832 mpDefaultSrcOverlayCKey = NULL;
833 }
834 }
835
836 void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
837 {
838 if(ckey)
839 {
840 mOverriddenDstOverlayCKey = *ckey;
841 mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
842 }
843 else
844 {
845 mpDstOverlayCKey = NULL;
846 }
847 }
848
849 void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
850 {
851 if(ckey)
852 {
853 mOverriddenSrcOverlayCKey = *ckey;
854 mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
855 }
856 else
857 {
858 mpSrcOverlayCKey = NULL;
859 }
860 }
861
862 const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
863 {
864 return mpSrcOverlayCKey;
865 }
866
867 const VBoxVHWAColorKey * getActiveDstOverlayCKey(VBoxVHWASurfaceBase * pPrimary)
868 {
869 return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : pPrimary->mpDstOverlayCKey;
870 }
871
872 const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
873
874 /* clients should treat the returned texture as read-only */
875// GLuint textureSynched(const QRect * aRect) { /*synchTex(aRect); */synchTexMem(aRect); return mTexture; }
876
877 void setAddress(uchar * addr);
878
879 const QRect& rect() {return mRect;}
880 const QRect& texRect() {return mTexRect;}
881
882// /* surface currently being displayed in a flip chain */
883// virtual bool isPrimary() = 0;
884// /* surface representing the main framebuffer. */
885// virtual bool isMainFramebuffer() = 0;
886#if 0
887 virtual void makeCurrent() = 0;
888 virtual void makeYInvertedCurrent() = 0;
889 bool isYInverted() {return mIsYInverted; }
890
891 bool isHidden() {return mIsYInverted; }
892 void setHidden(bool hidden)
893 {
894 if(hidden == mIsYInverted)
895 return;
896
897 invert();
898 }
899 int invert();
900
901 bool isFrontBuffer() {return !mIsYInverted; }
902#endif
903
904 class VBoxVHWASurfList * getComplexList() {return mComplexList; }
905
906// bool isOverlay() { return mIsOverlay; }
907
908#ifdef VBOX_WITH_VIDEOHWACCEL
909 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
910 static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
911#endif
912private:
913 void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
914 void initDisplay(VBoxVHWASurfaceBase *pPrimary);
915 void deleteDisplay();
916// void initDisplay(bool bInverted);
917// void deleteDisplay(bool bInverted);
918 GLuint createDisplay(VBoxVHWASurfaceBase *pPrimary
919#if 0
920 bool bInverted
921#endif
922 );
923 void doDisplay(VBoxVHWASurfaceBase *pPrimary, VBoxVHWAGlProgramVHWA * pProgram, bool bBindDst);
924 void synchTexMem(const QRect * aRect);
925#if 0
926 void synchTex(const QRect * aRect);
927 void synchTexFB(const QRect * aRect);
928 void synchMem(const QRect * aRect);
929 void synchFB(const QRect * aRect);
930 void synch(const QRect * aRect);
931#endif
932 int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
933
934// void doTex2FB(const QRect * aRect);
935 void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
936 void doMultiTex2FB(const QRect * pDstRect, const QRect * pDstTexSize, const QRect * pSrcRect, int cSrcTex);
937 void doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex);
938// void doMultiTex2FB(GLenum tex, const QRect * pDstRect, const QRect * pSrcRect);
939
940 void doSetupMatrix(const QSize * pSize , bool bInverted);
941
942 QRect mRect; /* == Inv FB size */
943 QRect mTexRect; /* texture size */
944
945 QRect mSrcRect;
946 QRect mTargRect; /* == Vis FB size */
947 QRect mTargSize;
948#if 0
949 GLuint mYInvertedDisplay;
950#endif
951 GLuint mVisibleDisplay;
952#if 0
953 bool mYInvertedDisplayInitialized;
954#endif
955 bool mVisibleDisplayInitialized;
956
957 uchar * mAddress;
958 VBoxVHWATexture mTex[3];
959
960 VBoxVHWAColorFormat mColorFormat;
961
962 VBoxVHWAColorKey *mpSrcBltCKey;
963 VBoxVHWAColorKey *mpDstBltCKey;
964 VBoxVHWAColorKey *mpSrcOverlayCKey;
965 VBoxVHWAColorKey *mpDstOverlayCKey;
966
967 VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
968 VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
969
970 VBoxVHWAColorKey mSrcBltCKey;
971 VBoxVHWAColorKey mDstBltCKey;
972 VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
973 VBoxVHWAColorKey mOverriddenDstOverlayCKey;
974 VBoxVHWAColorKey mDefaultDstOverlayCKey;
975 VBoxVHWAColorKey mDefaultSrcOverlayCKey;
976
977
978 GLenum mFormat;
979 GLint mInternalFormat;
980 GLenum mType;
981// ulong mDisplayWidth;
982// ulong mDisplayHeight;
983 ulong mBytesPerPixel;
984 ulong mBytesPerLine;
985
986 int mLockCount;
987 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
988 VBoxVHWADirtyRect mUpdateMem2TexRect;
989#if 0
990 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
991 VBoxVHWADirtyRect mUpdateTex2FBRect;
992 /*in case of blit we blit from another surface's texture, so our current texture gets durty */
993 VBoxVHWADirtyRect mUpdateFB2TexRect;
994 /*in case of blit the memory buffer does not get updated until we need it, e.g. for paint or lock operations */
995 VBoxVHWADirtyRect mUpdateFB2MemRect;
996#endif
997
998 bool mFreeAddress;
999#if 0
1000 bool mIsYInverted;
1001#endif
1002
1003 class VBoxVHWASurfList *mComplexList;
1004
1005 class VBoxGLWidget *mWidget;
1006protected:
1007#if 0
1008 virtual void init(uchar *pvMem, bool bInverted);
1009 class VBoxVHWAGlContextState *mState;
1010#endif
1011
1012 friend class VBoxVHWASurfList;
1013
1014};
1015
1016typedef std::list <VBoxVHWASurfaceBase*> SurfList;
1017
1018class VBoxVHWASurfList
1019{
1020public:
1021
1022 VBoxVHWASurfList() : mCurrent(NULL) {}
1023 void add(VBoxVHWASurfaceBase *pSurf)
1024 {
1025 VBoxVHWASurfList * pOld = pSurf->getComplexList();
1026 if(pOld)
1027 {
1028 pOld->remove(pSurf);
1029 }
1030 mSurfaces.push_back(pSurf);
1031 pSurf->setComplexList(this);
1032 }
1033
1034 void clear()
1035 {
1036 for (SurfList::iterator it = mSurfaces.begin();
1037 it != mSurfaces.end(); ++ it)
1038 {
1039 (*it)->setComplexList(NULL);
1040 }
1041 mSurfaces.clear();
1042 mCurrent = NULL;
1043 }
1044
1045 void remove(VBoxVHWASurfaceBase *pSurf)
1046 {
1047 mSurfaces.remove(pSurf);
1048 pSurf->setComplexList(NULL);
1049 if(mCurrent == pSurf)
1050 mCurrent = NULL;
1051 }
1052
1053 bool empty() { return mSurfaces.empty(); }
1054
1055 void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
1056 {
1057 mCurrent = pSurf;
1058 }
1059
1060 VBoxVHWASurfaceBase * current() { return mCurrent; }
1061 const SurfList & surfaces() const {return mSurfaces;}
1062
1063private:
1064
1065 SurfList mSurfaces;
1066 VBoxVHWASurfaceBase* mCurrent;
1067};
1068
1069class VBoxVHWADisplay
1070{
1071public:
1072 VBoxVHWADisplay() :
1073 mSurfVGA(NULL)
1074// ,
1075// mSurfPrimary(NULL)
1076 {}
1077
1078 VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
1079 {
1080 VBoxVHWASurfaceBase * old = mSurfVGA;
1081 mSurfVGA = pVga;
1082 mPrimary.clear();
1083 if(pVga)
1084 {
1085 mPrimary.add(pVga);
1086 mPrimary.setCurrentVisible(pVga);
1087 }
1088// mSurfPrimary = pVga;
1089 mOverlays.clear();
1090 return old;
1091 }
1092
1093 VBoxVHWASurfaceBase * getVGA()
1094 {
1095 return mSurfVGA;
1096 }
1097
1098 VBoxVHWASurfaceBase * getPrimary()
1099 {
1100 return mPrimary.current();
1101 }
1102//
1103// void setPrimary(VBoxVHWASurfList * pSurf)
1104// {
1105// mSurfPrimary = pSurf;
1106// }
1107
1108 void addOverlay(VBoxVHWASurfList * pSurf)
1109 {
1110 mOverlays.push_back(pSurf);
1111 }
1112
1113 void checkAddOverlay(VBoxVHWASurfList * pSurf)
1114 {
1115 if(!hasOverlay(pSurf))
1116 addOverlay(pSurf);
1117 }
1118
1119 bool hasOverlay(VBoxVHWASurfList * pSurf)
1120 {
1121 for (OverlayList::iterator it = mOverlays.begin();
1122 it != mOverlays.end(); ++ it)
1123 {
1124 if((*it) == pSurf)
1125 {
1126 return true;
1127 }
1128 }
1129 return false;
1130 }
1131
1132 void removeOverlay(VBoxVHWASurfList * pSurf)
1133 {
1134 mOverlays.remove(pSurf);
1135 }
1136
1137
1138 void performDisplay()
1139 {
1140 VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
1141 pPrimary->performDisplay(NULL);
1142
1143 for (OverlayList::const_iterator it = mOverlays.begin();
1144 it != mOverlays.end(); ++ it)
1145 {
1146 VBoxVHWASurfaceBase * pOverlay = (*it)->current();
1147 if(pOverlay)
1148 {
1149 pOverlay->performDisplay(pPrimary);
1150// pPrimary->overlay(pOverlay);
1151 }
1152 }
1153 }
1154
1155private:
1156 VBoxVHWASurfaceBase *mSurfVGA;
1157 VBoxVHWASurfList mPrimary;
1158
1159 typedef std::list <VBoxVHWASurfList*> OverlayList;
1160
1161 OverlayList mOverlays;
1162};
1163
1164class VBoxGLWidget : public QGLWidget
1165{
1166public:
1167 VBoxGLWidget (VBoxConsoleView *aView, QWidget *aParent);
1168 ~VBoxGLWidget();
1169
1170 ulong vboxPixelFormat() { return mPixelFormat; }
1171 bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
1172
1173 uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
1174 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
1175 ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
1176 ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : NULL; }
1177
1178typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
1179//typedef FNVBOXQGLOP *PFNVBOXQGLOP;
1180
1181 void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe);}
1182 void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re);}
1183#ifdef DEBUG_misha
1184 void vboxTestSurfaces () {vboxPerformGLOp(&VBoxGLWidget::vboxDoTestSurfaces, NULL);}
1185#endif
1186 void vboxProcessVHWACommands(VBoxVHWACommandProcessEvent * pEvent) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pEvent);}
1187#ifdef VBOX_WITH_VIDEOHWACCEL
1188 void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
1189 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
1190#endif
1191
1192 VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
1193
1194 void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
1195protected:
1196// void resizeGL (int height, int width);
1197
1198 void paintGL()
1199 {
1200// Assert(mState.getCurrent() == NULL);
1201// /* we are called with QGLWidget context */
1202// mState.assertCurrent(mDisplay.getVGA(), false);
1203 if(mpfnOp)
1204 {
1205 (this->*mpfnOp)(mOpContext);
1206 mpfnOp = NULL;
1207 }
1208 else
1209 {
1210 mDisplay.performDisplay();
1211 }
1212// /* restore the context */
1213// mState.makeCurrent(mDisplay.getVGA());
1214// /* clear*/
1215// mState.assertCurrent(NULL, false);
1216 }
1217
1218 void initializeGL();
1219private:
1220// void vboxDoInitDisplay();
1221// void vboxDoDeleteDisplay();
1222// void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
1223 void vboxDoResize(void *re);
1224 void vboxDoPaint(void *rec);
1225
1226 void vboxDoUpdateRect(const QRect * pRect);
1227#ifdef DEBUG_misha
1228 void vboxDoTestSurfaces(void *context);
1229#endif
1230#ifdef VBOX_WITH_VIDEOHWACCEL
1231 void vboxDoVHWACmd(void *cmd);
1232 void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
1233 {
1234 if (pSurface->addressAlocated())
1235 {
1236 uchar * addr = vboxVRAMAddressFromOffset(offset);
1237 if(addr)
1238 {
1239 pSurface->setAddress(addr);
1240 }
1241 }
1242 }
1243 int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
1244 int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
1245 int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
1246 int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
1247 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1248 int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
1249 int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
1250 int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
1251 int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
1252 int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
1253 int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
1254 int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
1255
1256 void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
1257#endif
1258 static const QGLFormat & vboxGLFormat();
1259
1260// VBoxVHWASurfaceQGL * pDisplay;
1261 VBoxVHWADisplay mDisplay;
1262
1263
1264 /* we need to do all opengl stuff in the paintGL context,
1265 * submit the operation to be performed */
1266 void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext) {mpfnOp = pfn; mOpContext = pContext; updateGL();}
1267
1268 void cmdPipeInit();
1269 void cmdPipeDelete();
1270 void vboxDoProcessVHWACommands(void *pContext);
1271
1272 VBoxVHWACommandElement * detachCmdList(VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
1273 VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
1274
1275 PFNVBOXQGLOP mpfnOp;
1276 void *mOpContext;
1277
1278// ulong mBitsPerPixel;
1279 ulong mPixelFormat;
1280 bool mUsesGuestVRAM;
1281#if 0
1282 VBoxVHWAGlContextState mState;
1283#endif
1284
1285 RTCRITSECT mCritSect;
1286 VBoxVHWACommandProcessEvent *mpFirstEvent;
1287 VBoxVHWACommandProcessEvent *mpLastEvent;
1288 bool mbNewEvent;
1289 VBoxVHWACommandElementStack mFreeElements;
1290 VBoxVHWACommandElement mElementsBuffer[2048];
1291
1292 VBoxConsoleView *mView;
1293
1294 VBoxVHWASurfList *mConstructingList;
1295 int32_t mcRemaining2Contruct;
1296
1297#ifdef VBOX_WITH_VIDEOHWACCEL
1298 class VBoxVHWAGlProgramMngr *mpMngr;
1299#endif
1300};
1301
1302
1303class VBoxQGLFrameBuffer : public VBoxFrameBuffer
1304{
1305public:
1306
1307 VBoxQGLFrameBuffer (VBoxConsoleView *aView);
1308
1309 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1310 ULONG aW, ULONG aH);
1311#ifdef VBOXQGL_PROF_BASE
1312 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
1313 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
1314 ULONG aWidth, ULONG aHeight,
1315 BOOL *aFinished);
1316#endif
1317
1318#ifdef VBOX_WITH_VIDEOHWACCEL
1319 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
1320#endif
1321
1322 ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
1323 bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
1324
1325 uchar *address() { return vboxWidget()->vboxAddress(); }
1326 ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
1327 ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
1328
1329 void paintEvent (QPaintEvent *pe);
1330 void resizeEvent (VBoxResizeEvent *re);
1331 void doProcessVHWACommand(VBoxVHWACommandProcessEvent * pEvent);
1332
1333private:
1334// void vboxMakeCurrent();
1335 VBoxGLWidget * vboxWidget();
1336};
1337
1338
1339#endif
1340
1341/////////////////////////////////////////////////////////////////////////////
1342
1343#if defined (VBOX_GUI_USE_SDL)
1344
1345class VBoxSDLFrameBuffer : public VBoxFrameBuffer
1346{
1347public:
1348
1349 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
1350 virtual ~VBoxSDLFrameBuffer();
1351
1352 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1353 ULONG aW, ULONG aH);
1354
1355 uchar *address()
1356 {
1357 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1358 return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
1359 }
1360
1361 ulong bitsPerPixel()
1362 {
1363 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1364 return surf ? surf->format->BitsPerPixel : 0;
1365 }
1366
1367 ulong bytesPerLine()
1368 {
1369 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1370 return surf ? surf->pitch : 0;
1371 }
1372
1373 ulong pixelFormat()
1374 {
1375 return mPixelFormat;
1376 }
1377
1378 bool usesGuestVRAM()
1379 {
1380 return mSurfVRAM != NULL;
1381 }
1382
1383 void paintEvent (QPaintEvent *pe);
1384 void resizeEvent (VBoxResizeEvent *re);
1385
1386private:
1387
1388 SDL_Surface *mScreen;
1389 SDL_Surface *mSurfVRAM;
1390
1391 ulong mPixelFormat;
1392};
1393
1394#endif
1395
1396/////////////////////////////////////////////////////////////////////////////
1397
1398#if defined (VBOX_GUI_USE_DDRAW)
1399
1400class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
1401{
1402public:
1403
1404 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
1405 virtual ~VBoxDDRAWFrameBuffer();
1406
1407 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1408 ULONG aW, ULONG aH);
1409
1410 uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
1411 ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
1412 ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
1413
1414 ulong pixelFormat() { return mPixelFormat; };
1415
1416 bool usesGuestVRAM() { return mUsesGuestVRAM; }
1417
1418 void paintEvent (QPaintEvent *pe);
1419 void resizeEvent (VBoxResizeEvent *re);
1420 void moveEvent (QMoveEvent *me);
1421
1422private:
1423
1424 void releaseObjects();
1425
1426 bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
1427 ULONG aBitsPerPixel, ULONG aBytesPerLine,
1428 ULONG aWidth, ULONG aHeight);
1429 void deleteSurface();
1430 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
1431 void getWindowPosition (void);
1432
1433 LPDIRECTDRAW7 mDDRAW;
1434 LPDIRECTDRAWCLIPPER mClipper;
1435 LPDIRECTDRAWSURFACE7 mSurface;
1436 DDSURFACEDESC2 mSurfaceDesc;
1437 LPDIRECTDRAWSURFACE7 mPrimarySurface;
1438
1439 ulong mPixelFormat;
1440
1441 bool mUsesGuestVRAM;
1442
1443 int mWndX;
1444 int mWndY;
1445
1446 bool mSynchronousUpdates;
1447};
1448
1449#endif
1450
1451/////////////////////////////////////////////////////////////////////////////
1452
1453#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
1454
1455#include <Carbon/Carbon.h>
1456
1457class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
1458{
1459public:
1460
1461 VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
1462 virtual ~VBoxQuartz2DFrameBuffer ();
1463
1464 STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
1465 ULONG aW, ULONG aH);
1466 STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
1467
1468 uchar *address() { return mDataAddress; }
1469 ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
1470 ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
1471 ulong pixelFormat() { return mPixelFormat; };
1472 bool usesGuestVRAM() { return mBitmapData == NULL; }
1473
1474 const CGImageRef imageRef() const { return mImage; }
1475
1476 void paintEvent (QPaintEvent *pe);
1477 void resizeEvent (VBoxResizeEvent *re);
1478
1479private:
1480
1481 void clean();
1482
1483 uchar *mDataAddress;
1484 void *mBitmapData;
1485 ulong mPixelFormat;
1486 CGImageRef mImage;
1487 typedef struct
1488 {
1489 /** The size of this structure expressed in rcts entries. */
1490 ULONG allocated;
1491 /** The number of entries in the rcts array. */
1492 ULONG used;
1493 /** Variable sized array of the rectangle that makes up the region. */
1494 CGRect rcts[1];
1495 } RegionRects;
1496 /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
1497 *
1498 * The protocol for updating and using this has to take into account that
1499 * the producer (SetVisibleRegion) and consumer (paintEvent) are running
1500 * on different threads. Therefore the producer will create a new RegionRects
1501 * structure before atomically replace the existing one. While the consumer
1502 * will read the value by atomically replace it by NULL, and then when its
1503 * done try restore it by cmpxchg. If the producer has already put a new
1504 * region there, it will be discarded (see mRegionUnused).
1505 */
1506 RegionRects volatile *mRegion;
1507 /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
1508 * This is operated with atomic cmpxchg and atomic xchg. */
1509 RegionRects volatile *mRegionUnused;
1510};
1511
1512#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
1513
1514#endif // !___VBoxFrameBuffer_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