VirtualBox

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

Last change on this file since 3569 was 3569, checked in by vboxsync, 18 years ago

QueryVisibleRegion -> GetVisibleRegion

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.1 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 innotek GmbH
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23#ifndef __VBoxFrameBuffer_h__
24#define __VBoxFrameBuffer_h__
25
26#include "COMDefs.h"
27
28class VBoxConsoleView;
29
30#include <qmutex.h>
31#include <qevent.h>
32#include <qpixmap.h>
33#include <qimage.h>
34
35#if defined (VBOX_GUI_USE_SDL)
36#include <SDL.h>
37#include <signal.h>
38#endif
39
40#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
41// VBox/cdefs.h defines these:
42#undef LOWORD
43#undef HIWORD
44#undef LOBYTE
45#undef HIBYTE
46#include <ddraw.h>
47#endif
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 VBoxResizeEvent (FramebufferPixelFormat_T f, uchar *v, unsigned l, int w, int h) :
76 QEvent ((QEvent::Type) VBoxDefs::ResizeEventType), fmt (f), vr (v), lsz (l), wdt (w), hgt (h) {}
77 FramebufferPixelFormat_T pixelFormat() { return fmt; }
78 uchar *vram() { return vr; }
79 unsigned lineSize() { return lsz; }
80 int width() { return wdt; }
81 int height() { return hgt; }
82private:
83 FramebufferPixelFormat_T fmt;
84 uchar *vr;
85 unsigned lsz;
86 int wdt;
87 int hgt;
88};
89
90/**
91 * Frame buffer repaint event.
92 */
93class VBoxRepaintEvent : public QEvent
94{
95public:
96 VBoxRepaintEvent (int x, int y, int w, int h) :
97 QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
98 ex (x), ey (y), ew (w), eh (h)
99 {}
100 int x() { return ex; }
101 int y() { return ey; }
102 int width() { return ew; }
103 int height() { return eh; }
104private:
105 int ex, ey, ew, eh;
106};
107
108/////////////////////////////////////////////////////////////////////////////
109
110#if defined (VBOX_GUI_USE_REFRESH_TIMER)
111
112/**
113 * Copies the current VM video buffer contents to the pixmap referenced
114 * by the argument. The return value indicates whether the
115 * buffer has been updated since the last call to this method or not.
116 *
117 * The copy operation is atomic (guarded by a mutex).
118 *
119 * This method is intentionally inlined for faster execution and should be
120 * called only by VBoxConsoleView members.
121 *
122 * @return true if the pixmap is updated, and false otherwise.
123 */
124inline bool display_to_pixmap( const CConsole &c, QPixmap &pm )
125{
126 CDisplay display = c.GetDisplay();
127
128 uint8_t *addr = (uint8_t *) display.LockFramebuffer();
129 AssertMsg (addr, ("The buffer address must not be null"));
130
131 bool rc = pm.convertFromImage (QImage (addr,
132 display.GetWidth(), display.GetHeight(),
133 display.GetColorDepth(),
134 0, 0, QImage::LittleEndian));
135 AssertMsg (rc, ("convertFromImage() must always return true"));
136
137 display.UnlockFramebuffer();
138
139 return rc;
140}
141
142#endif
143
144/////////////////////////////////////////////////////////////////////////////
145
146/**
147 * Common IFramebuffer implementation for all methods used by GUI to maintain
148 * the VM display video memory.
149 *
150 * Note that although this class can be called from multiple threads
151 * (in particular, the GUI thread and EMT) it doesn't protect access to every
152 * data field using its mutex lock. This is because all synchronization between
153 * the GUI and the EMT thread is supposed to be done using the
154 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
155 * (in particular, the \a aFinished parameter of these methods is responsible
156 * for the synchronization). These methods are always called on EMT and
157 * therefore always follow one another but never in parallel.
158 *
159 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
160 * IFramebuffer::Unlock() implementations) usually makes sense only if some
161 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
162 * *no* VM display update or resize event can occur while it is accessing
163 * IFramebuffer properties or the underlying display memory storage area.
164 *
165 * See IFramebuffer documentation for more info.
166 */
167
168class VBoxFrameBuffer : public IFramebuffer
169{
170public:
171
172 VBoxFrameBuffer (VBoxConsoleView *aView);
173 virtual ~VBoxFrameBuffer();
174
175 NS_DECL_ISUPPORTS
176
177#if defined (Q_OS_WIN32)
178 STDMETHOD_(ULONG, AddRef)() {
179 return ::InterlockedIncrement (&refcnt);
180 }
181 STDMETHOD_(ULONG, Release)()
182 {
183 long cnt = ::InterlockedDecrement (&refcnt);
184 if (cnt == 0)
185 delete this;
186 return cnt;
187 }
188 STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
189 {
190 if (riid == IID_IUnknown) {
191 *ppObj = this;
192 AddRef();
193 return S_OK;
194 }
195 if (riid == IID_IFramebuffer) {
196 *ppObj = this;
197 AddRef();
198 return S_OK;
199 }
200 *ppObj = NULL;
201 return E_NOINTERFACE;
202 }
203#endif
204
205 // IFramebuffer COM methods
206 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
207 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
208 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
209 STDMETHOD(COMGETTER(ColorDepth)) (ULONG *aColorDepth);
210 STDMETHOD(COMGETTER(LineSize)) (ULONG *aLineSize);
211 STDMETHOD(COMGETTER(PixelFormat)) (FramebufferPixelFormat_T *aPixelFormat);
212 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
213 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
214
215 STDMETHOD(Lock)();
216 STDMETHOD(Unlock)();
217
218 STDMETHOD(RequestResize) (ULONG aScreenId, FramebufferPixelFormat_T aPixelFormat,
219 BYTE *aVRAM, ULONG aLineSize,
220 ULONG aWidth, ULONG aHeight,
221 BOOL *aFinished);
222
223 STDMETHOD(OperationSupported)(FramebufferAccelerationOperation_T aOperation,
224 BOOL *aSupported);
225 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
226 BOOL *aSupported);
227 STDMETHOD(SolidFill) (ULONG aX, ULONG aY, ULONG aWidth, ULONG aHeight,
228 ULONG aColor, BOOL *aHandled);
229 STDMETHOD(CopyScreenBits) (ULONG aXDst, ULONG aYDst, ULONG aXSrc, ULONG aYSrc,
230 ULONG aWidth, ULONG aHeight, BOOL *aHandled);
231 STDMETHOD(GetVisibleRegion)(ULONG * aPcRect, BYTE * aPRect);
232 STDMETHOD(SetVisibleRegion)(ULONG aCRect, BYTE * aPRect);
233
234 // Helper functions
235 int width() { return mWdt; }
236 int height() { return mHgt; }
237
238 virtual FramebufferPixelFormat_T pixelFormat()
239 {
240 return FramebufferPixelFormat_PixelFormatDefault;
241 }
242
243 void lock() { mMutex->lock(); }
244 void unlock() { mMutex->unlock(); }
245
246 virtual uchar *address() = 0;
247 virtual int colorDepth() = 0;
248 virtual int lineSize() = 0;
249
250 /**
251 * Called on the GUI thread (from VBoxConsoleView) when some part of the
252 * VM display viewport needs to be repainted on the host screen.
253 */
254 virtual void paintEvent (QPaintEvent *pe) = 0;
255
256 /**
257 * Called on the GUI thread (from VBoxConsoleView) after it gets a
258 * VBoxResizeEvent posted from the RequestResize() method implementation.
259 */
260 virtual void resizeEvent (VBoxResizeEvent *re)
261 {
262 mWdt = re->width();
263 mHgt = re->height();
264 }
265
266 /**
267 * Called on the GUI thread (from VBoxConsoleView) when the VM console
268 * window is moved.
269 */
270 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
271
272protected:
273
274 VBoxConsoleView *mView;
275 QMutex *mMutex;
276 int mWdt;
277 int mHgt;
278
279#if defined (Q_OS_WIN32)
280private:
281 long refcnt;
282#endif
283};
284
285/////////////////////////////////////////////////////////////////////////////
286
287#if defined (VBOX_GUI_USE_QIMAGE)
288
289class VBoxQImageFrameBuffer : public VBoxFrameBuffer
290{
291public:
292
293 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
294
295 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
296 ULONG aW, ULONG aH,
297 BOOL *aFinished);
298
299 uchar *address() { return mImg.bits(); }
300 int colorDepth() { return mImg.depth(); }
301 int lineSize() { return mImg.bytesPerLine(); }
302
303 void paintEvent (QPaintEvent *pe);
304 void resizeEvent (VBoxResizeEvent *re);
305
306private:
307
308 QPixmap mPM;
309 QImage mImg;
310};
311
312#endif
313
314/////////////////////////////////////////////////////////////////////////////
315
316#if defined (VBOX_GUI_USE_SDL)
317
318class VBoxSDLFrameBuffer : public VBoxFrameBuffer
319{
320public:
321
322 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
323 virtual ~VBoxSDLFrameBuffer();
324
325 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
326 ULONG aW, ULONG aH,
327 BOOL *aFinished);
328
329 uchar *address()
330 {
331 if (mSurfVRAM)
332 {
333 return (uchar*) (mScreen ? (uintptr_t) mSurfVRAM->pixels : 0);
334 }
335 else
336 {
337 return (uchar*) (mScreen ? (uintptr_t) mScreen->pixels : 0);
338 }
339 }
340
341 int colorDepth()
342 {
343 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
344 return surf ? surf->format->BitsPerPixel : 0;
345 }
346
347 int lineSize()
348 {
349 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
350 return surf ? surf->pitch : 0;
351 }
352
353 FramebufferPixelFormat_T pixelFormat()
354 {
355 return mPixelFormat;
356 }
357
358 void paintEvent (QPaintEvent *pe);
359 void resizeEvent (VBoxResizeEvent *re);
360
361private:
362
363 SDL_Surface *mScreen;
364 SDL_Surface *mSurfVRAM;
365
366 uchar *mPtrVRAM;
367 ULONG mLineSize;
368 FramebufferPixelFormat_T mPixelFormat;
369};
370
371#endif
372
373/////////////////////////////////////////////////////////////////////////////
374
375#if defined (VBOX_GUI_USE_DDRAW)
376
377class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
378{
379public:
380
381 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
382 virtual ~VBoxDDRAWFrameBuffer();
383
384 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
385 ULONG aW, ULONG aH,
386 BOOL *aFinished);
387
388 uchar *address() { return (uchar *)mSurfaceDesc.lpSurface; }
389 int colorDepth() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
390 int lineSize() { return mSurfaceDesc.lPitch; }
391
392 FramebufferPixelFormat_T pixelFormat() { return mPixelFormat; };
393
394 void paintEvent (QPaintEvent *pe);
395 void resizeEvent (VBoxResizeEvent *re);
396 void moveEvent (QMoveEvent *me);
397
398private:
399 void releaseObjects();
400
401 void setupSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
402 void recreateSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
403 void deleteSurface ();
404 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
405 void getWindowPosition (void);
406
407 LPDIRECTDRAW7 mDDRAW;
408 LPDIRECTDRAWCLIPPER mClipper;
409 LPDIRECTDRAWSURFACE7 mSurface;
410 DDSURFACEDESC2 mSurfaceDesc;
411 LPDIRECTDRAWSURFACE7 mPrimarySurface;
412
413 FramebufferPixelFormat_T mPixelFormat;
414
415 BOOL mGuestVRAMSurface;
416
417 int mWndX;
418 int mWndY;
419
420 BOOL mSynchronousUpdates;
421};
422
423#endif
424
425#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