VirtualBox

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

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

64-bit (just making it build).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.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 InnoTek Systemberatung 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, void *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 void *vram() { return vr; }
79 unsigned lineSize() { return lsz; }
80 int width() { return wdt; }
81 int height() { return hgt; }
82private:
83 FramebufferPixelFormat_T fmt;
84 void *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)) (ULONG *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) (FramebufferPixelFormat_T aPixelFormat,
219 ULONG 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
232 // Helper functions
233 int width() { return mWdt; }
234 int height() { return mHgt; }
235
236 virtual FramebufferPixelFormat_T pixelFormat()
237 {
238 return FramebufferPixelFormat_PixelFormatDefault;
239 }
240
241 void lock() { mMutex->lock(); }
242 void unlock() { mMutex->unlock(); }
243
244 virtual uchar *address() = 0;
245 virtual int colorDepth() = 0;
246 virtual int lineSize() = 0;
247
248 /**
249 * Called on the GUI thread (from VBoxConsoleView) when some part of the
250 * VM display viewport needs to be repainted on the host screen.
251 */
252 virtual void paintEvent (QPaintEvent *pe) = 0;
253
254 /**
255 * Called on the GUI thread (from VBoxConsoleView) after it gets a
256 * VBoxResizeEvent posted from the RequestResize() method implementation.
257 */
258 virtual void resizeEvent (VBoxResizeEvent *re)
259 {
260 mWdt = re->width();
261 mHgt = re->height();
262 }
263
264 /**
265 * Called on the GUI thread (from VBoxConsoleView) when the VM console
266 * window is moved.
267 */
268 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
269
270protected:
271
272 VBoxConsoleView *mView;
273 QMutex *mMutex;
274 int mWdt;
275 int mHgt;
276
277#if defined (Q_OS_WIN32)
278private:
279 long refcnt;
280#endif
281};
282
283/////////////////////////////////////////////////////////////////////////////
284
285#if defined (VBOX_GUI_USE_QIMAGE)
286
287class VBoxQImageFrameBuffer : public VBoxFrameBuffer
288{
289public:
290
291 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
292
293 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
294 ULONG aW, ULONG aH,
295 BOOL *aFinished);
296
297 uchar *address() { return mImg.bits(); }
298 int colorDepth() { return mImg.depth(); }
299 int lineSize() { return mImg.bytesPerLine(); }
300
301 void paintEvent (QPaintEvent *pe);
302 void resizeEvent (VBoxResizeEvent *re);
303
304private:
305
306 QPixmap mPM;
307 QImage mImg;
308};
309
310#endif
311
312/////////////////////////////////////////////////////////////////////////////
313
314#if defined (VBOX_GUI_USE_SDL)
315
316class VBoxSDLFrameBuffer : public VBoxFrameBuffer
317{
318public:
319
320 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
321 virtual ~VBoxSDLFrameBuffer();
322
323 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
324 ULONG aW, ULONG aH,
325 BOOL *aFinished);
326
327 uchar *address()
328 {
329 if (mSurfVRAM)
330 {
331 return (uchar*) (mScreen ? (uintptr_t) mSurfVRAM->pixels : 0);
332 }
333 else
334 {
335 return (uchar*) (mScreen ? (uintptr_t) mScreen->pixels : 0);
336 }
337 }
338
339 int colorDepth()
340 {
341 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
342 return surf ? surf->format->BitsPerPixel : 0;
343 }
344
345 int lineSize()
346 {
347 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
348 return surf ? surf->pitch : 0;
349 }
350
351 FramebufferPixelFormat_T pixelFormat()
352 {
353 return mPixelFormat;
354 }
355
356 void paintEvent (QPaintEvent *pe);
357 void resizeEvent (VBoxResizeEvent *re);
358
359private:
360
361 SDL_Surface *mScreen;
362 SDL_Surface *mSurfVRAM;
363
364 void *mPtrVRAM;
365 ULONG mLineSize;
366 FramebufferPixelFormat_T mPixelFormat;
367};
368
369#endif
370
371/////////////////////////////////////////////////////////////////////////////
372
373#if defined (VBOX_GUI_USE_DDRAW)
374
375class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
376{
377public:
378
379 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
380 virtual ~VBoxDDRAWFrameBuffer();
381
382 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
383 ULONG aW, ULONG aH,
384 BOOL *aFinished);
385
386 uchar *address() { return (uchar *)mSurfaceDesc.lpSurface; }
387 int colorDepth() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
388 int lineSize() { return mSurfaceDesc.lPitch; }
389
390 FramebufferPixelFormat_T pixelFormat() { return mPixelFormat; };
391
392 void paintEvent (QPaintEvent *pe);
393 void resizeEvent (VBoxResizeEvent *re);
394 void moveEvent (QMoveEvent *me);
395
396private:
397 void releaseObjects();
398
399 void setupSurface (FramebufferPixelFormat_T pixelFormat, void *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
400 void recreateSurface (FramebufferPixelFormat_T pixelFormat, void *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
401 void deleteSurface ();
402 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
403 void getWindowPosition (void);
404
405 LPDIRECTDRAW7 mDDRAW;
406 LPDIRECTDRAWCLIPPER mClipper;
407 LPDIRECTDRAWSURFACE7 mSurface;
408 DDSURFACEDESC2 mSurfaceDesc;
409 LPDIRECTDRAWSURFACE7 mPrimarySurface;
410
411 FramebufferPixelFormat_T mPixelFormat;
412
413 BOOL mGuestVRAMSurface;
414
415 int mWndX;
416 int mWndY;
417
418 BOOL mSynchronousUpdates;
419};
420
421#endif
422
423#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