VirtualBox

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

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

video 2d accel: move overlay functionality to a separate class/files, make it easy to reuse with different framebuffers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 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//#define VBOXQGL_PROF_BASE 1
26//#define VBOXQGL_DBG_SURF 1
27#include "COMDefs.h"
28#include <iprt/critsect.h>
29
30/* Qt includes */
31#include <QImage>
32#include <QPixmap>
33#include <QMutex>
34#include <QPaintEvent>
35#include <QMoveEvent>
36#if defined (VBOX_GUI_USE_QGL)
37#include "VBoxFBOverlay.h"
38#endif
39
40#if defined (VBOX_GUI_USE_SDL)
41#include <SDL.h>
42#include <signal.h>
43#endif
44
45#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
46// VBox/cdefs.h defines these:
47#undef LOWORD
48#undef HIWORD
49#undef LOBYTE
50#undef HIBYTE
51#include <ddraw.h>
52#endif
53
54class VBoxConsoleView;
55
56/////////////////////////////////////////////////////////////////////////////
57
58/**
59 * Frame buffer resize event.
60 */
61class VBoxResizeEvent : public QEvent
62{
63public:
64
65 VBoxResizeEvent (ulong aPixelFormat, uchar *aVRAM,
66 ulong aBitsPerPixel, ulong aBytesPerLine,
67 ulong aWidth, ulong aHeight) :
68 QEvent ((QEvent::Type) VBoxDefs::ResizeEventType),
69 mPixelFormat (aPixelFormat), mVRAM (aVRAM), mBitsPerPixel (aBitsPerPixel),
70 mBytesPerLine (aBytesPerLine), mWidth (aWidth), mHeight (aHeight) {}
71 ulong pixelFormat() { return mPixelFormat; }
72 uchar *VRAM() { return mVRAM; }
73 ulong bitsPerPixel() { return mBitsPerPixel; }
74 ulong bytesPerLine() { return mBytesPerLine; }
75 ulong width() { return mWidth; }
76 ulong height() { return mHeight; }
77
78private:
79
80 ulong mPixelFormat;
81 uchar *mVRAM;
82 ulong mBitsPerPixel;
83 ulong mBytesPerLine;
84 ulong mWidth;
85 ulong mHeight;
86};
87
88/**
89 * Frame buffer repaint event.
90 */
91class VBoxRepaintEvent : public QEvent
92{
93public:
94 VBoxRepaintEvent (int x, int y, int w, int h) :
95 QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
96 ex (x), ey (y), ew (w), eh (h)
97 {}
98 int x() { return ex; }
99 int y() { return ey; }
100 int width() { return ew; }
101 int height() { return eh; }
102private:
103 int ex, ey, ew, eh;
104};
105
106/**
107 * Frame buffer set region event.
108 */
109class VBoxSetRegionEvent : public QEvent
110{
111public:
112 VBoxSetRegionEvent (const QRegion &aReg)
113 : QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
114 , mReg (aReg) {}
115 QRegion region() { return mReg; }
116private:
117 QRegion mReg;
118};
119
120/////////////////////////////////////////////////////////////////////////////
121
122/**
123 * Common IFramebuffer implementation for all methods used by GUI to maintain
124 * the VM display video memory.
125 *
126 * Note that although this class can be called from multiple threads
127 * (in particular, the GUI thread and EMT) it doesn't protect access to every
128 * data field using its mutex lock. This is because all synchronization between
129 * the GUI and the EMT thread is supposed to be done using the
130 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
131 * (in particular, the \a aFinished parameter of these methods is responsible
132 * for the synchronization). These methods are always called on EMT and
133 * therefore always follow one another but never in parallel.
134 *
135 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
136 * IFramebuffer::Unlock() implementations) usually makes sense only if some
137 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
138 * *no* VM display update or resize event can occur while it is accessing
139 * IFramebuffer properties or the underlying display memory storage area.
140 *
141 * See IFramebuffer documentation for more info.
142 */
143
144class VBoxFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
145{
146public:
147
148 VBoxFrameBuffer (VBoxConsoleView *aView);
149 virtual ~VBoxFrameBuffer();
150
151 NS_DECL_ISUPPORTS
152
153#if defined (Q_OS_WIN32)
154
155 STDMETHOD_(ULONG, AddRef)()
156 {
157 return ::InterlockedIncrement (&refcnt);
158 }
159
160 STDMETHOD_(ULONG, Release)()
161 {
162 long cnt = ::InterlockedDecrement (&refcnt);
163 if (cnt == 0)
164 delete this;
165 return cnt;
166 }
167#endif
168 VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer)
169
170 // IFramebuffer COM methods
171 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
172 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
173 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
174 STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *aBitsPerPixel);
175 STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *aBytesPerLine);
176 STDMETHOD(COMGETTER(PixelFormat)) (ULONG *aPixelFormat);
177 STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *aUsesGuestVRAM);
178 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
179 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
180 STDMETHOD(COMGETTER(WinId)) (ULONG64 *winId);
181
182 STDMETHOD(Lock)();
183 STDMETHOD(Unlock)();
184
185 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
186 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
187 ULONG aWidth, ULONG aHeight,
188 BOOL *aFinished);
189
190 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
191 BOOL *aSupported);
192
193 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
194 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
195
196 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
197
198 ulong width() { return mWdt; }
199 ulong height() { return mHgt; }
200
201 virtual ulong pixelFormat()
202 {
203 return FramebufferPixelFormat_FOURCC_RGB;
204 }
205
206 virtual bool usesGuestVRAM()
207 {
208 return false;
209 }
210
211 void lock() { RTCritSectEnter(&mCritSect); }
212 void unlock() { RTCritSectLeave(&mCritSect); }
213
214 virtual uchar *address() = 0;
215 virtual ulong bitsPerPixel() = 0;
216 virtual ulong bytesPerLine() = 0;
217
218 /**
219 * Called on the GUI thread (from VBoxConsoleView) when some part of the
220 * VM display viewport needs to be repainted on the host screen.
221 */
222 virtual void paintEvent (QPaintEvent *pe) = 0;
223
224 /**
225 * Called on the GUI thread (from VBoxConsoleView) after it gets a
226 * VBoxResizeEvent posted from the RequestResize() method implementation.
227 */
228 virtual void resizeEvent (VBoxResizeEvent *re)
229 {
230 mWdt = re->width();
231 mHgt = re->height();
232 }
233
234 /**
235 * Called on the GUI thread (from VBoxConsoleView) when the VM console
236 * window is moved.
237 */
238 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
239
240#ifdef VBOX_WITH_VIDEOHWACCEL
241 /* this method is called from the GUI thread
242 * to perform the actual Video HW Acceleration command processing
243 * the event is framebuffer implementation specific */
244 virtual void doProcessVHWACommand(QEvent * pEvent);
245#endif
246
247protected:
248
249 VBoxConsoleView *mView;
250 RTCRITSECT mCritSect;
251 int mWdt;
252 int mHgt;
253 uint64_t mWinId;
254
255#if defined (Q_OS_WIN32)
256private:
257 long refcnt;
258#endif
259};
260
261/////////////////////////////////////////////////////////////////////////////
262
263#if defined (VBOX_GUI_USE_QIMAGE)
264
265class VBoxQImageFrameBuffer : public VBoxFrameBuffer
266{
267public:
268
269 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
270
271 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
272 ULONG aW, ULONG aH);
273
274 ulong pixelFormat() { return mPixelFormat; }
275 bool usesGuestVRAM() { return mUsesGuestVRAM; }
276
277 uchar *address() { return mImg.bits(); }
278 ulong bitsPerPixel() { return mImg.depth(); }
279 ulong bytesPerLine() { return mImg.bytesPerLine(); }
280
281 void paintEvent (QPaintEvent *pe);
282 void resizeEvent (VBoxResizeEvent *re);
283
284private:
285
286 QPixmap mPM;
287 QImage mImg;
288 ulong mPixelFormat;
289 bool mUsesGuestVRAM;
290};
291
292#endif
293
294/////////////////////////////////////////////////////////////////////////////
295
296#if defined (VBOX_GUI_USE_QGL)
297
298class VBoxQGLFrameBuffer : public VBoxFrameBuffer
299{
300public:
301
302 VBoxQGLFrameBuffer (VBoxConsoleView *aView);
303
304 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
305 ULONG aW, ULONG aH);
306#ifdef VBOXQGL_PROF_BASE
307 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
308 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
309 ULONG aWidth, ULONG aHeight,
310 BOOL *aFinished);
311#endif
312
313#ifdef VBOX_WITH_VIDEOHWACCEL
314 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
315#endif
316
317 ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
318 bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
319
320 uchar *address() { return vboxWidget()->vboxAddress(); }
321 ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
322 ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
323
324 void paintEvent (QPaintEvent *pe);
325 void resizeEvent (VBoxResizeEvent *re);
326 void doProcessVHWACommand(QEvent * pEvent);
327
328private:
329// void vboxMakeCurrent();
330 class VBoxGLWidget * vboxWidget();
331
332 class VBoxVHWACommandElementProcessor mCmdPipe;
333};
334
335#ifdef VBOX_WITH_VIDEOHWACCEL
336class VBoxQImageOverlayFrameBuffer : public VBoxQImageFrameBuffer
337{
338public:
339 VBoxQImageOverlayFrameBuffer (VBoxConsoleView *aView);
340
341
342 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
343
344 void doProcessVHWACommand(QEvent * pEvent);
345
346 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
347 ULONG aW, ULONG aH);
348
349 void paintEvent (QPaintEvent *pe);
350 void resizeEvent (VBoxResizeEvent *re);
351private:
352 VBoxQGLOverlay mOverlay;
353};
354#endif
355
356#endif
357
358/////////////////////////////////////////////////////////////////////////////
359
360#if defined (VBOX_GUI_USE_SDL)
361
362class VBoxSDLFrameBuffer : public VBoxFrameBuffer
363{
364public:
365
366 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
367 virtual ~VBoxSDLFrameBuffer();
368
369 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
370 ULONG aW, ULONG aH);
371
372 uchar *address()
373 {
374 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
375 return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
376 }
377
378 ulong bitsPerPixel()
379 {
380 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
381 return surf ? surf->format->BitsPerPixel : 0;
382 }
383
384 ulong bytesPerLine()
385 {
386 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
387 return surf ? surf->pitch : 0;
388 }
389
390 ulong pixelFormat()
391 {
392 return mPixelFormat;
393 }
394
395 bool usesGuestVRAM()
396 {
397 return mSurfVRAM != NULL;
398 }
399
400 void paintEvent (QPaintEvent *pe);
401 void resizeEvent (VBoxResizeEvent *re);
402
403private:
404
405 SDL_Surface *mScreen;
406 SDL_Surface *mSurfVRAM;
407
408 ulong mPixelFormat;
409};
410
411#endif
412
413/////////////////////////////////////////////////////////////////////////////
414
415#if defined (VBOX_GUI_USE_DDRAW)
416
417class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
418{
419public:
420
421 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
422 virtual ~VBoxDDRAWFrameBuffer();
423
424 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
425 ULONG aW, ULONG aH);
426
427 uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
428 ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
429 ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
430
431 ulong pixelFormat() { return mPixelFormat; };
432
433 bool usesGuestVRAM() { return mUsesGuestVRAM; }
434
435 void paintEvent (QPaintEvent *pe);
436 void resizeEvent (VBoxResizeEvent *re);
437 void moveEvent (QMoveEvent *me);
438
439private:
440
441 void releaseObjects();
442
443 bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
444 ULONG aBitsPerPixel, ULONG aBytesPerLine,
445 ULONG aWidth, ULONG aHeight);
446 void deleteSurface();
447 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
448 void getWindowPosition (void);
449
450 LPDIRECTDRAW7 mDDRAW;
451 LPDIRECTDRAWCLIPPER mClipper;
452 LPDIRECTDRAWSURFACE7 mSurface;
453 DDSURFACEDESC2 mSurfaceDesc;
454 LPDIRECTDRAWSURFACE7 mPrimarySurface;
455
456 ulong mPixelFormat;
457
458 bool mUsesGuestVRAM;
459
460 int mWndX;
461 int mWndY;
462
463 bool mSynchronousUpdates;
464};
465
466#endif
467
468/////////////////////////////////////////////////////////////////////////////
469
470#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
471
472#include <Carbon/Carbon.h>
473
474class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
475{
476public:
477
478 VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
479 virtual ~VBoxQuartz2DFrameBuffer ();
480
481 STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
482 ULONG aW, ULONG aH);
483 STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
484
485 uchar *address() { return mDataAddress; }
486 ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
487 ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
488 ulong pixelFormat() { return mPixelFormat; };
489 bool usesGuestVRAM() { return mBitmapData == NULL; }
490
491 const CGImageRef imageRef() const { return mImage; }
492
493 void paintEvent (QPaintEvent *pe);
494 void resizeEvent (VBoxResizeEvent *re);
495
496private:
497
498 void clean();
499
500 uchar *mDataAddress;
501 void *mBitmapData;
502 ulong mPixelFormat;
503 CGImageRef mImage;
504 typedef struct
505 {
506 /** The size of this structure expressed in rcts entries. */
507 ULONG allocated;
508 /** The number of entries in the rcts array. */
509 ULONG used;
510 /** Variable sized array of the rectangle that makes up the region. */
511 CGRect rcts[1];
512 } RegionRects;
513 /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
514 *
515 * The protocol for updating and using this has to take into account that
516 * the producer (SetVisibleRegion) and consumer (paintEvent) are running
517 * on different threads. Therefore the producer will create a new RegionRects
518 * structure before atomically replace the existing one. While the consumer
519 * will read the value by atomically replace it by NULL, and then when its
520 * done try restore it by cmpxchg. If the producer has already put a new
521 * region there, it will be discarded (see mRegionUnused).
522 */
523 RegionRects volatile *mRegion;
524 /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
525 * This is operated with atomic cmpxchg and atomic xchg. */
526 RegionRects volatile *mRegionUnused;
527};
528
529#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
530
531#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