VirtualBox

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

Last change on this file since 21490 was 21490, checked in by vboxsync, 15 years ago

video hw accel: overlay support (not debugged yet), better colorkey & flip support impl in guest driver & QGLFramebuffer (not debugged yet)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.3 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#include <iprt/critsect.h>
28
29/* Qt includes */
30#include <QImage>
31#include <QPixmap>
32#include <QMutex>
33#include <QPaintEvent>
34#include <QMoveEvent>
35#if defined (VBOX_GUI_USE_QGL)
36#include <QGLWidget>
37#endif
38
39#if defined (VBOX_GUI_USE_SDL)
40#include <SDL.h>
41#include <signal.h>
42#endif
43
44#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
45// VBox/cdefs.h defines these:
46#undef LOWORD
47#undef HIWORD
48#undef LOBYTE
49#undef HIBYTE
50#include <ddraw.h>
51#endif
52
53class VBoxConsoleView;
54
55/////////////////////////////////////////////////////////////////////////////
56
57/**
58 * Frame buffer resize event.
59 */
60class VBoxResizeEvent : public QEvent
61{
62public:
63
64 VBoxResizeEvent (ulong aPixelFormat, uchar *aVRAM,
65 ulong aBitsPerPixel, ulong aBytesPerLine,
66 ulong aWidth, ulong aHeight) :
67 QEvent ((QEvent::Type) VBoxDefs::ResizeEventType),
68 mPixelFormat (aPixelFormat), mVRAM (aVRAM), mBitsPerPixel (aBitsPerPixel),
69 mBytesPerLine (aBytesPerLine), mWidth (aWidth), mHeight (aHeight) {}
70 ulong pixelFormat() { return mPixelFormat; }
71 uchar *VRAM() { return mVRAM; }
72 ulong bitsPerPixel() { return mBitsPerPixel; }
73 ulong bytesPerLine() { return mBytesPerLine; }
74 ulong width() { return mWidth; }
75 ulong height() { return mHeight; }
76
77private:
78
79 ulong mPixelFormat;
80 uchar *mVRAM;
81 ulong mBitsPerPixel;
82 ulong mBytesPerLine;
83 ulong mWidth;
84 ulong mHeight;
85};
86
87/**
88 * Frame buffer repaint event.
89 */
90class VBoxRepaintEvent : public QEvent
91{
92public:
93 VBoxRepaintEvent (int x, int y, int w, int h) :
94 QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
95 ex (x), ey (y), ew (w), eh (h)
96 {}
97 int x() { return ex; }
98 int y() { return ey; }
99 int width() { return ew; }
100 int height() { return eh; }
101private:
102 int ex, ey, ew, eh;
103};
104
105/**
106 * Frame buffer set region event.
107 */
108class VBoxSetRegionEvent : public QEvent
109{
110public:
111 VBoxSetRegionEvent (const QRegion &aReg)
112 : QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
113 , mReg (aReg) {}
114 QRegion region() { return mReg; }
115private:
116 QRegion mReg;
117};
118
119#ifdef VBOX_WITH_VIDEOHWACCEL
120class VBoxVHWACommandProcessEvent : public QEvent
121{
122public:
123 VBoxVHWACommandProcessEvent (struct _VBOXVHWACMD * pCmd)
124 : QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
125 , mpCmd (pCmd) {}
126 struct _VBOXVHWACMD * command() { return mpCmd; }
127private:
128 struct _VBOXVHWACMD * mpCmd;
129};
130
131#endif
132
133/////////////////////////////////////////////////////////////////////////////
134
135/**
136 * Common IFramebuffer implementation for all methods used by GUI to maintain
137 * the VM display video memory.
138 *
139 * Note that although this class can be called from multiple threads
140 * (in particular, the GUI thread and EMT) it doesn't protect access to every
141 * data field using its mutex lock. This is because all synchronization between
142 * the GUI and the EMT thread is supposed to be done using the
143 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
144 * (in particular, the \a aFinished parameter of these methods is responsible
145 * for the synchronization). These methods are always called on EMT and
146 * therefore always follow one another but never in parallel.
147 *
148 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
149 * IFramebuffer::Unlock() implementations) usually makes sense only if some
150 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
151 * *no* VM display update or resize event can occur while it is accessing
152 * IFramebuffer properties or the underlying display memory storage area.
153 *
154 * See IFramebuffer documentation for more info.
155 */
156
157class VBoxFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
158{
159public:
160
161 VBoxFrameBuffer (VBoxConsoleView *aView);
162 virtual ~VBoxFrameBuffer();
163
164 NS_DECL_ISUPPORTS
165
166#if defined (Q_OS_WIN32)
167
168 STDMETHOD_(ULONG, AddRef)()
169 {
170 return ::InterlockedIncrement (&refcnt);
171 }
172
173 STDMETHOD_(ULONG, Release)()
174 {
175 long cnt = ::InterlockedDecrement (&refcnt);
176 if (cnt == 0)
177 delete this;
178 return cnt;
179 }
180
181 STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
182 {
183 if (riid == IID_IUnknown) {
184 *ppObj = this;
185 AddRef();
186 return S_OK;
187 }
188 if (riid == IID_IFramebuffer) {
189 *ppObj = this;
190 AddRef();
191 return S_OK;
192 }
193 *ppObj = NULL;
194 return E_NOINTERFACE;
195 }
196
197#endif
198
199 // IFramebuffer COM methods
200 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
201 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
202 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
203 STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *aBitsPerPixel);
204 STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *aBytesPerLine);
205 STDMETHOD(COMGETTER(PixelFormat)) (ULONG *aPixelFormat);
206 STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *aUsesGuestVRAM);
207 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
208 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
209 STDMETHOD(COMGETTER(WinId)) (ULONG64 *winId);
210
211 STDMETHOD(Lock)();
212 STDMETHOD(Unlock)();
213
214 STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
215 BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
216 ULONG aWidth, ULONG aHeight,
217 BOOL *aFinished);
218
219 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
220 BOOL *aSupported);
221
222 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
223 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
224
225 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
226
227 ulong width() { return mWdt; }
228 ulong height() { return mHgt; }
229
230 virtual ulong pixelFormat()
231 {
232 return FramebufferPixelFormat_FOURCC_RGB;
233 }
234
235 virtual bool usesGuestVRAM()
236 {
237 return false;
238 }
239
240 void lock() { RTCritSectEnter(&mCritSect); }
241 void unlock() { RTCritSectLeave(&mCritSect); }
242
243 virtual uchar *address() = 0;
244 virtual ulong bitsPerPixel() = 0;
245 virtual ulong bytesPerLine() = 0;
246
247 /**
248 * Called on the GUI thread (from VBoxConsoleView) when some part of the
249 * VM display viewport needs to be repainted on the host screen.
250 */
251 virtual void paintEvent (QPaintEvent *pe) = 0;
252
253 /**
254 * Called on the GUI thread (from VBoxConsoleView) after it gets a
255 * VBoxResizeEvent posted from the RequestResize() method implementation.
256 */
257 virtual void resizeEvent (VBoxResizeEvent *re)
258 {
259 mWdt = re->width();
260 mHgt = re->height();
261 }
262
263 /**
264 * Called on the GUI thread (from VBoxConsoleView) when the VM console
265 * window is moved.
266 */
267 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
268
269#ifdef VBOX_WITH_VIDEOHWACCEL
270 /* this method is called from the GUI thread
271 * to perform the actual Video HW Acceleration command processing */
272 virtual void doProcessVHWACommand(struct _VBOXVHWACMD * pCommand);
273#endif
274
275protected:
276
277 VBoxConsoleView *mView;
278 RTCRITSECT mCritSect;
279 int mWdt;
280 int mHgt;
281 uint64_t mWinId;
282
283#if defined (Q_OS_WIN32)
284private:
285 long refcnt;
286#endif
287};
288
289/////////////////////////////////////////////////////////////////////////////
290
291#if defined (VBOX_GUI_USE_QIMAGE)
292
293class VBoxQImageFrameBuffer : public VBoxFrameBuffer
294{
295public:
296
297 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
298
299 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
300 ULONG aW, ULONG aH);
301
302 ulong pixelFormat() { return mPixelFormat; }
303 bool usesGuestVRAM() { return mUsesGuestVRAM; }
304
305 uchar *address() { return mImg.bits(); }
306 ulong bitsPerPixel() { return mImg.depth(); }
307 ulong bytesPerLine() { return mImg.bytesPerLine(); }
308
309 void paintEvent (QPaintEvent *pe);
310 void resizeEvent (VBoxResizeEvent *re);
311
312private:
313
314 QPixmap mPM;
315 QImage mImg;
316 ulong mPixelFormat;
317 bool mUsesGuestVRAM;
318};
319
320#endif
321
322/////////////////////////////////////////////////////////////////////////////
323
324#if defined (VBOX_GUI_USE_QGL)
325class VBoxVHWADirtyRect
326{
327public:
328 VBoxVHWADirtyRect() :
329 mIsClear(true)
330 {}
331
332 VBoxVHWADirtyRect(const QRect & aRect)
333 {
334 if(aRect.isEmpty())
335 {
336 mIsClear = false;
337 mRect = aRect;
338 }
339 else
340 {
341 mIsClear = true;
342 }
343 }
344
345 bool isClear() const { return mIsClear; }
346
347 void add(const QRect & aRect)
348 {
349 if(aRect.isEmpty())
350 return;
351
352 mRect = mIsClear ? aRect : mRect.united(aRect);
353 mIsClear = false;
354 }
355
356 void add(const VBoxVHWADirtyRect & aRect)
357 {
358 if(aRect.isClear())
359 return;
360 add(aRect.rect());
361 }
362
363 void set(const QRect & aRect)
364 {
365 if(aRect.isEmpty())
366 {
367 mIsClear = true;
368 }
369 else
370 {
371 mRect = aRect;
372 mIsClear = false;
373 }
374 }
375
376 void clear() { mIsClear = true; }
377
378 const QRect & rect() const {return mRect;}
379
380 bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
381
382 bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
383
384 QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
385
386 bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
387
388 void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
389
390private:
391 QRect mRect;
392 bool mIsClear;
393};
394
395class VBoxVHWAColorKey
396{
397public:
398 VBoxVHWAColorKey() :
399 mUpper(0),
400 mLower(0)
401 {}
402
403 VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
404 mUpper(aUpper),
405 mLower(aLower)
406 {}
407
408 uint32_t upper() const {return mUpper; }
409 uint32_t lower() const {return mLower; }
410
411 bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
412private:
413 uint32_t mUpper;
414 uint32_t mLower;
415};
416
417//class VBoxVHWAColorKeyRef
418//{
419//public:
420// VBoxVHWAColorKeyRef() : mValid(false){}
421//
422// bool isValid() {return mValid; }
423//
424// VBoxVHWAColorKey * ckey() { isVreturn mpCKey; }
425// const VBoxVHWAColorKey * constckey() const { return mpCKey; }
426//
427// void invalidate() { mValid = false; }
428// void set(VBoxVHWAColorKey * pKey) { mValid = false; }
429//
430//private:
431// VBoxVHWAColorKey * mpCKey;
432// bool mValid;
433//};
434
435class VBoxVHWAColorComponent
436{
437public:
438 VBoxVHWAColorComponent() :
439 mMask(0),
440 mRange(0),
441 mOffset(32),
442 mcBits(0)
443 {}
444
445 VBoxVHWAColorComponent(uint32_t aMask);
446
447 uint32_t mask() const { return mMask; }
448 uint32_t range() const { return mRange; }
449 uint32_t offset() const { return mOffset; }
450 uint32_t cBits() const { return mcBits; }
451 uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
452 float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
453private:
454 uint32_t mMask;
455 uint32_t mRange;
456 uint32_t mOffset;
457 uint32_t mcBits;
458};
459
460class VBoxVHWAColorFormat
461{
462public:
463
464// VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
465 VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
466
467 GLint internalFormat() const {return mInternalFormat; }
468 GLenum format() const {return mFormat; }
469 GLenum type() const {return mType; }
470 bool isValid() const {return mBitsPerPixel != 0; }
471 uint32_t dataFormat() const {return mDataFormat;}
472 uint32_t bitsPerPixel() const { return mBitsPerPixel; }
473 void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
474// uint32_t r(uint32_t pix);
475// uint32_t g(uint32_t pix);
476// uint32_t b(uint32_t pix);
477
478private:
479 void VBoxVHWAColorFormat::init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
480
481 GLint mInternalFormat;
482 GLenum mFormat;
483 GLenum mType;
484 uint32_t mDataFormat;
485
486 uint32_t mBitsPerPixel;
487
488 VBoxVHWAColorComponent mR;
489 VBoxVHWAColorComponent mG;
490 VBoxVHWAColorComponent mB;
491};
492
493/* data flow:
494 * I. NON-Yinverted surface:
495 * 1.direct memory update (paint, lock/unlock):
496 * mem->tex->fb
497 * 2.blt
498 * srcTex->invFB->tex->fb
499 * |->mem
500 *
501 * II. Yinverted surface:
502 * 1.direct memory update (paint, lock/unlock):
503 * mem->tex->fb
504 * 2.blt
505 * srcTex->fb->tex
506 * |->mem
507 *
508 * III. flip support:
509 * 1. Yinverted<->NON-YInverted conversion :
510 * mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
511 * fb-->| |->mem
512 * */
513class VBoxVHWASurfaceBase
514{
515public:
516 VBoxVHWASurfaceBase(class VBoxVHWAGlContextState *aState, bool aIsYInverted, const QSize * aSize, const QSize * aTargetSize,
517 VBoxVHWAColorFormat & aColorFormat,
518 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
519 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey);
520
521 virtual ~VBoxVHWASurfaceBase();
522
523 virtual void init(uchar *pvMem);
524
525 virtual void uninit();
526
527 static void globalInit();
528
529 int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
530 int overlay(VBoxVHWASurfaceBase * aOverlaySurface);
531
532 virtual int lock(const QRect * pRect, uint32_t flags);
533
534 virtual int unlock();
535
536 void updatedMem(const QRect * aRect);
537
538 void performDisplay();
539
540 void setRects(const QRect * aTargRect, const QRect * aSrcRect);
541 void setTargetRectPosition(const QPoint * aPoint);
542
543 static ulong calcBytesPerPixel(GLenum format, GLenum type);
544
545 static GLsizei makePowerOf2(GLsizei val);
546
547 bool addressAlocated() const { return mFreeAddress; }
548 uchar * address(){ return mAddress; }
549 uchar * pointAddress(int x, int y) { return mAddress + y*mBytesPerLine + x*mBytesPerPixel; }
550 ulong memSize(){ return mBytesPerLine * mRect.height(); }
551
552 ulong width() { return mRect.width(); }
553 ulong height() { return mRect.height(); }
554
555 GLenum format() {return mColorFormat.format(); }
556 GLint internalFormat() { return mColorFormat.internalFormat(); }
557 GLenum type() { return mColorFormat.type(); }
558 uint32_t dataFormat() {return mColorFormat.dataFormat(); }
559
560 ulong bytesPerPixel() { return mBytesPerPixel; }
561 ulong bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
562 ulong bytesPerLine() { return mBytesPerLine; }
563
564 const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
565 const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
566 const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
567 const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
568 const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
569 const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
570 void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
571 void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
572
573 void setDstBltCKey(const VBoxVHWAColorKey * ckey)
574 {
575 if(ckey)
576 {
577 mDstBltCKey = *ckey;
578 mpDstBltCKey = &mDstBltCKey;
579 }
580 else
581 {
582 mpDstBltCKey = NULL;
583 }
584 }
585
586 void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
587 {
588 if(ckey)
589 {
590 mSrcBltCKey = *ckey;
591 mpSrcBltCKey = &mSrcBltCKey;
592 }
593 else
594 {
595 mpSrcBltCKey = NULL;
596 }
597 }
598
599 void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
600 {
601 if(ckey)
602 {
603 mDefaultDstOverlayCKey = *ckey;
604 mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
605 }
606 else
607 {
608 mpDefaultDstOverlayCKey = NULL;
609 }
610 }
611
612 void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
613 {
614 if(ckey)
615 {
616 mDefaultSrcOverlayCKey = *ckey;
617 mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
618 }
619 else
620 {
621 mpDefaultSrcOverlayCKey = NULL;
622 }
623 }
624
625 void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
626 {
627 if(ckey)
628 {
629 mOverriddenDstOverlayCKey = *ckey;
630 mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
631 }
632 else
633 {
634 mpDstOverlayCKey = NULL;
635 }
636 }
637
638 void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
639 {
640 if(ckey)
641 {
642 mOverriddenSrcOverlayCKey = *ckey;
643 mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
644 }
645 else
646 {
647 mpSrcOverlayCKey = NULL;
648 }
649 }
650
651
652 const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
653
654 /* clients should treat the returned texture as read-only */
655 GLuint textureSynched(const QRect * aRect) { synchTex(aRect); return mTexture; }
656
657 void setAddress(uchar * addr);
658
659 const QRect& rect() {return mRect;}
660
661// /* surface currently being displayed in a flip chain */
662// virtual bool isPrimary() = 0;
663// /* surface representing the main framebuffer. */
664// virtual bool isMainFramebuffer() = 0;
665 virtual void makeCurrent() = 0;
666 virtual void makeYInvertedCurrent() = 0;
667
668 bool isYInverted() {return mIsYInverted; }
669
670 bool isHidden() {return mIsHidden; }
671 void setHidden(bool hidden) { mIsHidden = hidden; }
672
673 int invert();
674
675 bool isFrontBuffer() {return !mIsYInverted; }
676
677// bool isOverlay() { return mIsOverlay; }
678
679#ifdef VBOX_WITH_VIDEOHWACCEL
680 virtual class VBoxVHWAGlProgramMngr * getGlProgramMngr() = 0;
681 static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey);
682#endif
683private:
684 void initDisplay();
685 void deleteDisplay();
686 void initDisplay(bool bInverted);
687 void deleteDisplay(bool bInverted);
688 GLuint createDisplay(bool bInverted);
689 void synchTex(const QRect * aRect);
690 void synchTexMem(const QRect * aRect);
691 void synchTexFB(const QRect * aRect);
692 void synchMem(const QRect * aRect);
693 void synchFB(const QRect * aRect);
694 void synch(const QRect * aRect);
695
696 int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
697
698// void doTex2FB(const QRect * aRect);
699 void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
700
701 void doSetupMatrix(const QSize * pSize, bool bInverted);
702
703 QRect mRect; /* == Inv FB size */
704 QRect mTexRect; /* texture size */
705
706 QRect mSrcRect;
707 QRect mTargRect; /* == Vis FB size */
708 QRect mTargSize;
709
710 GLuint mYInvertedDisplay;
711 GLuint mVisibleDisplay;
712
713 bool mYInvertedDisplayInitialized;
714 bool mVisibleDisplayInitialized;
715
716 uchar * mAddress;
717 GLuint mTexture;
718
719 VBoxVHWAColorFormat mColorFormat;
720
721 VBoxVHWAColorKey *mpSrcBltCKey;
722 VBoxVHWAColorKey *mpDstBltCKey;
723 VBoxVHWAColorKey *mpSrcOverlayCKey;
724 VBoxVHWAColorKey *mpDstOverlayCKey;
725
726 VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
727 VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
728
729 VBoxVHWAColorKey mSrcBltCKey;
730 VBoxVHWAColorKey mDstBltCKey;
731 VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
732 VBoxVHWAColorKey mOverriddenDstOverlayCKey;
733 VBoxVHWAColorKey mDefaultDstOverlayCKey;
734 VBoxVHWAColorKey mDefaultSrcOverlayCKey;
735
736
737 GLenum mFormat;
738 GLint mInternalFormat;
739 GLenum mType;
740// ulong mDisplayWidth;
741// ulong mDisplayHeight;
742 ulong mBytesPerPixel;
743 ulong mBytesPerLine;
744
745 int mLockCount;
746 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
747 VBoxVHWADirtyRect mUpdateMem2TexRect;
748 /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock */
749 VBoxVHWADirtyRect mUpdateTex2FBRect;
750 /*in case of blit we blit from another surface's texture, so our current texture gets durty */
751 VBoxVHWADirtyRect mUpdateFB2TexRect;
752 /*in case of blit the memory buffer does not get updated until we need it, e.g. for paint or lock operations */
753 VBoxVHWADirtyRect mUpdateFB2MemRect;
754
755 /* flag for lazy invert post-processing */
756 bool mInverted;
757
758 bool mFreeAddress;
759
760 bool mIsYInverted;
761
762 bool mIsHidden;
763
764// bool mIsOverlay;
765
766protected:
767 virtual void init(uchar *pvMem, bool bInverted);
768
769 class VBoxVHWAGlContextState *mState;
770
771};
772
773class VBoxVHWADisplay
774{
775public:
776 VBoxVHWADisplay() :
777 mSurfVGA(NULL),
778 mSurfPrimary(NULL)
779 {}
780
781 VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
782 {
783 VBoxVHWASurfaceBase * old = mSurfVGA;
784 mSurfVGA = pVga;
785 mSurfPrimary = pVga;
786 mOverlays.clear();
787 return old;
788 }
789
790 VBoxVHWASurfaceBase * getVGA()
791 {
792 return mSurfVGA;
793 }
794
795 VBoxVHWASurfaceBase * getPrimary()
796 {
797 return mSurfPrimary;
798 }
799
800 void setPrimary(VBoxVHWASurfaceBase * pSurf)
801 {
802 mSurfPrimary = pSurf;
803 }
804
805 void addOverlay(VBoxVHWASurfaceBase * pSurf)
806 {
807 mOverlays.push_back(pSurf);
808 }
809
810 void removeOverlay(VBoxVHWASurfaceBase * pSurf)
811 {
812 mOverlays.remove(pSurf);
813 }
814
815 void flip(VBoxVHWASurfaceBase * pTarg, VBoxVHWASurfaceBase * pCurr)
816 {
817 pCurr->invert();
818 pTarg->invert();
819 if(pCurr == mSurfPrimary) /* flip of the primary surface */
820 {
821 mSurfPrimary = pTarg;
822 }
823 else /* flip of the overlay */
824 {
825 for (OverlayList::iterator it = mOverlays.begin();
826 it != mOverlays.end(); ++ it)
827 {
828 if((*it) == pCurr)
829 {
830 (*it) = pTarg;
831 }
832 }
833 }
834 }
835
836 void performDisplay()
837 {
838 mSurfPrimary->performDisplay();
839
840 for (OverlayList::const_iterator it = mOverlays.begin();
841 it != mOverlays.end(); ++ it)
842 {
843 mSurfPrimary->overlay(*it);
844 }
845 }
846
847private:
848 VBoxVHWASurfaceBase *mSurfVGA;
849 VBoxVHWASurfaceBase *mSurfPrimary;
850
851 typedef std::list <VBoxVHWASurfaceBase*> OverlayList;
852
853 OverlayList mOverlays;
854};
855
856
857
858class VBoxVHWAGlContextState
859{
860public:
861 VBoxVHWAGlContextState() : mContext(NULL), mInverted(false) {}
862
863 void assertCurrent(class VBoxVHWASurfaceBase *aContext, bool bInverted)
864 {
865 mContext = aContext;
866 if(aContext && aContext->isYInverted())
867 {
868 mInverted = true;
869 }
870 else
871 {
872 mInverted = bInverted;
873 }
874 }
875
876 void makeYInvertedCurrent(class VBoxVHWASurfaceBase *aContext)
877 {
878 if(mContext != aContext)
879 {
880// aContext->makeCurrent();
881 aContext->makeYInvertedCurrent();
882 assertCurrent(aContext, true);
883 }
884 else
885 {
886 if(!aContext->isYInverted() && !mInverted)
887 {
888// aContext->makeCurrent();
889 aContext->makeYInvertedCurrent();
890 mInverted = true;
891 }
892 }
893 }
894
895 void makeCurrent(class VBoxVHWASurfaceBase *aContext)
896 {
897 if(mContext != aContext)
898 {
899 aContext->makeCurrent();
900 assertCurrent(aContext, false);
901 }
902 else
903 {
904 if(!aContext->isYInverted() && mInverted)
905 {
906 aContext->makeCurrent();
907 mInverted = false;
908 }
909 }
910 }
911
912 void makeCurrent(class VBoxVHWASurfaceBase *aContext, bool mInverted)
913 {
914 if(mInverted)
915 {
916 makeYInvertedCurrent(aContext);
917 }
918 else
919 {
920 makeCurrent(aContext);
921 }
922 }
923
924 class VBoxVHWASurfaceBase * getCurrent() {return mContext; }
925 bool isCurrentYInverted() {return mInverted; }
926
927private:
928
929 class VBoxVHWASurfaceBase *mContext;
930 bool mInverted;
931};
932
933class VBoxVHWASurfaceQGL : public VBoxVHWASurfaceBase
934{
935public:
936 VBoxVHWASurfaceQGL(class VBoxVHWAGlContextState *aState, const QSize * aSize, const QSize * aTargetSize,
937 VBoxVHWAColorFormat & aColorFormat,
938 VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
939 VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
940 class VBoxGLWidget *pWidget,
941 bool bInvisibleBuffer) :
942 VBoxVHWASurfaceBase(aState, bInvisibleBuffer, aSize, aTargetSize,
943 aColorFormat,
944 pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey),
945 mWidget(pWidget),
946 mBuffer(NULL)
947 {}
948
949 ~VBoxVHWASurfaceQGL();
950
951 void makeCurrent();
952 void makeYInvertedCurrent();
953
954 void init(uchar *pvMem);
955
956 void uninit();
957
958// int unlock()
959// {
960// int rc = VBoxVHWASurfaceBase::unlock();
961// if(!mBuffer)
962// performDisplay();
963// return rc;
964// }
965#ifdef VBOX_WITH_VIDEOHWACCEL
966 class VBoxVHWAGlProgramMngr * getGlProgramMngr();
967#endif
968private:
969 class VBoxGLWidget *mWidget;
970 class QGLPixelBuffer *mBuffer;
971protected:
972 virtual void init(uchar *pvMem, bool bInverted);
973};
974
975class VBoxGLWidget : public QGLWidget
976{
977public:
978 VBoxGLWidget (QWidget *aParent);
979 ~VBoxGLWidget();
980
981 ulong vboxPixelFormat() { return mPixelFormat; }
982 bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
983
984 uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
985 uchar *vboxVRAMAddressFromOffset(uint64_t offset);
986 ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
987 ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : NULL; }
988
989typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
990//typedef FNVBOXQGLOP *PFNVBOXQGLOP;
991
992 void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe);}
993 void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re);}
994#ifdef DEBUG_misha
995 void vboxTestSurfaces () {vboxPerformGLOp(&VBoxGLWidget::vboxDoTestSurfaces, NULL);}
996#endif
997#ifdef VBOX_WITH_VIDEOHWACCEL
998 void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
999 class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr();
1000#endif
1001
1002 VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
1003protected:
1004// void resizeGL (int height, int width);
1005
1006 void paintGL()
1007 {
1008 Assert(mState.getCurrent() == NULL);
1009 /* we are called with QGLWidget context */
1010 mState.assertCurrent(mDisplay.getVGA(), false);
1011 (this->*mpfnOp)(mOpContext);
1012 /* restore the context */
1013 mState.makeCurrent(mDisplay.getVGA());
1014 /* clear*/
1015 mState.assertCurrent(NULL, false);
1016 }
1017
1018 void initializeGL();
1019
1020private:
1021// void vboxDoInitDisplay();
1022// void vboxDoDeleteDisplay();
1023// void vboxDoPerformDisplay() { Assert(mDisplayInitialized); glCallList(mDisplay); }
1024 void vboxDoResize(void *re);
1025 void vboxDoPaint(void *rec);
1026#ifdef DEBUG_misha
1027 void vboxDoTestSurfaces(void *context);
1028#endif
1029#ifdef VBOX_WITH_VIDEOHWACCEL
1030 void vboxDoVHWACmd(void *cmd);
1031 void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
1032 {
1033 if (pSurface->addressAlocated())
1034 {
1035 uchar * addr = vboxVRAMAddressFromOffset(offset);
1036 if(addr)
1037 {
1038 pSurface->setAddress(addr);
1039 }
1040 }
1041 }
1042 int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
1043 int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
1044 int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
1045 int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
1046 int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
1047 int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
1048 int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
1049 int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
1050 int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
1051 int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
1052 int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
1053 int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
1054#endif
1055
1056// VBoxVHWASurfaceQGL * pDisplay;
1057 VBoxVHWADisplay mDisplay;
1058
1059
1060 /* we need to do all opengl stuff in the paintGL context,
1061 * submit the operation to be performed */
1062 void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext) {mpfnOp = pfn; mOpContext = pContext; updateGL();}
1063
1064 PFNVBOXQGLOP mpfnOp;
1065 void *mOpContext;
1066
1067// ulong mBitsPerPixel;
1068 ulong mPixelFormat;
1069 bool mUsesGuestVRAM;
1070
1071 VBoxVHWAGlContextState mState;
1072
1073#ifdef VBOX_WITH_VIDEOHWACCEL
1074 class VBoxVHWAGlProgramMngr *mpMngr;
1075#endif
1076};
1077
1078
1079class VBoxQGLFrameBuffer : public VBoxFrameBuffer
1080{
1081public:
1082
1083 VBoxQGLFrameBuffer (VBoxConsoleView *aView);
1084
1085 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1086 ULONG aW, ULONG aH);
1087
1088#ifdef VBOX_WITH_VIDEOHWACCEL
1089 STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
1090#endif
1091
1092 ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
1093 bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
1094
1095 uchar *address() { return vboxWidget()->vboxAddress(); }
1096 ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
1097 ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
1098
1099 void paintEvent (QPaintEvent *pe);
1100 void resizeEvent (VBoxResizeEvent *re);
1101#ifdef VBOX_WITH_VIDEOHWACCEL
1102 void doProcessVHWACommand(struct _VBOXVHWACMD * pCommand);
1103#endif
1104
1105private:
1106// void vboxMakeCurrent();
1107 VBoxGLWidget * vboxWidget();
1108};
1109
1110
1111#endif
1112
1113/////////////////////////////////////////////////////////////////////////////
1114
1115#if defined (VBOX_GUI_USE_SDL)
1116
1117class VBoxSDLFrameBuffer : public VBoxFrameBuffer
1118{
1119public:
1120
1121 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
1122 virtual ~VBoxSDLFrameBuffer();
1123
1124 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1125 ULONG aW, ULONG aH);
1126
1127 uchar *address()
1128 {
1129 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1130 return surf ? (uchar *) (uintptr_t) surf->pixels : 0;
1131 }
1132
1133 ulong bitsPerPixel()
1134 {
1135 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1136 return surf ? surf->format->BitsPerPixel : 0;
1137 }
1138
1139 ulong bytesPerLine()
1140 {
1141 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM : mScreen;
1142 return surf ? surf->pitch : 0;
1143 }
1144
1145 ulong pixelFormat()
1146 {
1147 return mPixelFormat;
1148 }
1149
1150 bool usesGuestVRAM()
1151 {
1152 return mSurfVRAM != NULL;
1153 }
1154
1155 void paintEvent (QPaintEvent *pe);
1156 void resizeEvent (VBoxResizeEvent *re);
1157
1158private:
1159
1160 SDL_Surface *mScreen;
1161 SDL_Surface *mSurfVRAM;
1162
1163 ulong mPixelFormat;
1164};
1165
1166#endif
1167
1168/////////////////////////////////////////////////////////////////////////////
1169
1170#if defined (VBOX_GUI_USE_DDRAW)
1171
1172class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
1173{
1174public:
1175
1176 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
1177 virtual ~VBoxDDRAWFrameBuffer();
1178
1179 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
1180 ULONG aW, ULONG aH);
1181
1182 uchar *address() { return (uchar *) mSurfaceDesc.lpSurface; }
1183 ulong bitsPerPixel() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
1184 ulong bytesPerLine() { return (ulong) mSurfaceDesc.lPitch; }
1185
1186 ulong pixelFormat() { return mPixelFormat; };
1187
1188 bool usesGuestVRAM() { return mUsesGuestVRAM; }
1189
1190 void paintEvent (QPaintEvent *pe);
1191 void resizeEvent (VBoxResizeEvent *re);
1192 void moveEvent (QMoveEvent *me);
1193
1194private:
1195
1196 void releaseObjects();
1197
1198 bool createSurface (ULONG aPixelFormat, uchar *pvVRAM,
1199 ULONG aBitsPerPixel, ULONG aBytesPerLine,
1200 ULONG aWidth, ULONG aHeight);
1201 void deleteSurface();
1202 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
1203 void getWindowPosition (void);
1204
1205 LPDIRECTDRAW7 mDDRAW;
1206 LPDIRECTDRAWCLIPPER mClipper;
1207 LPDIRECTDRAWSURFACE7 mSurface;
1208 DDSURFACEDESC2 mSurfaceDesc;
1209 LPDIRECTDRAWSURFACE7 mPrimarySurface;
1210
1211 ulong mPixelFormat;
1212
1213 bool mUsesGuestVRAM;
1214
1215 int mWndX;
1216 int mWndY;
1217
1218 bool mSynchronousUpdates;
1219};
1220
1221#endif
1222
1223/////////////////////////////////////////////////////////////////////////////
1224
1225#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
1226
1227#include <Carbon/Carbon.h>
1228
1229class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
1230{
1231public:
1232
1233 VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
1234 virtual ~VBoxQuartz2DFrameBuffer ();
1235
1236 STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
1237 ULONG aW, ULONG aH);
1238 STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
1239
1240 uchar *address() { return mDataAddress; }
1241 ulong bitsPerPixel() { return CGImageGetBitsPerPixel (mImage); }
1242 ulong bytesPerLine() { return CGImageGetBytesPerRow (mImage); }
1243 ulong pixelFormat() { return mPixelFormat; };
1244 bool usesGuestVRAM() { return mBitmapData == NULL; }
1245
1246 const CGImageRef imageRef() const { return mImage; }
1247
1248 void paintEvent (QPaintEvent *pe);
1249 void resizeEvent (VBoxResizeEvent *re);
1250
1251private:
1252
1253 void clean();
1254
1255 uchar *mDataAddress;
1256 void *mBitmapData;
1257 ulong mPixelFormat;
1258 CGImageRef mImage;
1259 typedef struct
1260 {
1261 /** The size of this structure expressed in rcts entries. */
1262 ULONG allocated;
1263 /** The number of entries in the rcts array. */
1264 ULONG used;
1265 /** Variable sized array of the rectangle that makes up the region. */
1266 CGRect rcts[1];
1267 } RegionRects;
1268 /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
1269 *
1270 * The protocol for updating and using this has to take into account that
1271 * the producer (SetVisibleRegion) and consumer (paintEvent) are running
1272 * on different threads. Therefore the producer will create a new RegionRects
1273 * structure before atomically replace the existing one. While the consumer
1274 * will read the value by atomically replace it by NULL, and then when its
1275 * done try restore it by cmpxchg. If the producer has already put a new
1276 * region there, it will be discarded (see mRegionUnused).
1277 */
1278 RegionRects volatile *mRegion;
1279 /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
1280 * This is operated with atomic cmpxchg and atomic xchg. */
1281 RegionRects volatile *mRegionUnused;
1282};
1283
1284#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
1285
1286#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