3
* VBox frontends: Qt GUI ("VirtualBox"):
4
* VBoxFrameBuffer class and subclasses declarations
8
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
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.
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.
23
#ifndef ___VBoxFrameBuffer_h___
24
#define ___VBoxFrameBuffer_h___
26
#include <iprt/critsect.h>
32
#include <QPaintEvent>
34
#if defined (VBOX_GUI_USE_QGL)
35
#include "VBoxFBOverlay.h"
38
#if defined (VBOX_GUI_USE_SDL)
43
#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
44
// VBox/cdefs.h defines these:
52
class VBoxConsoleView;
54
/////////////////////////////////////////////////////////////////////////////
57
* Frame buffer resize event.
59
class VBoxResizeEvent : public QEvent
63
VBoxResizeEvent (ulong aPixelFormat, uchar *aVRAM,
64
ulong aBitsPerPixel, ulong aBytesPerLine,
65
ulong aWidth, ulong aHeight) :
66
QEvent ((QEvent::Type) VBoxDefs::ResizeEventType),
67
mPixelFormat (aPixelFormat), mVRAM (aVRAM), mBitsPerPixel (aBitsPerPixel),
68
mBytesPerLine (aBytesPerLine), mWidth (aWidth), mHeight (aHeight) {}
69
ulong pixelFormat() { return mPixelFormat; }
70
uchar *VRAM() { return mVRAM; }
71
ulong bitsPerPixel() { return mBitsPerPixel; }
72
ulong bytesPerLine() { return mBytesPerLine; }
73
ulong width() { return mWidth; }
74
ulong height() { return mHeight; }
87
* Frame buffer repaint event.
89
class VBoxRepaintEvent : public QEvent
92
VBoxRepaintEvent (int iX, int iY, int iW, int iH) :
93
QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
94
ex (iX), ey (iY), ew (iW), eh (iH)
96
int x() { return ex; }
97
int y() { return ey; }
98
int width() { return ew; }
99
int height() { return eh; }
105
* Frame buffer set region event.
107
class VBoxSetRegionEvent : public QEvent
110
VBoxSetRegionEvent (const QRegion &aReg)
111
: QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
113
QRegion region() { return mReg; }
118
/////////////////////////////////////////////////////////////////////////////
121
* Common IFramebuffer implementation for all methods used by GUI to maintain
122
* the VM display video memory.
124
* Note that although this class can be called from multiple threads
125
* (in particular, the GUI thread and EMT) it doesn't protect access to every
126
* data field using its mutex lock. This is because all synchronization between
127
* the GUI and the EMT thread is supposed to be done using the
128
* IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
129
* (in particular, the \a aFinished parameter of these methods is responsible
130
* for the synchronization). These methods are always called on EMT and
131
* therefore always follow one another but never in parallel.
133
* Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
134
* IFramebuffer::Unlock() implementations) usually makes sense only if some
135
* third-party thread (i.e. other than GUI or EMT) needs to make sure that
136
* *no* VM display update or resize event can occur while it is accessing
137
* IFramebuffer properties or the underlying display memory storage area.
139
* See IFramebuffer documentation for more info.
142
class VBoxFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
146
VBoxFrameBuffer (VBoxConsoleView *aView);
147
virtual ~VBoxFrameBuffer();
151
#if defined (Q_OS_WIN32)
153
STDMETHOD_(ULONG, AddRef)()
155
return ::InterlockedIncrement (&refcnt);
158
STDMETHOD_(ULONG, Release)()
160
long cnt = ::InterlockedDecrement (&refcnt);
166
VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer)
168
// IFramebuffer COM methods
169
STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
170
STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
171
STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
172
STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *aBitsPerPixel);
173
STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *aBytesPerLine);
174
STDMETHOD(COMGETTER(PixelFormat)) (ULONG *aPixelFormat);
175
STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *aUsesGuestVRAM);
176
STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
177
STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
178
STDMETHOD(COMGETTER(WinId)) (ULONG64 *winId);
183
STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
184
BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
185
ULONG aWidth, ULONG aHeight,
188
STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
191
STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
192
STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
194
STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
196
ulong width() { return mWdt; }
197
ulong height() { return mHgt; }
199
virtual ulong pixelFormat()
201
return FramebufferPixelFormat_FOURCC_RGB;
204
virtual bool usesGuestVRAM()
209
void lock() { RTCritSectEnter(&mCritSect); }
210
void unlock() { RTCritSectLeave(&mCritSect); }
212
virtual uchar *address() = 0;
213
virtual ulong bitsPerPixel() = 0;
214
virtual ulong bytesPerLine() = 0;
217
* Called on the GUI thread (from VBoxConsoleView) when some part of the
218
* VM display viewport needs to be repainted on the host screen.
220
virtual void paintEvent (QPaintEvent *pe) = 0;
223
* Called on the GUI thread (from VBoxConsoleView) after it gets a
224
* VBoxResizeEvent posted from the RequestResize() method implementation.
226
virtual void resizeEvent (VBoxResizeEvent *re)
233
* Called on the GUI thread (from VBoxConsoleView) when the VM console
236
virtual void moveEvent (QMoveEvent * /*me*/ ) {}
238
#ifdef VBOX_WITH_VIDEOHWACCEL
239
/* this method is called from the GUI thread
240
* to perform the actual Video HW Acceleration command processing
241
* the event is framebuffer implementation specific */
242
virtual void doProcessVHWACommand(QEvent * pEvent);
244
virtual void viewportResized(QResizeEvent * /*re*/){}
246
virtual void viewportScrolled(int /*dx*/, int /*dy*/){}
251
VBoxConsoleView *mView;
252
RTCRITSECT mCritSect;
257
#if defined (Q_OS_WIN32)
263
/////////////////////////////////////////////////////////////////////////////
265
#if defined (VBOX_GUI_USE_QIMAGE)
267
class VBoxQImageFrameBuffer : public VBoxFrameBuffer
271
VBoxQImageFrameBuffer (VBoxConsoleView *aView);
273
STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
276
ulong pixelFormat() { return mPixelFormat; }
277
bool usesGuestVRAM() { return mUsesGuestVRAM; }
279
uchar *address() { return mImg.bits(); }
280
ulong bitsPerPixel() { return mImg.depth(); }
281
ulong bytesPerLine() { return mImg.bytesPerLine(); }
283
void paintEvent (QPaintEvent *pe);
284
void resizeEvent (VBoxResizeEvent *re);
296
/////////////////////////////////////////////////////////////////////////////
298
#if defined (VBOX_GUI_USE_QGL)
300
class VBoxQGLFrameBuffer : public VBoxFrameBuffer
304
VBoxQGLFrameBuffer (VBoxConsoleView *aView);
306
STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
308
#ifdef VBOXQGL_PROF_BASE
309
STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
310
BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
311
ULONG aWidth, ULONG aHeight,
315
#ifdef VBOX_WITH_VIDEOHWACCEL
316
STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
319
ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
320
bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
322
uchar *address() { return vboxWidget()->vboxAddress(); }
323
ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
324
ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
326
void paintEvent (QPaintEvent *pe);
327
void resizeEvent (VBoxResizeEvent *re);
328
void doProcessVHWACommand(QEvent * pEvent);
331
// void vboxMakeCurrent();
332
class VBoxGLWidget * vboxWidget();
334
class VBoxVHWACommandElementProcessor mCmdPipe;
339
/////////////////////////////////////////////////////////////////////////////
341
#if defined (VBOX_GUI_USE_SDL)
343
class VBoxSDLFrameBuffer : public VBoxFrameBuffer
347
VBoxSDLFrameBuffer (VBoxConsoleView *aView);
348
virtual ~VBoxSDLFrameBuffer();
350
STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
355
SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
356
return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
361
SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
362
return surf ? surf->format->BitsPerPixel : 0;
367
SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
368
return surf ? surf->pitch : 0;
378
return mSurfVRAM != NULL;
381
void paintEvent (QPaintEvent *pe);
382
void resizeEvent (VBoxResizeEvent *re);
386
SDL_Surface *mScreen;
387
SDL_Surface *mSurfVRAM;
394
/////////////////////////////////////////////////////////////////////////////
396
#if defined (VBOX_GUI_USE_DDRAW)
398
class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
402
VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
403
virtual ~VBoxDDRAWFrameBuffer();
405
STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
408
uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
409
ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
410
ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
412
ulong pixelFormat() { return mPixelFormat; };
414
bool usesGuestVRAM() { return mUsesGuestVRAM; }
416
void paintEvent (QPaintEvent *pe);
417
void resizeEvent (VBoxResizeEvent *re);
418
void moveEvent (QMoveEvent *me);
422
void releaseObjects();
424
bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
425
ULONG aBitsPerPixel, ULONG aBytesPerLine,
426
ULONG aWidth, ULONG aHeight);
427
void deleteSurface();
428
void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
429
void getWindowPosition (void);
431
LPDIRECTDRAW7 mDDRAW;
432
LPDIRECTDRAWCLIPPER mClipper;
433
LPDIRECTDRAWSURFACE7 mSurface;
434
DDSURFACEDESC2 mSurfaceDesc;
435
LPDIRECTDRAWSURFACE7 mPrimarySurface;
444
bool mSynchronousUpdates;
449
/////////////////////////////////////////////////////////////////////////////
451
#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
453
#include <Carbon/Carbon.h>
455
class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
459
VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
460
virtual ~VBoxQuartz2DFrameBuffer ();
462
STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
464
STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
466
uchar *address() { return mDataAddress; }
467
ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
468
ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
469
ulong pixelFormat() { return mPixelFormat; };
470
bool usesGuestVRAM() { return mBitmapData == NULL; }
472
const CGImageRef imageRef() const { return mImage; }
474
void paintEvent (QPaintEvent *pe);
475
void resizeEvent (VBoxResizeEvent *re);
477
#ifndef QT_MAC_USE_COCOA
478
void testAndSetSNCarbonFix();
479
#endif /* QT_MAC_USE_COCOA */
491
/** The size of this structure expressed in rcts entries. */
493
/** The number of entries in the rcts array. */
495
/** Variable sized array of the rectangle that makes up the region. */
498
/** The current valid region, all access is by atomic cmpxchg or atomic xchg.
500
* The protocol for updating and using this has to take into account that
501
* the producer (SetVisibleRegion) and consumer (paintEvent) are running
502
* on different threads. Therefore the producer will create a new RegionRects
503
* structure before atomically replace the existing one. While the consumer
504
* will read the value by atomically replace it by NULL, and then when its
505
* done try restore it by cmpxchg. If the producer has already put a new
506
* region there, it will be discarded (see mRegionUnused).
508
RegionRects volatile *mRegion;
509
/** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
510
* This is operated with atomic cmpxchg and atomic xchg. */
511
RegionRects volatile *mRegionUnused;
513
#ifndef QT_MAC_USE_COCOA
514
bool mSnowLeoCarbonFix;
515
EventHandlerRef mDarwinSNWindowHandlerRef;
516
#endif /* QT_MAC_USE_COCOA */
519
#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
521
#endif // !___VBoxFrameBuffer_h___