VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/include/VBoxFrameBuffer.h@ 13384

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

+changed IFramebuffer interface to report id of associated window if there's one
+changed sdl/qt3/qt4 frontends's interface implementations to report this id
+added VBoxSharedCrOpenGL hgcm service
(VBoxManage.exe setextradata lvm_winxp_sp2 VBoxInternal/Devices/VMMDev/0/LUN#0/Config/crOpenGLEnabled 1)
+changed crserver to be launched from vmmdev by guest request
+added hgcm call to supply desired window id to render spu
+changed guest icd driver to initialize hgcm and cause tcpip listener startup on host
+fixed spu finalization
+fixed q3 startup, again :)

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