VirtualBox

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

最後變更 在這個檔案從3670是 3614,由 vboxsync 提交於 18 年 前

Main: Renamed PixelFormatDefault => PixelFormatOpaque.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 12.5 KB
 
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.alldomusa.eu.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/* Framebuffer render mode */
147typedef enum
148{
149 RenderModeNormal = 0,
150 RenderModeSeamless = 1,
151 RenderModeHostWindow = 2
152} FramebufferRenderMode;
153
154/**
155 * Common IFramebuffer implementation for all methods used by GUI to maintain
156 * the VM display video memory.
157 *
158 * Note that although this class can be called from multiple threads
159 * (in particular, the GUI thread and EMT) it doesn't protect access to every
160 * data field using its mutex lock. This is because all synchronization between
161 * the GUI and the EMT thread is supposed to be done using the
162 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
163 * (in particular, the \a aFinished parameter of these methods is responsible
164 * for the synchronization). These methods are always called on EMT and
165 * therefore always follow one another but never in parallel.
166 *
167 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
168 * IFramebuffer::Unlock() implementations) usually makes sense only if some
169 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
170 * *no* VM display update or resize event can occur while it is accessing
171 * IFramebuffer properties or the underlying display memory storage area.
172 *
173 * See IFramebuffer documentation for more info.
174 */
175
176class VBoxFrameBuffer : public IFramebuffer
177{
178public:
179
180 VBoxFrameBuffer (VBoxConsoleView *aView);
181 virtual ~VBoxFrameBuffer();
182
183 NS_DECL_ISUPPORTS
184
185#if defined (Q_OS_WIN32)
186 STDMETHOD_(ULONG, AddRef)() {
187 return ::InterlockedIncrement (&refcnt);
188 }
189 STDMETHOD_(ULONG, Release)()
190 {
191 long cnt = ::InterlockedDecrement (&refcnt);
192 if (cnt == 0)
193 delete this;
194 return cnt;
195 }
196 STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
197 {
198 if (riid == IID_IUnknown) {
199 *ppObj = this;
200 AddRef();
201 return S_OK;
202 }
203 if (riid == IID_IFramebuffer) {
204 *ppObj = this;
205 AddRef();
206 return S_OK;
207 }
208 *ppObj = NULL;
209 return E_NOINTERFACE;
210 }
211#endif
212
213 // IFramebuffer COM methods
214 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
215 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
216 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
217 STDMETHOD(COMGETTER(ColorDepth)) (ULONG *aColorDepth);
218 STDMETHOD(COMGETTER(LineSize)) (ULONG *aLineSize);
219 STDMETHOD(COMGETTER(PixelFormat)) (FramebufferPixelFormat_T *aPixelFormat);
220 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
221 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
222 STDMETHOD(COMGETTER(RenderMode)) (FramebufferRenderMode *renderMode);
223 STDMETHOD(COMSETTER(RenderMode)) (FramebufferRenderMode renderMode);
224
225 STDMETHOD(Lock)();
226 STDMETHOD(Unlock)();
227
228 STDMETHOD(RequestResize) (ULONG aScreenId, FramebufferPixelFormat_T aPixelFormat,
229 BYTE *aVRAM, ULONG aLineSize,
230 ULONG aWidth, ULONG aHeight,
231 BOOL *aFinished);
232
233 STDMETHOD(OperationSupported)(FramebufferAccelerationOperation_T aOperation,
234 BOOL *aSupported);
235 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
236 BOOL *aSupported);
237 STDMETHOD(SolidFill) (ULONG aX, ULONG aY, ULONG aWidth, ULONG aHeight,
238 ULONG aColor, BOOL *aHandled);
239 STDMETHOD(CopyScreenBits) (ULONG aXDst, ULONG aYDst, ULONG aXSrc, ULONG aYSrc,
240 ULONG aWidth, ULONG aHeight, BOOL *aHandled);
241
242 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
243 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
244
245 // Helper functions
246 int width() { return mWdt; }
247 int height() { return mHgt; }
248
249 virtual FramebufferPixelFormat_T pixelFormat()
250 {
251 return FramebufferPixelFormat_PixelFormatOpaque;
252 }
253
254 void lock() { mMutex->lock(); }
255 void unlock() { mMutex->unlock(); }
256
257 virtual uchar *address() = 0;
258 virtual int colorDepth() = 0;
259 virtual int lineSize() = 0;
260
261 /**
262 * Called on the GUI thread (from VBoxConsoleView) when some part of the
263 * VM display viewport needs to be repainted on the host screen.
264 */
265 virtual void paintEvent (QPaintEvent *pe) = 0;
266
267 /**
268 * Called on the GUI thread (from VBoxConsoleView) after it gets a
269 * VBoxResizeEvent posted from the RequestResize() method implementation.
270 */
271 virtual void resizeEvent (VBoxResizeEvent *re)
272 {
273 mWdt = re->width();
274 mHgt = re->height();
275 }
276
277 /**
278 * Called on the GUI thread (from VBoxConsoleView) when the VM console
279 * window is moved.
280 */
281 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
282
283protected:
284
285 VBoxConsoleView *mView;
286 QMutex *mMutex;
287 int mWdt;
288 int mHgt;
289
290 /* Framebuffer render mode */
291 FramebufferRenderMode mRenderMode;
292
293#if defined (Q_OS_WIN32)
294private:
295 long refcnt;
296#endif
297};
298
299/////////////////////////////////////////////////////////////////////////////
300
301#if defined (VBOX_GUI_USE_QIMAGE)
302
303class VBoxQImageFrameBuffer : public VBoxFrameBuffer
304{
305public:
306
307 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
308
309 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
310 ULONG aW, ULONG aH,
311 BOOL *aFinished);
312
313 uchar *address() { return mImg.bits(); }
314 int colorDepth() { return mImg.depth(); }
315 int lineSize() { return mImg.bytesPerLine(); }
316
317 void paintEvent (QPaintEvent *pe);
318 void resizeEvent (VBoxResizeEvent *re);
319
320private:
321
322 QPixmap mPM;
323 QImage mImg;
324};
325
326#endif
327
328/////////////////////////////////////////////////////////////////////////////
329
330#if defined (VBOX_GUI_USE_SDL)
331
332class VBoxSDLFrameBuffer : public VBoxFrameBuffer
333{
334public:
335
336 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
337 virtual ~VBoxSDLFrameBuffer();
338
339 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
340 ULONG aW, ULONG aH,
341 BOOL *aFinished);
342
343 uchar *address()
344 {
345 if (mSurfVRAM)
346 {
347 return (uchar*) (mScreen ? (uintptr_t) mSurfVRAM->pixels : 0);
348 }
349 else
350 {
351 return (uchar*) (mScreen ? (uintptr_t) mScreen->pixels : 0);
352 }
353 }
354
355 int colorDepth()
356 {
357 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
358 return surf ? surf->format->BitsPerPixel : 0;
359 }
360
361 int lineSize()
362 {
363 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
364 return surf ? surf->pitch : 0;
365 }
366
367 FramebufferPixelFormat_T pixelFormat()
368 {
369 return mPixelFormat;
370 }
371
372 void paintEvent (QPaintEvent *pe);
373 void resizeEvent (VBoxResizeEvent *re);
374
375private:
376
377 SDL_Surface *mScreen;
378 SDL_Surface *mSurfVRAM;
379
380 uchar *mPtrVRAM;
381 ULONG mLineSize;
382 FramebufferPixelFormat_T mPixelFormat;
383};
384
385#endif
386
387/////////////////////////////////////////////////////////////////////////////
388
389#if defined (VBOX_GUI_USE_DDRAW)
390
391class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
392{
393public:
394
395 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
396 virtual ~VBoxDDRAWFrameBuffer();
397
398 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
399 ULONG aW, ULONG aH,
400 BOOL *aFinished);
401
402 uchar *address() { return (uchar *)mSurfaceDesc.lpSurface; }
403 int colorDepth() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
404 int lineSize() { return mSurfaceDesc.lPitch; }
405
406 FramebufferPixelFormat_T pixelFormat() { return mPixelFormat; };
407
408 void paintEvent (QPaintEvent *pe);
409 void resizeEvent (VBoxResizeEvent *re);
410 void moveEvent (QMoveEvent *me);
411
412private:
413 void releaseObjects();
414
415 void setupSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
416 void recreateSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
417 void deleteSurface ();
418 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
419 void getWindowPosition (void);
420
421 LPDIRECTDRAW7 mDDRAW;
422 LPDIRECTDRAWCLIPPER mClipper;
423 LPDIRECTDRAWSURFACE7 mSurface;
424 DDSURFACEDESC2 mSurfaceDesc;
425 LPDIRECTDRAWSURFACE7 mPrimarySurface;
426
427 FramebufferPixelFormat_T mPixelFormat;
428
429 BOOL mGuestVRAMSurface;
430
431 int mWndX;
432 int mWndY;
433
434 BOOL mSynchronousUpdates;
435};
436
437#endif
438
439#endif // __VBoxFrameBuffer_h__
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette