~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.h

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

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