VirtualBox

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

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

video hw accel: colorkey support in guest driver, checking gl caps (version & extension) in QGL gramebuffer, some bugfixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.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() const {return mUpper; }
402 uint32_t lower() const {return mLower; }
403private:
404 uint32_t mUpper;
405 uint32_t mLower;
406};
407
408class VBoxVHWAColorComponent
409{
410public:
411 VBoxVHWAColorComponent() :
412 mMask(0),
413 mRange(0),
414 mOffset(32),
415 mcBits(0)
416 {}
417
418 VBoxVHWAColorComponent(uint32_t aMask);
419
420 uint32_t mask() const { return mMask; }
421 uint32_t range() const { return mRange; }
422 uint32_t offset() const { return mOffset; }
423 uint32_t cBits() const { return mcBits; }
424 uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
425 float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
426private:
427 uint32_t mMask;
428 uint32_t mRange;
429 uint32_t mOffset;
430 uint32_t mcBits;
431};
432
433class VBoxVHWAColorFormat
434{
435public:
436
437// VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
438 VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
439
440 GLint internalFormat() const {return mInternalFormat; }
441 GLenum format() const {return mFormat; }
442 GLenum type() const {return mType; }
443 bool isValid() const {return mBitsPerPixel != 0; }
444 uint32_t dataFormat() const {return mDataFormat;}
445 uint32_t bitsPerPixel() const { return mBitsPerPixel; }
446 void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
447// uint32_t r(uint32_t pix);
448// uint32_t g(uint32_t pix);
449// uint32_t b(uint32_t pix);
450
451private:
452 void VBoxVHWAColorFormat::init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
453
454 GLint mInternalFormat;
455 GLenum mFormat;
456 GLenum mType;
457 uint32_t mDataFormat;
458
459 uint32_t mBitsPerPixel;
460
461 VBoxVHWAColorComponent mR;
462 VBoxVHWAColorComponent mG;
463 VBoxVHWAColorComponent mB;
464};
465
466class VBoxVHWASurfaceBase
467{
468public:
469 VBoxVHWASurfaceBase(GLsizei aWidth, GLsizei aHeight,
470 VBoxVHWAColorFormat & aColorFormat,
471 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
472 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey);
473
474 virtual ~VBoxVHWASurfaceBase();
475
476 virtual void init(uchar *pvMem);
477
478 virtual void uninit();
479
480 static void globalInit();
481
482 int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
483
484 virtual int lock(const QRect * pRect, uint32_t flags);
485
486 virtual int unlock();
487
488 void paint(const QRect * aRect);
489
490 void performDisplay();
491
492 static ulong calcBytesPerPixel(GLenum format, GLenum type);
493
494 static GLsizei makePowerOf2(GLsizei val);
495
496 bool addressAlocated() const { return mFreeAddress; }
497 uchar * address(){ return mAddress; }
498 uchar * pointAddress(int x, int y) { return mAddress + y*mBytesPerLine + x*mBytesPerPixel; }
499 ulong memSize(){ return mBytesPerLine * mRect.height(); }
500
501 ulong width() { return mRect.width(); }
502 ulong height() { return mRect.height(); }
503
504 GLenum format() {return mColorFormat.format(); }
505 GLint internalFormat() { return mColorFormat.internalFormat(); }
506 GLenum type() { return mColorFormat.type(); }
507 uint32_t dataFormat() {return mColorFormat.dataFormat(); }
508
509 ulong bytesPerPixel() { return mBytesPerPixel; }
510 ulong bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
511 ulong bytesPerLine() { return mBytesPerLine; }
512
513 const VBoxVHWAColorKey * dstBltCKey() { return mDstBltCKeyValid ? &mDstBltCKey : NULL; }
514 const VBoxVHWAColorKey * srcBltCKey() { return mSrcBltCKeyValid ? &mSrcBltCKey : NULL; }
515 const VBoxVHWAColorKey * dstOverlayCKey() { return mDstOverlayCKeyValid ? &mDstOverlayCKey : NULL; }
516 const VBoxVHWAColorKey * srcOverlayCKey() { return mSrcOverlayCKeyValid ? &mSrcOverlayCKey : NULL; }
517 const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
518
519 /* clients should treat the returned texture as read-only */
520 GLuint textureSynched(const QRect * aRect) { synchTexture(aRect); return mTexture; }
521
522 void setAddress(uchar * addr);
523
524 const QRect& rect() {return mRect;}
525
526// /* surface currently being displayed in a flip chain */
527// virtual bool isPrimary() = 0;
528// /* surface representing the main framebuffer. */
529// virtual bool isMainFramebuffer() = 0;
530 virtual void makeCurrent() = 0;
531#ifdef VBOX_WITH_VIDEOHWACCEL
532 virtual class VBoxVHWAGlProgramMngr * getGlProgramMngr() = 0;
533 static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey);
534#endif
535private:
536 void initDisplay();
537 void deleteDisplay();
538 void updateTexture(const QRect * aRect);
539 void synchTexture(const QRect * aRect);
540 void synchMem(const QRect * aRect);
541
542 QRect mRect;
543
544 GLuint mDisplay;
545 bool mDisplayInitialized;
546
547 uchar * mAddress;
548 GLuint mTexture;
549
550 VBoxVHWAColorFormat mColorFormat;
551 VBoxVHWAColorKey mSrcBltCKey;
552 VBoxVHWAColorKey mDstBltCKey;
553 VBoxVHWAColorKey mSrcOverlayCKey;
554 VBoxVHWAColorKey mDstOverlayCKey;
555 bool mSrcBltCKeyValid;
556 bool mDstBltCKeyValid;
557 bool mSrcOverlayCKeyValid;
558 bool mDstOverlayCKeyValid;
559 GLenum mFormat;
560 GLint mInternalFormat;
561 GLenum mType;
562// ulong mDisplayWidth;
563// ulong mDisplayHeight;
564 ulong mBytesPerPixel;
565 ulong mBytesPerLine;
566
567 int mLockCount;
568 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
569 VBoxVHWADirtyRect mUpdateMemRect;
570 /*in case of blit we blit from another surface's texture, so our current texture gets durty */
571 VBoxVHWADirtyRect mUpdateFB2TexRect;
572 /*in case of blit the memory buffer does not get updated until we need it, e.g. for paint or lock operations */
573 VBoxVHWADirtyRect mUpdateFB2MemRect;
574
575 bool mFreeAddress;
576};
577
578class VBoxVHWASurfaceQGL : public VBoxVHWASurfaceBase
579{
580public:
581 VBoxVHWASurfaceQGL(GLsizei aWidth, GLsizei aHeight,
582 VBoxVHWAColorFormat & aColorFormat,
583 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
584 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
585 class VBoxGLWidget *pWidget,
586 bool bBackBuffer) :
587 VBoxVHWASurfaceBase(aWidth, aHeight,
588 aColorFormat,
589 pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey),
590 mWidget(pWidget),
591 mCreateBuf(bBackBuffer)
592 {}
593
594 void makeCurrent();
595
596 void init(uchar *pvMem);
597
598// int unlock()
599// {
600// int rc = VBoxVHWASurfaceBase::unlock();
601// if(!mBuffer)
602// performDisplay();
603// return rc;
604// }
605#ifdef VBOX_WITH_VIDEOHWACCEL
606 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
607#endif
608private:
609 class VBoxGLWidget *mWidget;
610 class QGLPixelBuffer *mBuffer;
611 bool mCreateBuf;
612};
613
614class VBoxGLWidget : public QGLWidget
615{
616public:
617 VBoxGLWidget (QWidget *aParent);
618 ~VBoxGLWidget();
619
620 ulong vboxPixelFormat() { return mPixelFormat; }
621 bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
622
623 uchar *vboxAddress() { return pDisplay ? pDisplay->address() : NULL; }
624 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
625 ulong vboxBitsPerPixel() { return pDisplay->bitsPerPixel(); }
626 ulong vboxBytesPerLine() { return pDisplay ? pDisplay->bytesPerLine() : NULL; }
627
628typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
629//typedef FNVBOXQGLOP *PFNVBOXQGLOP;
630
631 void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe);}
632 void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re);}
633#ifdef VBOX_WITH_VIDEOHWACCEL
634 void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
635 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr();
636#endif
637
638 VBoxVHWASurfaceQGL * vboxGetSurface() { return pDisplay; }
639protected:
640// void resizeGL (int height, int width);
641
642 void paintGL() { (this->*mpfnOp)(mOpContext); }
643
644 void initializeGL();
645
646private:
647// void vboxDoInitDisplay();
648// void vboxDoDeleteDisplay();
649// void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
650 void vboxDoResize(void *re);
651 void vboxDoPaint(void *rec);
652#ifdef VBOX_WITH_VIDEOHWACCEL
653 void vboxDoVHWACmd(void *cmd);
654 void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
655 {
656 if (pSurface->addressAlocated())
657 {
658 uchar * addr = vboxVRAMAddressFromOffset(offset);
659 if(addr)
660 {
661 pSurface->setAddress(addr);
662 }
663 }
664 }
665 int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
666 int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
667 int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
668 int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
669 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
670 int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
671 int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
672 int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
673#endif
674
675 VBoxVHWASurfaceQGL * pDisplay;
676 /* we need to do all opengl stuff in the paintGL context,
677 * submit the operation to be performed */
678 void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext) {mpfnOp = pfn; mOpContext = pContext; updateGL();}
679
680 PFNVBOXQGLOP mpfnOp;
681 void *mOpContext;
682
683// ulong mBitsPerPixel;
684 ulong mPixelFormat;
685 bool mUsesGuestVRAM;
686
687#ifdef VBOX_WITH_VIDEOHWACCEL
688 class VBoxVHWAGlProgramMngr *mpMngr;
689#endif
690};
691
692
693class VBoxQGLFrameBuffer : public VBoxFrameBuffer
694{
695public:
696
697 VBoxQGLFrameBuffer (VBoxConsoleView *aView);
698
699 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
700 ULONG aW, ULONG aH);
701
702#ifdef VBOX_WITH_VIDEOHWACCEL
703 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
704#endif
705
706 ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
707 bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
708
709 uchar *address() { return vboxWidget()->vboxAddress(); }
710 ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
711 ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
712
713 void paintEvent (QPaintEvent *pe);
714 void resizeEvent (VBoxResizeEvent *re);
715#ifdef VBOX_WITH_VIDEOHWACCEL
716 void doProcessVHWACommand(struct _VBOXVHWACMD * pCommand);
717#endif
718
719private:
720 void vboxMakeCurrent();
721 VBoxGLWidget * vboxWidget();
722};
723
724
725#endif
726
727/////////////////////////////////////////////////////////////////////////////
728
729#if defined (VBOX_GUI_USE_SDL)
730
731class VBoxSDLFrameBuffer : public VBoxFrameBuffer
732{
733public:
734
735 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
736 virtual ~VBoxSDLFrameBuffer();
737
738 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
739 ULONG aW, ULONG aH);
740
741 uchar *address()
742 {
743 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
744 return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
745 }
746
747 ulong bitsPerPixel()
748 {
749 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
750 return surf ? surf->format->BitsPerPixel : 0;
751 }
752
753 ulong bytesPerLine()
754 {
755 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
756 return surf ? surf->pitch : 0;
757 }
758
759 ulong pixelFormat()
760 {
761 return mPixelFormat;
762 }
763
764 bool usesGuestVRAM()
765 {
766 return mSurfVRAM != NULL;
767 }
768
769 void paintEvent (QPaintEvent *pe);
770 void resizeEvent (VBoxResizeEvent *re);
771
772private:
773
774 SDL_Surface *mScreen;
775 SDL_Surface *mSurfVRAM;
776
777 ulong mPixelFormat;
778};
779
780#endif
781
782/////////////////////////////////////////////////////////////////////////////
783
784#if defined (VBOX_GUI_USE_DDRAW)
785
786class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
787{
788public:
789
790 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
791 virtual ~VBoxDDRAWFrameBuffer();
792
793 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
794 ULONG aW, ULONG aH);
795
796 uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
797 ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
798 ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
799
800 ulong pixelFormat() { return mPixelFormat; };
801
802 bool usesGuestVRAM() { return mUsesGuestVRAM; }
803
804 void paintEvent (QPaintEvent *pe);
805 void resizeEvent (VBoxResizeEvent *re);
806 void moveEvent (QMoveEvent *me);
807
808private:
809
810 void releaseObjects();
811
812 bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
813 ULONG aBitsPerPixel, ULONG aBytesPerLine,
814 ULONG aWidth, ULONG aHeight);
815 void deleteSurface();
816 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
817 void getWindowPosition (void);
818
819 LPDIRECTDRAW7 mDDRAW;
820 LPDIRECTDRAWCLIPPER mClipper;
821 LPDIRECTDRAWSURFACE7 mSurface;
822 DDSURFACEDESC2 mSurfaceDesc;
823 LPDIRECTDRAWSURFACE7 mPrimarySurface;
824
825 ulong mPixelFormat;
826
827 bool mUsesGuestVRAM;
828
829 int mWndX;
830 int mWndY;
831
832 bool mSynchronousUpdates;
833};
834
835#endif
836
837/////////////////////////////////////////////////////////////////////////////
838
839#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
840
841#include <Carbon/Carbon.h>
842
843class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
844{
845public:
846
847 VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
848 virtual ~VBoxQuartz2DFrameBuffer ();
849
850 STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
851 ULONG aW, ULONG aH);
852 STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
853
854 uchar *address() { return mDataAddress; }
855 ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
856 ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
857 ulong pixelFormat() { return mPixelFormat; };
858 bool usesGuestVRAM() { return mBitmapData == NULL; }
859
860 const CGImageRef imageRef() const { return mImage; }
861
862 void paintEvent (QPaintEvent *pe);
863 void resizeEvent (VBoxResizeEvent *re);
864
865private:
866
867 void clean();
868
869 uchar *mDataAddress;
870 void *mBitmapData;
871 ulong mPixelFormat;
872 CGImageRef mImage;
873 typedef struct
874 {
875 /** The size of this structure expressed in rcts entries. */
876 ULONG allocated;
877 /** The number of entries in the rcts array. */
878 ULONG used;
879 /** Variable sized array of the rectangle that makes up the region. */
880 CGRect rcts[1];
881 } RegionRects;
882 /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
883 *
884 * The protocol for updating and using this has to take into account that
885 * the producer (SetVisibleRegion) and consumer (paintEvent) are running
886 * on different threads. Therefore the producer will create a new RegionRects
887 * structure before atomically replace the existing one. While the consumer
888 * will read the value by atomically replace it by NULL, and then when its
889 * done try restore it by cmpxchg. If the producer has already put a new
890 * region there, it will be discarded (see mRegionUnused).
891 */
892 RegionRects volatile *mRegion;
893 /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
894 * This is operated with atomic cmpxchg and atomic xchg. */
895 RegionRects volatile *mRegionUnused;
896};
897
898#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
899
900#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