VirtualBox

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

Last change on this file since 20906 was 20906, checked in by vboxsync, 16 years ago

video hw accel: color keying & color conversion basics impl for QGL Framebuffer

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 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_WITH_VIDEOHWACCEL
120class VBoxVHWACommandProcessEvent : public QEvent
121{
122public:
123 VBoxVHWACommandProcessEvent (struct _VBOXVHWACMD * pCmd)
124 : QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
125 , mpCmd (pCmd) {}
126 struct _VBOXVHWACMD * command() { return mpCmd; }
127private:
128 struct _VBOXVHWACMD * mpCmd;
129};
130
131#endif
132
133/////////////////////////////////////////////////////////////////////////////
134
135/**
136 * Common IFramebuffer implementation for all methods used by GUI to maintain
137 * the VM display video memory.
138 *
139 * Note that although this class can be called from multiple threads
140 * (in particular, the GUI thread and EMT) it doesn't protect access to every
141 * data field using its mutex lock. This is because all synchronization between
142 * the GUI and the EMT thread is supposed to be done using the
143 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
144 * (in particular, the \a aFinished parameter of these methods is responsible
145 * for the synchronization). These methods are always called on EMT and
146 * therefore always follow one another but never in parallel.
147 *
148 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
149 * IFramebuffer::Unlock() implementations) usually makes sense only if some
150 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
151 * *no* VM display update or resize event can occur while it is accessing
152 * IFramebuffer properties or the underlying display memory storage area.
153 *
154 * See IFramebuffer documentation for more info.
155 */
156
157class VBoxFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
158{
159public:
160
161 VBoxFrameBuffer (VBoxConsoleView *aView);
162 virtual ~VBoxFrameBuffer();
163
164 NS_DECL_ISUPPORTS
165
166#if defined (Q_OS_WIN32)
167
168 STDMETHOD_(ULONG, AddRef)()
169 {
170 return ::InterlockedIncrement (&refcnt);
171 }
172
173 STDMETHOD_(ULONG, Release)()
174 {
175 long cnt = ::InterlockedDecrement (&refcnt);
176 if (cnt == 0)
177 delete this;
178 return cnt;
179 }
180
181 STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
182 {
183 if (riid == IID_IUnknown) {
184 *ppObj = this;
185 AddRef();
186 return S_OK;
187 }
188 if (riid == IID_IFramebuffer) {
189 *ppObj = this;
190 AddRef();
191 return S_OK;
192 }
193 *ppObj = NULL;
194 return E_NOINTERFACE;
195 }
196
197#endif
198
199 // IFramebuffer COM methods
200 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
201 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
202 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
203 STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *aBitsPerPixel);
204 STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *aBytesPerLine);
205 STDMETHOD(COMGETTER(PixelFormat)) (ULONG *aPixelFormat);
206 STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *aUsesGuestVRAM);
207 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
208 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
209 STDMETHOD(COMGETTER(WinId)) (ULONG64 *winId);
210
211 STDMETHOD(Lock)();
212 STDMETHOD(Unlock)();
213
214 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
215 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
216 ULONG aWidth, ULONG aHeight,
217 BOOL *aFinished);
218
219 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
220 BOOL *aSupported);
221
222 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
223 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
224
225 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
226
227 ulong width() { return mWdt; }
228 ulong height() { return mHgt; }
229
230 virtual ulong pixelFormat()
231 {
232 return FramebufferPixelFormat_FOURCC_RGB;
233 }
234
235 virtual bool usesGuestVRAM()
236 {
237 return false;
238 }
239
240 void lock() { RTCritSectEnter(&mCritSect); }
241 void unlock() { RTCritSectLeave(&mCritSect); }
242
243 virtual uchar *address() = 0;
244 virtual ulong bitsPerPixel() = 0;
245 virtual ulong bytesPerLine() = 0;
246
247 /**
248 * Called on the GUI thread (from VBoxConsoleView) when some part of the
249 * VM display viewport needs to be repainted on the host screen.
250 */
251 virtual void paintEvent (QPaintEvent *pe) = 0;
252
253 /**
254 * Called on the GUI thread (from VBoxConsoleView) after it gets a
255 * VBoxResizeEvent posted from the RequestResize() method implementation.
256 */
257 virtual void resizeEvent (VBoxResizeEvent *re)
258 {
259 mWdt = re->width();
260 mHgt = re->height();
261 }
262
263 /**
264 * Called on the GUI thread (from VBoxConsoleView) when the VM console
265 * window is moved.
266 */
267 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
268
269#ifdef VBOX_WITH_VIDEOHWACCEL
270 /* this method is called from the GUI thread
271 * to perform the actual Video HW Acceleration command processing */
272 virtual void doProcessVHWACommand(struct _VBOXVHWACMD * pCommand);
273#endif
274
275protected:
276
277 VBoxConsoleView *mView;
278 RTCRITSECT mCritSect;
279 int mWdt;
280 int mHgt;
281 uint64_t mWinId;
282
283#if defined (Q_OS_WIN32)
284private:
285 long refcnt;
286#endif
287};
288
289/////////////////////////////////////////////////////////////////////////////
290
291#if defined (VBOX_GUI_USE_QIMAGE)
292
293class VBoxQImageFrameBuffer : public VBoxFrameBuffer
294{
295public:
296
297 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
298
299 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
300 ULONG aW, ULONG aH);
301
302 ulong pixelFormat() { return mPixelFormat; }
303 bool usesGuestVRAM() { return mUsesGuestVRAM; }
304
305 uchar *address() { return mImg.bits(); }
306 ulong bitsPerPixel() { return mImg.depth(); }
307 ulong bytesPerLine() { return mImg.bytesPerLine(); }
308
309 void paintEvent (QPaintEvent *pe);
310 void resizeEvent (VBoxResizeEvent *re);
311
312private:
313
314 QPixmap mPM;
315 QImage mImg;
316 ulong mPixelFormat;
317 bool mUsesGuestVRAM;
318};
319
320#endif
321
322/////////////////////////////////////////////////////////////////////////////
323
324#if defined (VBOX_GUI_USE_QGL)
325class VBoxVHWADirtyRect
326{
327public:
328 VBoxVHWADirtyRect() :
329 mIsClear(true)
330 {}
331
332 VBoxVHWADirtyRect(const QRect & aRect)
333 {
334 if(aRect.isEmpty())
335 {
336 mIsClear = false;
337 mRect = aRect;
338 }
339 else
340 {
341 mIsClear = true;
342 }
343 }
344
345 bool isClear() const { return mIsClear; }
346
347 void add(const QRect & aRect)
348 {
349 if(aRect.isEmpty())
350 return;
351
352 mRect = mIsClear ? aRect : mRect.united(aRect);
353 mIsClear = false;
354 }
355
356 void set(const QRect & aRect)
357 {
358 if(aRect.isEmpty())
359 {
360 mIsClear = true;
361 }
362 else
363 {
364 mRect = aRect;
365 mIsClear = false;
366 }
367 }
368
369 void clear() { mIsClear = true; }
370
371 const QRect & rect() const {return mRect;}
372
373 bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
374
375 bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
376
377 QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
378
379 bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
380
381 void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
382
383private:
384 QRect mRect;
385 bool mIsClear;
386};
387
388class VBoxVHWAColorKey
389{
390public:
391 VBoxVHWAColorKey() :
392 mUpper(0),
393 mLower(0)
394 {}
395
396 VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
397 mUpper(aUpper),
398 mLower(aLower)
399 {}
400
401 uint32_t upper() {return mUpper; }
402 uint32_t lower() {return mLower; }
403private:
404 uint32_t mUpper;
405 uint32_t mLower;
406};
407
408class VBoxVHWAColorFormat
409{
410public:
411
412 VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat) :
413 mInternalFormat(aInternalFormat),
414 mFormat(aFormat),
415 mType(aType),
416 mDataFormat(aDataFormat)
417 {}
418
419 GLint internalFormat() const {return mInternalFormat; }
420 GLenum format() const {return mFormat; }
421 GLenum type() const {return mType; }
422 uint32_t dataFormat() const {return mDataFormat;}
423
424 void pixel2Normalized(uint32_t pix, float &r, float &g, float &b);
425 uint32_t r(uint32_t pix);
426 uint32_t g(uint32_t pix);
427 uint32_t b(uint32_t pix);
428
429private:
430 GLint mInternalFormat;
431 GLenum mFormat;
432 GLenum mType;
433 uint32_t mDataFormat;
434
435 uint32_t mRMask;
436 uint32_t mGMask;
437 uint32_t mBMask;
438 uint32_t mRRange;
439 uint32_t mGRange;
440 uint32_t mBRange;
441
442};
443
444class VBoxVHWASurfaceBase
445{
446public:
447 VBoxVHWASurfaceBase(GLsizei aWidth, GLsizei aHeight,
448 VBoxVHWAColorFormat & aColorFormat,
449 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
450 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey);
451
452 virtual ~VBoxVHWASurfaceBase();
453
454 virtual void init(uchar *pvMem);
455
456 virtual void uninit();
457
458 static void globalInit();
459
460 int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, uint32_t flags, struct _VBOXVHWA_BLTDESC * pBltInfo);
461
462 virtual int lock(const QRect * pRect, uint32_t flags);
463
464 virtual int unlock();
465
466 void paint(const QRect * aRect);
467
468 void performDisplay();
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 uchar * pointAddress(int x, int y) { return mAddress + y*mBytesPerLine + x*mBytesPerPixel; }
477 ulong memSize(){ return mBytesPerLine * mRect.height(); }
478
479 ulong width() { return mRect.width(); }
480 ulong height() { return mRect.height(); }
481
482 GLenum format() {return mColorFormat.format(); }
483 GLint internalFormat() { return mColorFormat.internalFormat(); }
484 GLenum type() { return mColorFormat.type(); }
485 uint32_t dataFormat() {return mColorFormat.dataFormat(); }
486
487 ulong bytesPerPixel() { return mBytesPerPixel; }
488 ulong bytesPerLine() { return mBytesPerLine; }
489
490 const VBoxVHWAColorKey * dstBltCKey() { return mDstBltCKeyValid ? &mDstBltCKey : NULL; }
491 const VBoxVHWAColorKey * srcBltCKey() { return mSrcBltCKeyValid ? &mSrcBltCKey : NULL; }
492 const VBoxVHWAColorKey * dstOverlayCKey() { return mDstOverlayCKeyValid ? &mDstOverlayCKey : NULL; }
493 const VBoxVHWAColorKey * srcOverlayCKey() { return mSrcOverlayCKeyValid ? &mSrcOverlayCKey : NULL; }
494 const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
495
496 /* clients should treat the returned texture as read-only */
497 GLuint textureSynched(const QRect * aRect) { synchTexture(aRect); return mTexture; }
498
499 void setAddress(uchar * addr);
500
501 const QRect& rect() {return mRect;}
502
503// /* surface currently being displayed in a flip chain */
504// virtual bool isPrimary() = 0;
505// /* surface representing the main framebuffer. */
506// virtual bool isMainFramebuffer() = 0;
507 virtual void makeCurrent() = 0;
508#ifdef VBOX_WITH_VIDEOHWACCEL
509 virtual class VBoxVHWAGlProgramMngr * getGlProgramMngr() = 0;
510#endif
511private:
512 void initDisplay();
513 void deleteDisplay();
514 void updateTexture(const QRect * aRect);
515 void synchTexture(const QRect * aRect);
516 void synchMem(const QRect * aRect);
517
518 QRect mRect;
519
520 GLuint mDisplay;
521 bool mDisplayInitialized;
522
523 uchar * mAddress;
524 GLuint mTexture;
525
526 VBoxVHWAColorFormat mColorFormat;
527 VBoxVHWAColorKey mSrcBltCKey;
528 VBoxVHWAColorKey mDstBltCKey;
529 VBoxVHWAColorKey mSrcOverlayCKey;
530 VBoxVHWAColorKey mDstOverlayCKey;
531 bool mSrcBltCKeyValid;
532 bool mDstBltCKeyValid;
533 bool mSrcOverlayCKeyValid;
534 bool mDstOverlayCKeyValid;
535 GLenum mFormat;
536 GLint mInternalFormat;
537 GLenum mType;
538// ulong mDisplayWidth;
539// ulong mDisplayHeight;
540 ulong mBytesPerPixel;
541 ulong mBytesPerLine;
542
543 int mLockCount;
544 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
545 VBoxVHWADirtyRect mUpdateMemRect;
546 /*in case of blit we blit from another surface's texture, so our current texture gets durty */
547 VBoxVHWADirtyRect mUpdateFB2TexRect;
548 /*in case of blit the memory buffer does not get updated until we need it, e.g. for paint or lock operations */
549 VBoxVHWADirtyRect mUpdateFB2MemRect;
550
551 bool mFreeAddress;
552};
553
554class VBoxVHWASurfaceQGL : public VBoxVHWASurfaceBase
555{
556public:
557 VBoxVHWASurfaceQGL(GLsizei aWidth, GLsizei aHeight,
558 VBoxVHWAColorFormat & aColorFormat,
559 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
560 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
561 class VBoxGLWidget *pWidget,
562 bool bBackBuffer) :
563 VBoxVHWASurfaceBase(aWidth, aHeight,
564 aColorFormat,
565 pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey),
566 mWidget(pWidget),
567 mCreateBuf(bBackBuffer)
568 {}
569
570 void makeCurrent();
571
572 void init(uchar *pvMem);
573
574 int unlock()
575 {
576 int rc = VBoxVHWASurfaceBase::unlock();
577 if(!mBuffer)
578 performDisplay();
579 return rc;
580 }
581#ifdef VBOX_WITH_VIDEOHWACCEL
582 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
583#endif
584private:
585 class VBoxGLWidget *mWidget;
586 class QGLPixelBuffer *mBuffer;
587 bool mCreateBuf;
588};
589
590class VBoxGLWidget : public QGLWidget
591{
592public:
593 VBoxGLWidget (QWidget *aParent);
594 ~VBoxGLWidget();
595
596 ulong vboxPixelFormat() { return mPixelFormat; }
597 bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
598
599 uchar *vboxAddress() { return pDisplay ? pDisplay->address() : NULL; }
600 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
601 ulong vboxBitsPerPixel() { return mBitsPerPixel; }
602 ulong vboxBytesPerLine() { return pDisplay ? pDisplay->bytesPerLine() : NULL; }
603
604typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
605//typedef FNVBOXQGLOP *PFNVBOXQGLOP;
606
607 void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe);}
608 void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re);}
609#ifdef VBOX_WITH_VIDEOHWACCEL
610 void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
611 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr();
612#endif
613
614 VBoxVHWASurfaceQGL * vboxGetSurface() { return pDisplay; }
615protected:
616// void resizeGL (int height, int width);
617
618 void paintGL() { (this->*mpfnOp)(mOpContext);}
619
620 void initializeGL();
621
622private:
623// void vboxDoInitDisplay();
624// void vboxDoDeleteDisplay();
625// void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
626 void vboxDoResize(void *re);
627 void vboxDoPaint(void *rec);
628#ifdef VBOX_WITH_VIDEOHWACCEL
629 void vboxDoVHWACmd(void *cmd);
630 void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
631 {
632 if (pSurface->addressAlocated())
633 {
634 uchar * addr = vboxVRAMAddressFromOffset(offset);
635 if(addr)
636 {
637 pSurface->setAddress(addr);
638 }
639 }
640 }
641 int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
642 int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
643 int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
644 int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
645 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
646 int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
647 int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
648 int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
649#endif
650
651 VBoxVHWASurfaceQGL * pDisplay;
652 /* we need to do all opengl stuff in the paintGL context,
653 * submit the operation to be performed */
654 void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext) {mpfnOp = pfn; mOpContext = pContext; updateGL();}
655
656 PFNVBOXQGLOP mpfnOp;
657 void *mOpContext;
658
659 ulong mBitsPerPixel;
660 ulong mPixelFormat;
661 bool mUsesGuestVRAM;
662
663#ifdef VBOX_WITH_VIDEOHWACCEL
664 class VBoxVHWAGlProgramMngr *mpMngr;
665#endif
666};
667
668
669class VBoxQGLFrameBuffer : public VBoxFrameBuffer
670{
671public:
672
673 VBoxQGLFrameBuffer (VBoxConsoleView *aView);
674
675 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
676 ULONG aW, ULONG aH);
677
678#ifdef VBOX_WITH_VIDEOHWACCEL
679 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
680#endif
681
682 ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
683 bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
684
685 uchar *address() { return vboxWidget()->vboxAddress(); }
686 ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
687 ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
688
689 void paintEvent (QPaintEvent *pe);
690 void resizeEvent (VBoxResizeEvent *re);
691#ifdef VBOX_WITH_VIDEOHWACCEL
692 void doProcessVHWACommand(struct _VBOXVHWACMD * pCommand);
693#endif
694
695private:
696 void vboxMakeCurrent();
697 VBoxGLWidget * vboxWidget();
698};
699
700
701#endif
702
703/////////////////////////////////////////////////////////////////////////////
704
705#if defined (VBOX_GUI_USE_SDL)
706
707class VBoxSDLFrameBuffer : public VBoxFrameBuffer
708{
709public:
710
711 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
712 virtual ~VBoxSDLFrameBuffer();
713
714 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
715 ULONG aW, ULONG aH);
716
717 uchar *address()
718 {
719 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
720 return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
721 }
722
723 ulong bitsPerPixel()
724 {
725 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
726 return surf ? surf->format->BitsPerPixel : 0;
727 }
728
729 ulong bytesPerLine()
730 {
731 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
732 return surf ? surf->pitch : 0;
733 }
734
735 ulong pixelFormat()
736 {
737 return mPixelFormat;
738 }
739
740 bool usesGuestVRAM()
741 {
742 return mSurfVRAM != NULL;
743 }
744
745 void paintEvent (QPaintEvent *pe);
746 void resizeEvent (VBoxResizeEvent *re);
747
748private:
749
750 SDL_Surface *mScreen;
751 SDL_Surface *mSurfVRAM;
752
753 ulong mPixelFormat;
754};
755
756#endif
757
758/////////////////////////////////////////////////////////////////////////////
759
760#if defined (VBOX_GUI_USE_DDRAW)
761
762class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
763{
764public:
765
766 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
767 virtual ~VBoxDDRAWFrameBuffer();
768
769 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
770 ULONG aW, ULONG aH);
771
772 uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
773 ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
774 ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
775
776 ulong pixelFormat() { return mPixelFormat; };
777
778 bool usesGuestVRAM() { return mUsesGuestVRAM; }
779
780 void paintEvent (QPaintEvent *pe);
781 void resizeEvent (VBoxResizeEvent *re);
782 void moveEvent (QMoveEvent *me);
783
784private:
785
786 void releaseObjects();
787
788 bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
789 ULONG aBitsPerPixel, ULONG aBytesPerLine,
790 ULONG aWidth, ULONG aHeight);
791 void deleteSurface();
792 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
793 void getWindowPosition (void);
794
795 LPDIRECTDRAW7 mDDRAW;
796 LPDIRECTDRAWCLIPPER mClipper;
797 LPDIRECTDRAWSURFACE7 mSurface;
798 DDSURFACEDESC2 mSurfaceDesc;
799 LPDIRECTDRAWSURFACE7 mPrimarySurface;
800
801 ulong mPixelFormat;
802
803 bool mUsesGuestVRAM;
804
805 int mWndX;
806 int mWndY;
807
808 bool mSynchronousUpdates;
809};
810
811#endif
812
813/////////////////////////////////////////////////////////////////////////////
814
815#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
816
817#include <Carbon/Carbon.h>
818
819class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
820{
821public:
822
823 VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
824 virtual ~VBoxQuartz2DFrameBuffer ();
825
826 STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
827 ULONG aW, ULONG aH);
828 STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
829
830 uchar *address() { return mDataAddress; }
831 ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
832 ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
833 ulong pixelFormat() { return mPixelFormat; };
834 bool usesGuestVRAM() { return mBitmapData == NULL; }
835
836 const CGImageRef imageRef() const { return mImage; }
837
838 void paintEvent (QPaintEvent *pe);
839 void resizeEvent (VBoxResizeEvent *re);
840
841private:
842
843 void clean();
844
845 uchar *mDataAddress;
846 void *mBitmapData;
847 ulong mPixelFormat;
848 CGImageRef mImage;
849 typedef struct
850 {
851 /** The size of this structure expressed in rcts entries. */
852 ULONG allocated;
853 /** The number of entries in the rcts array. */
854 ULONG used;
855 /** Variable sized array of the rectangle that makes up the region. */
856 CGRect rcts[1];
857 } RegionRects;
858 /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
859 *
860 * The protocol for updating and using this has to take into account that
861 * the producer (SetVisibleRegion) and consumer (paintEvent) are running
862 * on different threads. Therefore the producer will create a new RegionRects
863 * structure before atomically replace the existing one. While the consumer
864 * will read the value by atomically replace it by NULL, and then when its
865 * done try restore it by cmpxchg. If the producer has already put a new
866 * region there, it will be discarded (see mRegionUnused).
867 */
868 RegionRects volatile *mRegion;
869 /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
870 * This is operated with atomic cmpxchg and atomic xchg. */
871 RegionRects volatile *mRegionUnused;
872};
873
874#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
875
876#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