~ubuntu-branches/ubuntu/trusty/virtualbox-ose/trusty

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.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 Overly classes 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
#ifndef __VBoxFBOverlay_h__
 
23
#define __VBoxFBOverlay_h__
 
24
#if defined (VBOX_GUI_USE_QGL) || defined(VBOX_WITH_VIDEOHWACCEL)
 
25
 
 
26
//#define VBOXQGL_PROF_BASE 1
 
27
//#define VBOXQGL_DBG_SURF 1
 
28
 
 
29
#include "COMDefs.h"
 
30
#include <QGLWidget>
 
31
#include <iprt/assert.h>
 
32
#include <iprt/critsect.h>
 
33
 
 
34
#include <VBox/VBoxGL2D.h>
 
35
#include "VBoxFBOverlayCommon.h"
 
36
 
 
37
#define VBOXVHWA_ALLOW_PRIMARY_AND_OVERLAY_ONLY 1
 
38
 
 
39
#ifdef DEBUG_misha
 
40
# define VBOXVHWA_PROFILE_FPS
 
41
#endif
 
42
 
 
43
#ifdef DEBUG
 
44
class VBoxVHWADbgTimer
 
45
{
 
46
public:
 
47
    VBoxVHWADbgTimer(uint32_t cPeriods);
 
48
    ~VBoxVHWADbgTimer();
 
49
    void frame();
 
50
    uint64_t everagePeriod() {return mPeriodSum / mcPeriods; }
 
51
    double fps() {return ((double)1000000000.0) / everagePeriod(); }
 
52
    uint64_t frames() {return mcFrames; }
 
53
private:
 
54
    uint64_t mPeriodSum;
 
55
    uint64_t *mpaPeriods;
 
56
    uint64_t mPrevTime;
 
57
    uint64_t mcFrames;
 
58
    uint32_t mcPeriods;
 
59
    uint32_t miPeriod;
 
60
};
 
61
 
 
62
#endif
 
63
 
 
64
class VBoxVHWADirtyRect
 
65
{
 
66
public:
 
67
    VBoxVHWADirtyRect() :
 
68
        mIsClear(true)
 
69
    {}
 
70
 
 
71
    VBoxVHWADirtyRect(const QRect & aRect)
 
72
    {
 
73
        if(aRect.isEmpty())
 
74
        {
 
75
            mIsClear = false;
 
76
            mRect = aRect;
 
77
        }
 
78
        else
 
79
        {
 
80
            mIsClear = true;
 
81
        }
 
82
    }
 
83
 
 
84
    bool isClear() const { return mIsClear; }
 
85
 
 
86
    void add(const QRect & aRect)
 
87
    {
 
88
        if(aRect.isEmpty())
 
89
            return;
 
90
 
 
91
        mRect = mIsClear ? aRect : mRect.united(aRect);
 
92
        mIsClear = false;
 
93
    }
 
94
 
 
95
    void add(const VBoxVHWADirtyRect & aRect)
 
96
    {
 
97
        if(aRect.isClear())
 
98
            return;
 
99
        add(aRect.rect());
 
100
    }
 
101
 
 
102
    void set(const QRect & aRect)
 
103
    {
 
104
        if(aRect.isEmpty())
 
105
        {
 
106
            mIsClear = true;
 
107
        }
 
108
        else
 
109
        {
 
110
            mRect = aRect;
 
111
            mIsClear = false;
 
112
        }
 
113
    }
 
114
 
 
115
    void clear() { mIsClear = true; }
 
116
 
 
117
    const QRect & rect() const {return mRect;}
 
118
 
 
119
    const QRect & toRect()
 
120
    {
 
121
        if(isClear())
 
122
        {
 
123
            mRect.setCoords(0, 0, -1, -1);
 
124
        }
 
125
        return mRect;
 
126
    }
 
127
 
 
128
    bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
 
129
 
 
130
    bool intersects(const VBoxVHWADirtyRect & aRect) const {return mIsClear ? false : aRect.intersects(mRect);}
 
131
 
 
132
    QRect united(const QRect & aRect) const {return mIsClear ? aRect : aRect.united(mRect);}
 
133
 
 
134
    bool contains(const QRect & aRect) const {return mIsClear ? false : aRect.contains(mRect);}
 
135
 
 
136
    void subst(const VBoxVHWADirtyRect & aRect) { if(!mIsClear && aRect.contains(mRect)) clear(); }
 
137
 
 
138
private:
 
139
    QRect mRect;
 
140
    bool mIsClear;
 
141
};
 
142
 
 
143
class VBoxVHWAColorKey
 
144
{
 
145
public:
 
146
    VBoxVHWAColorKey() :
 
147
        mUpper(0),
 
148
        mLower(0)
 
149
    {}
 
150
 
 
151
    VBoxVHWAColorKey(uint32_t aUpper, uint32_t aLower) :
 
152
        mUpper(aUpper),
 
153
        mLower(aLower)
 
154
    {}
 
155
 
 
156
    uint32_t upper() const {return mUpper; }
 
157
    uint32_t lower() const {return mLower; }
 
158
 
 
159
    bool operator==(const VBoxVHWAColorKey & other) const { return mUpper == other.mUpper && mLower == other.mLower; }
 
160
private:
 
161
    uint32_t mUpper;
 
162
    uint32_t mLower;
 
163
};
 
164
 
 
165
class VBoxVHWAColorComponent
 
166
{
 
167
public:
 
168
    VBoxVHWAColorComponent() :
 
169
        mMask(0),
 
170
        mRange(0),
 
171
        mOffset(32),
 
172
        mcBits(0)
 
173
    {}
 
174
 
 
175
    VBoxVHWAColorComponent(uint32_t aMask);
 
176
 
 
177
    uint32_t mask() const { return mMask; }
 
178
    uint32_t range() const { return mRange; }
 
179
    uint32_t offset() const { return mOffset; }
 
180
    uint32_t cBits() const { return mcBits; }
 
181
    uint32_t colorVal(uint32_t col) const { return (col & mMask) >> mOffset; }
 
182
    float colorValNorm(uint32_t col) const { return ((float)colorVal(col))/mRange; }
 
183
private:
 
184
    uint32_t mMask;
 
185
    uint32_t mRange;
 
186
    uint32_t mOffset;
 
187
    uint32_t mcBits;
 
188
};
 
189
 
 
190
class VBoxVHWAColorFormat
 
191
{
 
192
public:
 
193
 
 
194
//    VBoxVHWAColorFormat(GLint aInternalFormat, GLenum aFormat, GLenum aType, uint32_t aDataFormat);
 
195
    VBoxVHWAColorFormat(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
 
196
    VBoxVHWAColorFormat(uint32_t fourcc);
 
197
    VBoxVHWAColorFormat(){}
 
198
    GLint internalFormat() const {return mInternalFormat; }
 
199
    GLenum format() const {return mFormat; }
 
200
    GLenum type() const {return mType; }
 
201
    bool isValid() const {return mBitsPerPixel != 0; }
 
202
    uint32_t fourcc() const {return mDataFormat;}
 
203
    uint32_t bitsPerPixel() const { return mBitsPerPixel; }
 
204
    uint32_t bitsPerPixelTex() const { return mBitsPerPixelTex; }
 
205
//    uint32_t bitsPerPixelDd() const { return mBitsPerPixelDd; }
 
206
    void pixel2Normalized(uint32_t pix, float *r, float *g, float *b) const;
 
207
    uint32_t widthCompression() const {return mWidthCompression;}
 
208
    uint32_t heightCompression() const {return mHeightCompression;}
 
209
    const VBoxVHWAColorComponent& r() const {return mR;}
 
210
    const VBoxVHWAColorComponent& g() const {return mG;}
 
211
    const VBoxVHWAColorComponent& b() const {return mB;}
 
212
    const VBoxVHWAColorComponent& a() const {return mA;}
 
213
 
 
214
    bool equals (const VBoxVHWAColorFormat & other) const;
 
215
 
 
216
private:
 
217
    void init(uint32_t bitsPerPixel, uint32_t r, uint32_t g, uint32_t b);
 
218
    void init(uint32_t fourcc);
 
219
 
 
220
    GLint mInternalFormat;
 
221
    GLenum mFormat;
 
222
    GLenum mType;
 
223
    uint32_t mDataFormat;
 
224
 
 
225
    uint32_t mBitsPerPixel;
 
226
    uint32_t mBitsPerPixelTex;
 
227
//    uint32_t mBitsPerPixelDd;
 
228
    uint32_t mWidthCompression;
 
229
    uint32_t mHeightCompression;
 
230
    VBoxVHWAColorComponent mR;
 
231
    VBoxVHWAColorComponent mG;
 
232
    VBoxVHWAColorComponent mB;
 
233
    VBoxVHWAColorComponent mA;
 
234
};
 
235
 
 
236
class VBoxVHWATexture
 
237
{
 
238
public:
 
239
    VBoxVHWATexture() {}
 
240
    VBoxVHWATexture(const QRect & aRect, const VBoxVHWAColorFormat &aFormat);
 
241
    virtual ~VBoxVHWATexture();
 
242
    virtual void init(uchar *pvMem);
 
243
    void setAddress(uchar *pvMem) {mAddress = pvMem;}
 
244
    void update(const QRect * pRect) { doUpdate(mAddress, pRect);}
 
245
    void bind() {glBindTexture(texTarget(), mTexture);}
 
246
 
 
247
    virtual void texCoord(int x, int y);
 
248
    virtual void multiTexCoord(GLenum texUnit, int x, int y);
 
249
 
 
250
//    GLuint texture() {return mTexture;}
 
251
    const QRect & texRect() {return mTexRect;}
 
252
    const QRect & rect() {return mRect;}
 
253
    uchar * address(){ return mAddress; }
 
254
    uint32_t rectSizeTex(const QRect * pRect) {return pRect->width() * pRect->height() * mBytesPerPixelTex;}
 
255
    uchar * pointAddress(int x, int y)
 
256
    {
 
257
        x = toXTex(x);
 
258
        y = toYTex(y);
 
259
        return pointAddressTex(x, y);
 
260
    }
 
261
    uint32_t pointOffsetTex(int x, int y) { return y*mBytesPerLine + x*mBytesPerPixelTex; }
 
262
    uchar * pointAddressTex(int x, int y) { return mAddress + pointOffsetTex(x, y); }
 
263
    int toXTex(int x) {return x/mColorFormat.widthCompression();}
 
264
    int toYTex(int y) {return y/mColorFormat.heightCompression();}
 
265
    ulong memSize(){ return mBytesPerLine * mRect.height(); }
 
266
    uint32_t bytesPerLine() {return mBytesPerLine; }
 
267
 
 
268
protected:
 
269
    virtual void doUpdate(uchar * pAddress, const QRect * pRect);
 
270
    virtual void initParams();
 
271
    virtual void load();
 
272
    virtual GLenum texTarget() {return GL_TEXTURE_2D; }
 
273
 
 
274
 
 
275
    QRect mTexRect; /* texture size */
 
276
    QRect mRect; /* img size */
 
277
    uchar * mAddress;
 
278
    GLuint mTexture;
 
279
    uint32_t mBytesPerPixel;
 
280
    uint32_t mBytesPerPixelTex;
 
281
    uint32_t mBytesPerLine;
 
282
    VBoxVHWAColorFormat mColorFormat;
 
283
private:
 
284
    void uninit();
 
285
};
 
286
 
 
287
class VBoxVHWATextureNP2 : public VBoxVHWATexture
 
288
{
 
289
public:
 
290
    VBoxVHWATextureNP2() : VBoxVHWATexture() {}
 
291
    VBoxVHWATextureNP2(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
 
292
        VBoxVHWATexture(aRect, aFormat){
 
293
        mTexRect = QRect(0, 0, aRect.width()/aFormat.widthCompression(), aRect.height()/aFormat.heightCompression());
 
294
    }
 
295
};
 
296
 
 
297
class VBoxVHWATextureNP2Rect : public VBoxVHWATextureNP2
 
298
{
 
299
public:
 
300
    VBoxVHWATextureNP2Rect() : VBoxVHWATextureNP2() {}
 
301
    VBoxVHWATextureNP2Rect(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
 
302
        VBoxVHWATextureNP2(aRect, aFormat){}
 
303
 
 
304
    virtual void texCoord(int x, int y);
 
305
    virtual void multiTexCoord(GLenum texUnit, int x, int y);
 
306
protected:
 
307
    virtual GLenum texTarget();
 
308
};
 
309
 
 
310
class VBoxVHWATextureNP2RectPBO : public VBoxVHWATextureNP2Rect
 
311
{
 
312
public:
 
313
    VBoxVHWATextureNP2RectPBO() : VBoxVHWATextureNP2Rect() {}
 
314
    VBoxVHWATextureNP2RectPBO(const QRect & aRect, const VBoxVHWAColorFormat &aFormat) :
 
315
        VBoxVHWATextureNP2Rect(aRect, aFormat){}
 
316
    virtual ~VBoxVHWATextureNP2RectPBO();
 
317
 
 
318
    virtual void init(uchar *pvMem);
 
319
protected:
 
320
    virtual void load();
 
321
    virtual void doUpdate(uchar * pAddress, const QRect * pRect);
 
322
private:
 
323
    GLuint mPBO;
 
324
};
 
325
 
 
326
#ifdef VBOXVHWA_USE_TEXGROUP
 
327
class VBoxVHWATextureGroup
 
328
{
 
329
public:
 
330
    VBoxVHWATextureGroup()
 
331
    {
 
332
        init(0, 0);
 
333
    }
 
334
 
 
335
    VBoxVHWATextureGroup(uint32_t cTextures, uint32_t cBacks)
 
336
    {
 
337
        init(cTextures, cBacks);
 
338
    }
 
339
 
 
340
    ~VBoxVHWATextureGroup()
 
341
    {
 
342
        delete[] mppTextures;
 
343
        delete[] mpDisplays;
 
344
    }
 
345
 
 
346
    VBoxVHWATexture*& operator[] (size_t i) { return mppCurTextures[i]; }
 
347
    void swap()
 
348
    {
 
349
        mCur = ((++mCur) % mcSets);
 
350
        if(mCur)
 
351
            mppCurTextures += mcTextures;
 
352
        else
 
353
            mppCurTextures = mppTextures;
 
354
    }
 
355
    uint32_t numSets() { return mcSets; }
 
356
 
 
357
    void init(uint32_t cTextures, uint32_t cBacks)
 
358
    {
 
359
        mCur = 0;
 
360
        mcTextures = cTextures;
 
361
        mcSets = cBacks + 1;
 
362
        if(mcTextures)
 
363
        {
 
364
            mppTextures = new VBoxVHWATexture*[mcSets * cTextures];
 
365
            mppCurTextures = mppTextures;
 
366
            memset(mppTextures, 0, sizeof(mppTextures[0]) * mcSets * cTextures);
 
367
            mpDisplays = new GLuint[mcSets];
 
368
            memset(mpDisplays, 0, sizeof(mpDisplays[0]) * mcSets);
 
369
        }
 
370
        else
 
371
        {
 
372
            mppTextures = mppCurTextures = NULL;
 
373
            mpDisplays = NULL;
 
374
        }
 
375
    }
 
376
 
 
377
    GLuint& display() {return mpDisplays[mCur];}
 
378
private:
 
379
    VBoxVHWATexture **mppTextures;
 
380
    VBoxVHWATexture **mppCurTextures;
 
381
    GLuint * mpDisplays;
 
382
    uint32_t mCur;
 
383
    uint32_t mcTextures;
 
384
    uint32_t mcSets;
 
385
};
 
386
#endif
 
387
 
 
388
class VBoxVHWAHandleTable
 
389
{
 
390
public:
 
391
    VBoxVHWAHandleTable(uint32_t initialSize);
 
392
    ~VBoxVHWAHandleTable();
 
393
    uint32_t put(void * data);
 
394
    bool mapPut(uint32_t h, void * data);
 
395
    void* get(uint32_t h);
 
396
    void* remove(uint32_t h);
 
397
private:
 
398
    void doPut(uint32_t h, void * data);
 
399
    void doRemove(uint32_t h);
 
400
    void** mTable;
 
401
    uint32_t mcSize;
 
402
    uint32_t mcUsage;
 
403
    uint32_t mCursor;
 
404
};
 
405
 
 
406
/* data flow:
 
407
 * I. NON-Yinverted surface:
 
408
 * 1.direct memory update (paint, lock/unlock):
 
409
 *  mem->tex->fb
 
410
 * 2.blt
 
411
 *  srcTex->invFB->tex->fb
 
412
 *              |->mem
 
413
 *
 
414
 * II. Yinverted surface:
 
415
 * 1.direct memory update (paint, lock/unlock):
 
416
 *  mem->tex->fb
 
417
 * 2.blt
 
418
 *  srcTex->fb->tex
 
419
 *           |->mem
 
420
 *
 
421
 * III. flip support:
 
422
 * 1. Yinverted<->NON-YInverted conversion :
 
423
 *  mem->tex-(rotate model view, force LAZY complete fb update)->invFB->tex
 
424
 *  fb-->|                                                           |->mem
 
425
 * */
 
426
class VBoxVHWASurfaceBase
 
427
{
 
428
public:
 
429
    VBoxVHWASurfaceBase(
 
430
            class VBoxGLWidget *mWidget,
 
431
#if 0
 
432
            class VBoxVHWAGlContextState *aState,
 
433
            bool aIsYInverted,
 
434
#endif
 
435
            const QSize & aSize,
 
436
            const QRect & aTargRect,
 
437
            const QRect & aSrcRect,
 
438
            const QRect & aVisTargRect,
 
439
            VBoxVHWAColorFormat & aColorFormat,
 
440
            VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
 
441
            VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
 
442
#ifdef VBOXVHWA_USE_TEXGROUP
 
443
            uint32_t cBackTex,
 
444
#endif
 
445
            bool bVGA);
 
446
 
 
447
    virtual ~VBoxVHWASurfaceBase();
 
448
 
 
449
    void init(VBoxVHWASurfaceBase * pPrimary, uchar *pvMem);
 
450
 
 
451
    void uninit();
 
452
 
 
453
    static void globalInit();
 
454
 
 
455
//    int blt(const QRect * aDstRect, VBoxVHWASurfaceBase * aSrtSurface, const QRect * aSrcRect, const VBoxVHWAColorKey * pDstCKeyOverride, const VBoxVHWAColorKey * pSrcCKeyOverride);
 
456
 
 
457
    int lock(const QRect * pRect, uint32_t flags);
 
458
 
 
459
    int unlock();
 
460
 
 
461
    void updatedMem(const QRect * aRect);
 
462
 
 
463
    bool performDisplay(VBoxVHWASurfaceBase *pPrimary, bool bForce);
 
464
 
 
465
    void setRects (const QRect & aTargRect, const QRect & aSrcRect);
 
466
    void setTargRectPosition (const QPoint & aPoint);
 
467
    void setVisibilityReinitFlag() { mNeedVisibilityReinit = true; }
 
468
    void updateVisibility (VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect, bool bNotIntersected, bool bForce);
 
469
 
 
470
    static ulong calcBytesPerPixel(GLenum format, GLenum type);
 
471
 
 
472
    static GLsizei makePowerOf2(GLsizei val);
 
473
 
 
474
    bool    addressAlocated() const { return mFreeAddress; }
 
475
    uchar * address(){ return mAddress; }
 
476
 
 
477
    ulong   memSize();
 
478
 
 
479
    ulong width()  { return mRect.width();  }
 
480
    ulong height() { return mRect.height(); }
 
481
    const QSize size() {return mRect.size();}
 
482
 
 
483
    GLenum format() {return mColorFormat.format(); }
 
484
    GLint  internalFormat() { return mColorFormat.internalFormat(); }
 
485
    GLenum type() { return mColorFormat.type(); }
 
486
    uint32_t fourcc() {return mColorFormat.fourcc(); }
 
487
 
 
488
//    ulong  bytesPerPixel() { return mpTex[0]->bytesPerPixel(); }
 
489
    ulong  bitsPerPixel() { return mColorFormat.bitsPerPixel(); }
 
490
//    ulong  bitsPerPixelDd() { return mColorFormat.bitsPerPixelDd(); }
 
491
    ulong  bytesPerLine() { return mpTex[0]->bytesPerLine(); }
 
492
 
 
493
    const VBoxVHWAColorKey * dstBltCKey() const { return mpDstBltCKey; }
 
494
    const VBoxVHWAColorKey * srcBltCKey() const { return mpSrcBltCKey; }
 
495
    const VBoxVHWAColorKey * dstOverlayCKey() const { return mpDstOverlayCKey; }
 
496
    const VBoxVHWAColorKey * defaultSrcOverlayCKey() const { return mpDefaultSrcOverlayCKey; }
 
497
    const VBoxVHWAColorKey * defaultDstOverlayCKey() const { return mpDefaultDstOverlayCKey; }
 
498
    const VBoxVHWAColorKey * srcOverlayCKey() const { return mpSrcOverlayCKey; }
 
499
    void resetDefaultSrcOverlayCKey() { mpSrcOverlayCKey = mpDefaultSrcOverlayCKey; }
 
500
    void resetDefaultDstOverlayCKey() { mpDstOverlayCKey = mpDefaultDstOverlayCKey; }
 
501
 
 
502
    void setDstBltCKey(const VBoxVHWAColorKey * ckey)
 
503
    {
 
504
        if(ckey)
 
505
        {
 
506
            mDstBltCKey = *ckey;
 
507
            mpDstBltCKey = &mDstBltCKey;
 
508
        }
 
509
        else
 
510
        {
 
511
            mpDstBltCKey = NULL;
 
512
        }
 
513
    }
 
514
 
 
515
    void setSrcBltCKey(const VBoxVHWAColorKey * ckey)
 
516
    {
 
517
        if(ckey)
 
518
        {
 
519
            mSrcBltCKey = *ckey;
 
520
            mpSrcBltCKey = &mSrcBltCKey;
 
521
        }
 
522
        else
 
523
        {
 
524
            mpSrcBltCKey = NULL;
 
525
        }
 
526
    }
 
527
 
 
528
    void setDefaultDstOverlayCKey(const VBoxVHWAColorKey * ckey)
 
529
    {
 
530
        if(ckey)
 
531
        {
 
532
            mDefaultDstOverlayCKey = *ckey;
 
533
            mpDefaultDstOverlayCKey = &mDefaultDstOverlayCKey;
 
534
        }
 
535
        else
 
536
        {
 
537
            mpDefaultDstOverlayCKey = NULL;
 
538
        }
 
539
    }
 
540
 
 
541
    void setDefaultSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
 
542
    {
 
543
        if(ckey)
 
544
        {
 
545
            mDefaultSrcOverlayCKey = *ckey;
 
546
            mpDefaultSrcOverlayCKey = &mDefaultSrcOverlayCKey;
 
547
        }
 
548
        else
 
549
        {
 
550
            mpDefaultSrcOverlayCKey = NULL;
 
551
        }
 
552
    }
 
553
 
 
554
    void setOverriddenDstOverlayCKey(const VBoxVHWAColorKey * ckey)
 
555
    {
 
556
        if(ckey)
 
557
        {
 
558
            mOverriddenDstOverlayCKey = *ckey;
 
559
            mpDstOverlayCKey = &mOverriddenDstOverlayCKey;
 
560
        }
 
561
        else
 
562
        {
 
563
            mpDstOverlayCKey = NULL;
 
564
        }
 
565
    }
 
566
 
 
567
    void setOverriddenSrcOverlayCKey(const VBoxVHWAColorKey * ckey)
 
568
    {
 
569
        if(ckey)
 
570
        {
 
571
            mOverriddenSrcOverlayCKey = *ckey;
 
572
            mpSrcOverlayCKey = &mOverriddenSrcOverlayCKey;
 
573
        }
 
574
        else
 
575
        {
 
576
            mpSrcOverlayCKey = NULL;
 
577
        }
 
578
    }
 
579
 
 
580
    const VBoxVHWAColorKey * getActiveSrcOverlayCKey()
 
581
    {
 
582
        return mpSrcOverlayCKey;
 
583
    }
 
584
 
 
585
    const VBoxVHWAColorKey * getActiveDstOverlayCKey(VBoxVHWASurfaceBase * pPrimary)
 
586
    {
 
587
        return mpDstOverlayCKey ? mpDefaultDstOverlayCKey : pPrimary->mpDstOverlayCKey;
 
588
    }
 
589
 
 
590
    const VBoxVHWAColorFormat & colorFormat() {return mColorFormat; }
 
591
 
 
592
    void setAddress(uchar * addr);
 
593
 
 
594
    const QRect& rect() const {return mRect;}
 
595
    const QRect& srcRect() const {return mSrcRect; }
 
596
    const QRect& targRect() const {return mTargRect; }
 
597
    class VBoxVHWASurfList * getComplexList() {return mComplexList; }
 
598
 
 
599
    class VBoxVHWAGlProgramMngr * getGlProgramMngr();
 
600
    static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
 
601
 
 
602
    uint32_t handle() const {return mHGHandle;}
 
603
    void setHandle(uint32_t h) {mHGHandle = h;}
 
604
 
 
605
    const VBoxVHWADirtyRect & getDirtyRect() { return mUpdateMem2TexRect; }
 
606
 
 
607
    class VBoxVHWAGlProgramVHWA * getProgram(VBoxVHWASurfaceBase * pPrimary)
 
608
    {
 
609
        if(mVisibleDisplayInitialized)
 
610
            return mpProgram;
 
611
        return calcProgram(pPrimary);
 
612
    }
 
613
private:
 
614
    class VBoxVHWAGlProgramVHWA * calcProgram(VBoxVHWASurfaceBase * pPrimary);
 
615
    void setRectValues (const QRect & aTargRect, const QRect & aSrcRect);
 
616
    void setVisibleRectValues (const QRect & aVisTargRect);
 
617
 
 
618
    void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
 
619
    void initDisplay(VBoxVHWASurfaceBase *pPrimary);
 
620
    void deleteDisplay();
 
621
 
 
622
    int createDisplay(VBoxVHWASurfaceBase *pPrimary, GLuint *pDisplay, class VBoxVHWAGlProgramVHWA ** ppProgram);
 
623
    void doDisplay(VBoxVHWASurfaceBase *pPrimary, bool bProgram, bool bBindDst);
 
624
    bool synchTexMem(const QRect * aRect);
 
625
 
 
626
    int performBlt(const QRect * pDstRect, VBoxVHWASurfaceBase * pSrcSurface, const QRect * pSrcRect, const VBoxVHWAColorKey * pDstCKey, const VBoxVHWAColorKey * pSrcCKey, bool blt);
 
627
 
 
628
    void doTex2FB(const QRect * pDstRect, const QRect * pSrcRect);
 
629
    void doMultiTex2FB(const QRect * pDstRect, VBoxVHWATexture * pDstTex, const QRect * pSrcRect, int cSrcTex);
 
630
    void doMultiTex2FB(const QRect * pDstRect, const QRect * pSrcRect, int cSrcTex);
 
631
 
 
632
    QRect mRect; /* == Inv FB size */
 
633
 
 
634
    QRect mSrcRect;
 
635
    QRect mTargRect; /* == Vis FB size */
 
636
 
 
637
    QRect mVisibleTargRect;
 
638
    QRect mVisibleSrcRect;
 
639
 
 
640
#ifndef VBOXVHWA_USE_TEXGROUP
 
641
    GLuint mVisibleDisplay;
 
642
#endif
 
643
    class VBoxVHWAGlProgramVHWA * mpProgram;
 
644
 
 
645
    bool mVisibleDisplayInitialized;
 
646
    bool mNeedVisibilityReinit;
 
647
    bool mNotIntersected;
 
648
 
 
649
    uchar * mAddress;
 
650
#ifdef VBOXVHWA_USE_TEXGROUP
 
651
    VBoxVHWATextureGroup mpTex;
 
652
#else
 
653
    VBoxVHWATexture *mpTex[3];
 
654
#endif
 
655
 
 
656
    VBoxVHWAColorFormat mColorFormat;
 
657
 
 
658
    VBoxVHWAColorKey *mpSrcBltCKey;
 
659
    VBoxVHWAColorKey *mpDstBltCKey;
 
660
    VBoxVHWAColorKey *mpSrcOverlayCKey;
 
661
    VBoxVHWAColorKey *mpDstOverlayCKey;
 
662
 
 
663
    VBoxVHWAColorKey *mpDefaultDstOverlayCKey;
 
664
    VBoxVHWAColorKey *mpDefaultSrcOverlayCKey;
 
665
 
 
666
    VBoxVHWAColorKey mSrcBltCKey;
 
667
    VBoxVHWAColorKey mDstBltCKey;
 
668
    VBoxVHWAColorKey mOverriddenSrcOverlayCKey;
 
669
    VBoxVHWAColorKey mOverriddenDstOverlayCKey;
 
670
    VBoxVHWAColorKey mDefaultDstOverlayCKey;
 
671
    VBoxVHWAColorKey mDefaultSrcOverlayCKey;
 
672
 
 
673
    int mLockCount;
 
674
    /* memory buffer not reflected in fm and texture, e.g if memory buffer is replaced or in case of lock/unlock  */
 
675
    VBoxVHWADirtyRect mUpdateMem2TexRect;
 
676
 
 
677
    bool mFreeAddress;
 
678
 
 
679
    class VBoxVHWASurfList *mComplexList;
 
680
 
 
681
    class VBoxGLWidget *mWidget;
 
682
 
 
683
    uint32_t mHGHandle;
 
684
 
 
685
#ifdef DEBUG
 
686
public:
 
687
    uint64_t cFlipsCurr;
 
688
    uint64_t cFlipsTarg;
 
689
#endif
 
690
    friend class VBoxVHWASurfList;
 
691
};
 
692
 
 
693
typedef std::list <VBoxVHWASurfaceBase*> SurfList;
 
694
typedef std::list <VBoxVHWASurfList*> OverlayList;
 
695
typedef std::list <struct _VBOXVHWACMD *> VHWACommandList;
 
696
 
 
697
class VBoxVHWASurfList
 
698
{
 
699
public:
 
700
 
 
701
    VBoxVHWASurfList() : mCurrent(NULL) {}
 
702
    void add(VBoxVHWASurfaceBase *pSurf)
 
703
    {
 
704
        VBoxVHWASurfList * pOld = pSurf->getComplexList();
 
705
        if(pOld)
 
706
        {
 
707
            pOld->remove(pSurf);
 
708
        }
 
709
        mSurfaces.push_back(pSurf);
 
710
        pSurf->setComplexList(this);
 
711
    }
 
712
 
 
713
    void clear()
 
714
    {
 
715
        for (SurfList::iterator it = mSurfaces.begin();
 
716
             it != mSurfaces.end(); ++ it)
 
717
        {
 
718
            (*it)->setComplexList(NULL);
 
719
        }
 
720
        mSurfaces.clear();
 
721
        mCurrent = NULL;
 
722
    }
 
723
 
 
724
    size_t size() const {return mSurfaces.size(); }
 
725
 
 
726
    void remove(VBoxVHWASurfaceBase *pSurf)
 
727
    {
 
728
        mSurfaces.remove(pSurf);
 
729
        pSurf->setComplexList(NULL);
 
730
        if(mCurrent == pSurf)
 
731
            mCurrent = NULL;
 
732
    }
 
733
 
 
734
    bool empty() { return mSurfaces.empty(); }
 
735
 
 
736
    void setCurrentVisible(VBoxVHWASurfaceBase *pSurf)
 
737
    {
 
738
        mCurrent = pSurf;
 
739
    }
 
740
 
 
741
    VBoxVHWASurfaceBase * current() { return mCurrent; }
 
742
    const SurfList & surfaces() const {return mSurfaces;}
 
743
 
 
744
private:
 
745
 
 
746
    SurfList mSurfaces;
 
747
    VBoxVHWASurfaceBase* mCurrent;
 
748
};
 
749
 
 
750
class VBoxVHWADisplay
 
751
{
 
752
public:
 
753
    VBoxVHWADisplay() :
 
754
        mSurfVGA(NULL),
 
755
        mbDisplayPrimary(true)
 
756
//        ,
 
757
//        mSurfPrimary(NULL)
 
758
    {}
 
759
 
 
760
    VBoxVHWASurfaceBase * setVGA(VBoxVHWASurfaceBase * pVga)
 
761
    {
 
762
        VBoxVHWASurfaceBase * old = mSurfVGA;
 
763
        mSurfVGA = pVga;
 
764
        mPrimary.clear();
 
765
        if(pVga)
 
766
        {
 
767
            Assert(!pVga->getComplexList());
 
768
            mPrimary.add(pVga);
 
769
            mPrimary.setCurrentVisible(pVga);
 
770
        }
 
771
//        mSurfPrimary = pVga;
 
772
        mOverlays.clear();
 
773
        return old;
 
774
    }
 
775
 
 
776
    VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
 
777
    {
 
778
        VBoxVHWASurfaceBase * old = mSurfVGA;
 
779
        Assert(old);
 
780
        mSurfVGA = pVga;
 
781
        return old;
 
782
    }
 
783
 
 
784
    VBoxVHWASurfaceBase * getVGA() const
 
785
    {
 
786
        return mSurfVGA;
 
787
    }
 
788
 
 
789
    VBoxVHWASurfaceBase * getPrimary()
 
790
    {
 
791
        return mPrimary.current();
 
792
    }
 
793
 
 
794
    void addOverlay(VBoxVHWASurfList * pSurf)
 
795
    {
 
796
        mOverlays.push_back(pSurf);
 
797
    }
 
798
 
 
799
    void checkAddOverlay(VBoxVHWASurfList * pSurf)
 
800
    {
 
801
        if(!hasOverlay(pSurf))
 
802
            addOverlay(pSurf);
 
803
    }
 
804
 
 
805
    bool hasOverlay(VBoxVHWASurfList * pSurf)
 
806
    {
 
807
        for (OverlayList::iterator it = mOverlays.begin();
 
808
             it != mOverlays.end(); ++ it)
 
809
        {
 
810
            if((*it) == pSurf)
 
811
            {
 
812
                return true;
 
813
            }
 
814
        }
 
815
        return false;
 
816
    }
 
817
 
 
818
    void removeOverlay(VBoxVHWASurfList * pSurf)
 
819
    {
 
820
        mOverlays.remove(pSurf);
 
821
    }
 
822
 
 
823
    bool performDisplay(bool bForce)
 
824
    {
 
825
        VBoxVHWASurfaceBase * pPrimary = mPrimary.current();
 
826
 
 
827
        if(mbDisplayPrimary)
 
828
        {
 
829
#ifdef DEBUG_misha
 
830
            /* should only display overlay now */
 
831
            AssertBreakpoint();
 
832
#endif
 
833
            bForce |= pPrimary->performDisplay(NULL, bForce);
 
834
        }
 
835
 
 
836
        for (OverlayList::const_iterator it = mOverlays.begin();
 
837
             it != mOverlays.end(); ++ it)
 
838
        {
 
839
            VBoxVHWASurfaceBase * pOverlay = (*it)->current();
 
840
            if(pOverlay)
 
841
            {
 
842
                bForce |= pOverlay->performDisplay(pPrimary, bForce);
 
843
            }
 
844
        }
 
845
        return bForce;
 
846
    }
 
847
 
 
848
    bool isPrimary(VBoxVHWASurfaceBase * pSurf) { return pSurf->getComplexList() == &mPrimary; }
 
849
 
 
850
    void setDisplayPrimary(bool bDisplay) { mbDisplayPrimary = bDisplay; }
 
851
 
 
852
    const OverlayList & overlays() const {return mOverlays;}
 
853
    const VBoxVHWASurfList & primaries() const { return mPrimary; }
 
854
 
 
855
private:
 
856
    VBoxVHWASurfaceBase *mSurfVGA;
 
857
    VBoxVHWASurfList mPrimary;
 
858
 
 
859
    OverlayList mOverlays;
 
860
 
 
861
    bool mbDisplayPrimary;
 
862
};
 
863
 
 
864
typedef void (VBoxGLWidget::*PFNVBOXQGLOP)(void* );
 
865
 
 
866
typedef void (*PFNVBOXQGLFUNC)(void*, void*);
 
867
 
 
868
typedef enum
 
869
{
 
870
    VBOXVHWA_PIPECMD_PAINT = 1,
 
871
    VBOXVHWA_PIPECMD_VHWA,
 
872
    VBOXVHWA_PIPECMD_OP,
 
873
    VBOXVHWA_PIPECMD_FUNC,
 
874
}VBOXVHWA_PIPECMD_TYPE;
 
875
 
 
876
typedef struct VBOXVHWACALLBACKINFO
 
877
{
 
878
    VBoxGLWidget *pThis;
 
879
    PFNVBOXQGLOP pfnCallback;
 
880
    void * pContext;
 
881
}VBOXVHWACALLBACKINFO;
 
882
 
 
883
typedef struct VBOXVHWAFUNCCALLBACKINFO
 
884
{
 
885
    PFNVBOXQGLFUNC pfnCallback;
 
886
    void * pContext1;
 
887
    void * pContext2;
 
888
}VBOXVHWAFUNCCALLBACKINFO;
 
889
 
 
890
class VBoxVHWACommandElement
 
891
{
 
892
public:
 
893
    void setVHWACmd(struct _VBOXVHWACMD * pCmd)
 
894
    {
 
895
        mType = VBOXVHWA_PIPECMD_VHWA;
 
896
        u.mpCmd = pCmd;
 
897
    }
 
898
 
 
899
    void setPaintCmd(const QRect & aRect)
 
900
    {
 
901
        mType = VBOXVHWA_PIPECMD_PAINT;
 
902
        mRect = aRect;
 
903
    }
 
904
 
 
905
    void setOp(const VBOXVHWACALLBACKINFO & aOp)
 
906
    {
 
907
        mType = VBOXVHWA_PIPECMD_OP;
 
908
        u.mCallback = aOp;
 
909
    }
 
910
 
 
911
    void setFunc(const VBOXVHWAFUNCCALLBACKINFO & aOp)
 
912
    {
 
913
        mType = VBOXVHWA_PIPECMD_FUNC;
 
914
        u.mFuncCallback = aOp;
 
915
    }
 
916
 
 
917
    void setData(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
 
918
    {
 
919
        switch(aType)
 
920
        {
 
921
        case VBOXVHWA_PIPECMD_PAINT:
 
922
            setPaintCmd(*((QRect*)pvData));
 
923
            break;
 
924
        case VBOXVHWA_PIPECMD_VHWA:
 
925
            setVHWACmd((struct _VBOXVHWACMD *)pvData);
 
926
            break;
 
927
        case VBOXVHWA_PIPECMD_OP:
 
928
            setOp(*((VBOXVHWACALLBACKINFO *)pvData));
 
929
            break;
 
930
        case VBOXVHWA_PIPECMD_FUNC:
 
931
            setFunc(*((VBOXVHWAFUNCCALLBACKINFO *)pvData));
 
932
            break;
 
933
        default:
 
934
            Assert(0);
 
935
            break;
 
936
        }
 
937
    }
 
938
 
 
939
    VBOXVHWA_PIPECMD_TYPE type() const {return mType;}
 
940
    const QRect & rect() const {return mRect;}
 
941
    struct _VBOXVHWACMD * vhwaCmd() const {return u.mpCmd;}
 
942
    const VBOXVHWACALLBACKINFO & op() const {return u.mCallback; }
 
943
    const VBOXVHWAFUNCCALLBACKINFO & func() const {return u.mFuncCallback; }
 
944
 
 
945
    VBoxVHWACommandElement * mpNext;
 
946
private:
 
947
    VBOXVHWA_PIPECMD_TYPE mType;
 
948
    union
 
949
    {
 
950
        struct _VBOXVHWACMD * mpCmd;
 
951
        VBOXVHWACALLBACKINFO mCallback;
 
952
        VBOXVHWAFUNCCALLBACKINFO mFuncCallback;
 
953
    }u;
 
954
    QRect                 mRect;
 
955
};
 
956
 
 
957
class VBoxVHWACommandElementPipe
 
958
{
 
959
public:
 
960
    VBoxVHWACommandElementPipe() :
 
961
        mpFirst(NULL),
 
962
        mpLast(NULL)
 
963
    {}
 
964
 
 
965
    void put(VBoxVHWACommandElement *pCmd)
 
966
    {
 
967
        if(mpLast)
 
968
        {
 
969
            Assert(mpFirst);
 
970
            mpLast->mpNext = pCmd;
 
971
            mpLast = pCmd;
 
972
        }
 
973
        else
 
974
        {
 
975
            Assert(!mpFirst);
 
976
            mpFirst = pCmd;
 
977
            mpLast = pCmd;
 
978
        }
 
979
        pCmd->mpNext= NULL;
 
980
 
 
981
    }
 
982
 
 
983
    VBoxVHWACommandElement * detachList()
 
984
    {
 
985
        if(mpLast)
 
986
        {
 
987
            VBoxVHWACommandElement * pHead = mpFirst;
 
988
            mpFirst = NULL;
 
989
            mpLast = NULL;
 
990
            return pHead;
 
991
        }
 
992
        return NULL;
 
993
    }
 
994
private:
 
995
    VBoxVHWACommandElement *mpFirst;
 
996
    VBoxVHWACommandElement *mpLast;
 
997
};
 
998
 
 
999
class VBoxVHWACommandElementStack
 
1000
{
 
1001
public:
 
1002
    VBoxVHWACommandElementStack() :
 
1003
        mpFirst(NULL) {}
 
1004
 
 
1005
    void push(VBoxVHWACommandElement *pCmd)
 
1006
    {
 
1007
        pCmd->mpNext = mpFirst;
 
1008
        mpFirst = pCmd;
 
1009
    }
 
1010
 
 
1011
    void pusha(VBoxVHWACommandElement *pFirst, VBoxVHWACommandElement *pLast)
 
1012
    {
 
1013
        pLast->mpNext = mpFirst;
 
1014
        mpFirst = pFirst;
 
1015
    }
 
1016
 
 
1017
    VBoxVHWACommandElement * pop()
 
1018
    {
 
1019
        if(mpFirst)
 
1020
        {
 
1021
            VBoxVHWACommandElement * ret = mpFirst;
 
1022
            mpFirst = ret->mpNext;
 
1023
            return ret;
 
1024
        }
 
1025
        return NULL;
 
1026
    }
 
1027
private:
 
1028
    VBoxVHWACommandElement *mpFirst;
 
1029
};
 
1030
 
 
1031
#define VBOXVHWACMDPIPEC_NEWEVENT      0x00000001
 
1032
#define VBOXVHWACMDPIPEC_COMPLETEEVENT 0x00000002
 
1033
class VBoxVHWACommandElementProcessor
 
1034
{
 
1035
public:
 
1036
    VBoxVHWACommandElementProcessor(class VBoxConsoleView *aView);
 
1037
    ~VBoxVHWACommandElementProcessor();
 
1038
    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData, uint32_t flags);
 
1039
    void completeCurrentEvent();
 
1040
    class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
 
1041
    void reset(class VBoxVHWACommandElement ** ppHead, class VBoxVHWACommandElement ** ppTail);
 
1042
private:
 
1043
    RTCRITSECT mCritSect;
 
1044
    class VBoxVHWACommandProcessEvent *mpFirstEvent;
 
1045
    class VBoxVHWACommandProcessEvent *mpLastEvent;
 
1046
    class VBoxConsoleView *mView;
 
1047
    bool mbNewEvent;
 
1048
    bool mbProcessingList;
 
1049
    VBoxVHWACommandElementStack mFreeElements;
 
1050
    VBoxVHWACommandElement mElementsBuffer[2048];
 
1051
};
 
1052
 
 
1053
class VBoxVHWACommandsQueue
 
1054
{
 
1055
public:
 
1056
    void enqueue(PFNVBOXQGLFUNC pfn, void* pContext1, void* pContext2);
 
1057
 
 
1058
    VBoxVHWACommandElement * detachList();
 
1059
 
 
1060
    void freeList(VBoxVHWACommandElement * pList);
 
1061
 
 
1062
private:
 
1063
    VBoxVHWACommandElementPipe mCmds;
 
1064
};
 
1065
 
 
1066
class VBoxGLWidget : public QGLWidget
 
1067
{
 
1068
public:
 
1069
    VBoxGLWidget (class VBoxConsoleView *aView, QWidget *aParent);
 
1070
    ~VBoxGLWidget();
 
1071
 
 
1072
    ulong vboxPixelFormat() { return mPixelFormat; }
 
1073
    bool vboxUsesGuestVRAM() { return mUsesGuestVRAM; }
 
1074
 
 
1075
    uchar *vboxAddress() { return mDisplay.getVGA() ? mDisplay.getVGA()->address() : NULL; }
 
1076
 
 
1077
#ifdef VBOX_WITH_VIDEOHWACCEL
 
1078
    uchar *vboxVRAMAddressFromOffset(uint64_t offset);
 
1079
    uint64_t vboxVRAMOffsetFromAddress(uchar* addr);
 
1080
    uint64_t vboxVRAMOffset(VBoxVHWASurfaceBase * pSurf);
 
1081
 
 
1082
    void vhwaSaveExec(struct SSMHANDLE * pSSM);
 
1083
    static void vhwaSaveExecVoid(struct SSMHANDLE * pSSM);
 
1084
    static int vhwaLoadExec(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
 
1085
 
 
1086
    int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
 
1087
    int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
 
1088
    int vhwaSurfaceDestroy(struct _VBOXVHWACMD_SURF_DESTROY *pCmd);
 
1089
    int vhwaSurfaceLock(struct _VBOXVHWACMD_SURF_LOCK *pCmd);
 
1090
    int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
 
1091
    int vhwaSurfaceBlt(struct _VBOXVHWACMD_SURF_BLT *pCmd);
 
1092
    int vhwaSurfaceFlip(struct _VBOXVHWACMD_SURF_FLIP *pCmd);
 
1093
    int vhwaSurfaceOverlayUpdate(struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmf);
 
1094
    int vhwaSurfaceOverlaySetPosition(struct _VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pCmd);
 
1095
    int vhwaSurfaceColorkeySet(struct _VBOXVHWACMD_SURF_COLORKEY_SET *pCmd);
 
1096
    int vhwaQueryInfo1(struct _VBOXVHWACMD_QUERYINFO1 *pCmd);
 
1097
    int vhwaQueryInfo2(struct _VBOXVHWACMD_QUERYINFO2 *pCmd);
 
1098
    int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
 
1099
 
 
1100
    bool hasSurfaces() const;
 
1101
    bool hasVisibleOverlays();
 
1102
    QRect overlaysRectUnion();
 
1103
    QRect overlaysRectIntersection();
 
1104
#endif
 
1105
 
 
1106
    int reset(VHWACommandList * pCmdList);
 
1107
 
 
1108
    ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
 
1109
    ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
 
1110
    int vboxFbWidth() {return mDisplay.getVGA()->width(); }
 
1111
    int vboxFbHeight() {return mDisplay.getVGA()->height(); }
 
1112
    bool vboxIsInitialized() {return mDisplay.getVGA() != NULL; }
 
1113
 
 
1114
    void vboxDoResize(void *re);
 
1115
 
 
1116
//    void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
 
1117
    void vboxResizeEvent (class VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
 
1118
 
 
1119
    void vboxProcessVHWACommands(class VBoxVHWACommandElementProcessor * pPipe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pPipe);}
 
1120
 
 
1121
    class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
 
1122
 
 
1123
    VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
 
1124
 
 
1125
#ifdef VBOXVHWA_OLD_COORD
 
1126
    static void doSetupMatrix(const QSize & aSize, bool bInverted);
 
1127
#endif
 
1128
 
 
1129
    void vboxDoUpdateViewport(const QRect & aRect);
 
1130
    void vboxDoUpdateRect(const QRect * pRect);
 
1131
 
 
1132
    const QRect & vboxViewport() const {return mViewport;}
 
1133
 
 
1134
#ifdef VBOXVHWA_PROFILE_FPS
 
1135
    void reportNewFrame() { mbNewFrame = true; }
 
1136
#endif
 
1137
 
 
1138
    bool performDisplayAndSwap(bool bForce)
 
1139
    {
 
1140
//      VBOXQGLLOG_METHODTIME("t:");
 
1141
 
 
1142
        bForce = mDisplay.performDisplay(bForce | mRepaintNeeded);
 
1143
        if(bForce)
 
1144
        {
 
1145
            swapBuffers();
 
1146
        }
 
1147
 
 
1148
#ifdef VBOXVHWA_PROFILE_FPS
 
1149
        if(mbNewFrame)
 
1150
        {
 
1151
            mFPSCounter.frame();
 
1152
            double fps = mFPSCounter.fps();
 
1153
            if(!(mFPSCounter.frames() % 31))
 
1154
            {
 
1155
                printf("fps: %f\n", fps);
 
1156
            }
 
1157
            mbNewFrame = false;
 
1158
        }
 
1159
#endif
 
1160
        return bForce;
 
1161
    }
 
1162
 
 
1163
    VHWACommandList &onResizeCmdList() { return mOnResizeCmdList; }
 
1164
protected:
 
1165
 
 
1166
    void paintGL()
 
1167
    {
 
1168
        if(mpfnOp)
 
1169
        {
 
1170
            (this->*mpfnOp)(mOpContext);
 
1171
            mpfnOp = NULL;
 
1172
        }
 
1173
        VBOXQGLLOG(("paintGL\n"));
 
1174
//        else
 
1175
//        {
 
1176
            mDisplay.performDisplay(true);
 
1177
//        }
 
1178
    }
 
1179
 
 
1180
    void initializeGL();
 
1181
 
 
1182
private:
 
1183
    static void setupMatricies(const QSize &display);
 
1184
    static void adjustViewport(const QSize &display, const QRect &viewport);
 
1185
//    void vboxDoPaint(void *rec);
 
1186
 
 
1187
 
 
1188
#ifdef VBOXQGL_DBG_SURF
 
1189
    void vboxDoTestSurfaces(void *context);
 
1190
#endif
 
1191
#ifdef VBOX_WITH_VIDEOHWACCEL
 
1192
    void vboxDoVHWACmdExec(void *cmd);
 
1193
    void vboxDoVHWACmdAndFree(void *cmd);
 
1194
    void vboxDoVHWACmd(void *cmd);
 
1195
 
 
1196
    void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
 
1197
    {
 
1198
        if (pSurface->addressAlocated())
 
1199
        {
 
1200
            uchar * addr = vboxVRAMAddressFromOffset(offset);
 
1201
            if(addr)
 
1202
            {
 
1203
                pSurface->setAddress(addr);
 
1204
            }
 
1205
        }
 
1206
    }
 
1207
 
 
1208
    int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
 
1209
    static int vhwaLoadSurface(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t cBackBuffers, uint32_t u32Version);
 
1210
    int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
 
1211
    static int vhwaLoadOverlayData(VHWACommandList * pCmdList, struct SSMHANDLE * pSSM, uint32_t u32Version);
 
1212
    static int vhwaLoadVHWAEnable(VHWACommandList * pCmdList);
 
1213
 
 
1214
    void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
 
1215
#endif
 
1216
    static const QGLFormat & vboxGLFormat();
 
1217
 
 
1218
    VBoxVHWADisplay mDisplay;
 
1219
 
 
1220
 
 
1221
    /* we do all opengl stuff in the paintGL context,
 
1222
     * submit the operation to be performed
 
1223
     * @todo: could be moved outside the updateGL */
 
1224
    void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext)
 
1225
    {
 
1226
        mpfnOp = pfn;
 
1227
        mOpContext = pContext;
 
1228
        updateGL();
 
1229
    }
 
1230
 
 
1231
//    /* posts op to UI thread */
 
1232
//    int vboxExecOpSynch(PFNVBOXQGLOP pfn, void* pContext);
 
1233
//    void vboxExecOnResize(PFNVBOXQGLOP pfn, void* pContext);
 
1234
 
 
1235
    void vboxDoProcessVHWACommands(void *pContext);
 
1236
 
 
1237
    class VBoxVHWACommandElement * processCmdList(class VBoxVHWACommandElement * pCmd);
 
1238
 
 
1239
    VBoxVHWASurfaceBase* handle2Surface(uint32_t h)
 
1240
    {
 
1241
        VBoxVHWASurfaceBase* pSurf = (VBoxVHWASurfaceBase*)mSurfHandleTable.get(h);
 
1242
        Assert(pSurf);
 
1243
        return pSurf;
 
1244
    }
 
1245
 
 
1246
    VBoxVHWAHandleTable mSurfHandleTable;
 
1247
 
 
1248
    PFNVBOXQGLOP mpfnOp;
 
1249
    void *mOpContext;
 
1250
 
 
1251
    ulong  mPixelFormat;
 
1252
    bool   mUsesGuestVRAM;
 
1253
 
 
1254
    bool mRepaintNeeded;
 
1255
 
 
1256
//    bool   mbVGASurfCreated;
 
1257
    QRect mViewport;
 
1258
 
 
1259
    class VBoxConsoleView *mView;
 
1260
 
 
1261
    VBoxVHWASurfList *mConstructingList;
 
1262
    int32_t mcRemaining2Contruct;
 
1263
 
 
1264
    /* this is used in saved state restore to postpone surface restoration
 
1265
     * till the framebuffer size is restored */
 
1266
    VHWACommandList mOnResizeCmdList;
 
1267
 
 
1268
    class VBoxVHWAGlProgramMngr *mpMngr;
 
1269
 
 
1270
#ifdef VBOXVHWA_PROFILE_FPS
 
1271
    VBoxVHWADbgTimer mFPSCounter;
 
1272
    bool mbNewFrame;
 
1273
#endif
 
1274
};
 
1275
 
 
1276
 
 
1277
//typedef enum
 
1278
//{
 
1279
//    VBOXFBOVERLAY_DONE = 1,
 
1280
//    VBOXFBOVERLAY_MODIFIED,
 
1281
//    VBOXFBOVERLAY_UNTOUCHED
 
1282
//} VBOXFBOVERLAY_RESUT;
 
1283
 
 
1284
class VBoxQGLOverlay
 
1285
{
 
1286
public:
 
1287
    VBoxQGLOverlay (class VBoxConsoleView *aView, class VBoxFrameBuffer * aContainer);
 
1288
 
 
1289
    int onVHWACommand(struct _VBOXVHWACMD * pCommand);
 
1290
 
 
1291
    void onVHWACommandEvent(QEvent * pEvent);
 
1292
 
 
1293
    /**
 
1294
     * to be called on NotifyUpdate framebuffer call
 
1295
     * @return true if the request was processed & should not be forwarded to the framebuffer
 
1296
     * false - otherwise */
 
1297
    bool onNotifyUpdate (ULONG aX, ULONG aY,
 
1298
                             ULONG aW, ULONG aH);
 
1299
 
 
1300
    /**
 
1301
     * to be called on RequestResize framebuffer call
 
1302
     * @return true if the request was processed & should not be forwarded to the framebuffer
 
1303
     * false - otherwise */
 
1304
    bool onRequestResize (ULONG /*aScreenId*/, ULONG /*aPixelFormat*/,
 
1305
                          BYTE * /*aVRAM*/, ULONG /*aBitsPerPixel*/, ULONG /*aBytesPerLine*/,
 
1306
                          ULONG /*aWidth*/, ULONG /*aHeight*/,
 
1307
                          BOOL * /*aFinished*/)
 
1308
    {
 
1309
        mCmdPipe.completeCurrentEvent();
 
1310
        return false;
 
1311
    }
 
1312
 
 
1313
//    VBOXFBOVERLAY_RESUT onPaintEvent (const QPaintEvent *pe, QRect *pRect);
 
1314
 
 
1315
    void onResizeEvent (const class VBoxResizeEvent *re);
 
1316
    void onResizeEventPostprocess (const class VBoxResizeEvent *re);
 
1317
 
 
1318
    void onViewportResized(QResizeEvent * /*re*/)
 
1319
    {
 
1320
        vboxDoCheckUpdateViewport();
 
1321
        mGlCurrent = false;
 
1322
    }
 
1323
 
 
1324
    void onViewportScrolled(int /*dx*/, int /*dy*/)
 
1325
    {
 
1326
        vboxDoCheckUpdateViewport();
 
1327
        mGlCurrent = false;
 
1328
    }
 
1329
 
 
1330
    static bool isAcceleration2DVideoAvailable();
 
1331
 
 
1332
    /** additional video memory required for the best 2D support performance
 
1333
     *  total amount of VRAM required is thus calculated as requiredVideoMemory + required2DOffscreenVideoMemory  */
 
1334
    static quint64 required2DOffscreenVideoMemory();
 
1335
 
 
1336
    /* not supposed to be called by clients */
 
1337
    int vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version);
 
1338
    void vhwaSaveExec(struct SSMHANDLE * pSSM);
 
1339
private:
 
1340
    int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
 
1341
 
 
1342
    void repaintMain();
 
1343
    void repaintOverlay()
 
1344
    {
 
1345
        if(mNeedOverlayRepaint)
 
1346
        {
 
1347
            mNeedOverlayRepaint = false;
 
1348
            performDisplayOverlay();
 
1349
        }
 
1350
        if(mNeedSetVisible)
 
1351
        {
 
1352
            mNeedSetVisible = false;
 
1353
            mpOverlayWidget->setVisible(true);
 
1354
        }
 
1355
    }
 
1356
    void repaint()
 
1357
    {
 
1358
        repaintOverlay();
 
1359
        repaintMain();
 
1360
    }
 
1361
 
 
1362
    void makeCurrent()
 
1363
    {
 
1364
        if(!mGlCurrent)
 
1365
        {
 
1366
            mGlCurrent = true;
 
1367
            mpOverlayWidget->makeCurrent();
 
1368
        }
 
1369
    }
 
1370
 
 
1371
    void performDisplayOverlay()
 
1372
    {
 
1373
        if(mOverlayVisible)
 
1374
        {
 
1375
#if 0
 
1376
            mpOverlayWidget->updateGL();
 
1377
#else
 
1378
            makeCurrent();
 
1379
            mpOverlayWidget->performDisplayAndSwap(false);
 
1380
#endif
 
1381
        }
 
1382
    }
 
1383
 
 
1384
//    void vboxOpExit()
 
1385
//    {
 
1386
//        performDisplayOverlay();
 
1387
//        mGlCurrent = false;
 
1388
//    }
 
1389
 
 
1390
 
 
1391
    void vboxSetGlOn(bool on);
 
1392
    bool vboxGetGlOn() { return mGlOn; }
 
1393
    bool vboxSynchGl();
 
1394
    void vboxDoVHWACmdExec(void *cmd);
 
1395
    void vboxShowOverlay(bool show);
 
1396
    void vboxDoCheckUpdateViewport();
 
1397
    void vboxDoVHWACmd(void *cmd);
 
1398
    void addMainDirtyRect(const QRect & aRect);
 
1399
//    void vboxUpdateOverlayPosition(const QPoint & pos);
 
1400
    void vboxCheckUpdateOverlay(const QRect & rect);
 
1401
    VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
 
1402
 
 
1403
    int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
 
1404
 
 
1405
    int reset();
 
1406
 
 
1407
    int resetGl();
 
1408
        
 
1409
    void initGl();
 
1410
 
 
1411
    VBoxGLWidget *mpOverlayWidget;
 
1412
    class VBoxConsoleView *mView;
 
1413
    class VBoxFrameBuffer *mContainer;
 
1414
    bool mGlOn;
 
1415
    bool mOverlayWidgetVisible;
 
1416
    bool mOverlayVisible;
 
1417
    bool mGlCurrent;
 
1418
    bool mProcessingCommands;
 
1419
    bool mNeedOverlayRepaint;
 
1420
    bool mNeedSetVisible;
 
1421
    QRect mOverlayViewport;
 
1422
    VBoxVHWADirtyRect mMainDirtyRect;
 
1423
 
 
1424
    VBoxVHWACommandElementProcessor mCmdPipe;
 
1425
 
 
1426
    /* this is used in saved state restore to postpone surface restoration
 
1427
     * till the framebuffer size is restored */
 
1428
    VHWACommandList mOnResizeCmdList;
 
1429
};
 
1430
 
 
1431
 
 
1432
template <class T>
 
1433
class VBoxOverlayFrameBuffer : public T
 
1434
{
 
1435
public:
 
1436
    VBoxOverlayFrameBuffer (class VBoxConsoleView *aView)
 
1437
        : T(aView),
 
1438
          mOverlay(aView, this)
 
1439
    {}
 
1440
 
 
1441
 
 
1442
    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand)
 
1443
    {
 
1444
        return mOverlay.onVHWACommand((struct _VBOXVHWACMD*)pCommand);
 
1445
    }
 
1446
 
 
1447
    void doProcessVHWACommand(QEvent * pEvent)
 
1448
    {
 
1449
        mOverlay.onVHWACommandEvent(pEvent);
 
1450
    }
 
1451
 
 
1452
    STDMETHOD(RequestResize) (ULONG aScreenId, ULONG aPixelFormat,
 
1453
                              BYTE *aVRAM, ULONG aBitsPerPixel, ULONG aBytesPerLine,
 
1454
                              ULONG aWidth, ULONG aHeight,
 
1455
                              BOOL *aFinished)
 
1456
   {
 
1457
        if(mOverlay.onRequestResize (aScreenId, aPixelFormat,
 
1458
                aVRAM, aBitsPerPixel, aBytesPerLine,
 
1459
                aWidth, aHeight,
 
1460
                aFinished))
 
1461
        {
 
1462
            return S_OK;
 
1463
        }
 
1464
        return T::RequestResize (aScreenId, aPixelFormat,
 
1465
                aVRAM, aBitsPerPixel, aBytesPerLine,
 
1466
                aWidth, aHeight,
 
1467
                aFinished);
 
1468
   }
 
1469
 
 
1470
    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
 
1471
                             ULONG aW, ULONG aH)
 
1472
    {
 
1473
        if(mOverlay.onNotifyUpdate(aX, aY, aW, aH))
 
1474
            return S_OK;
 
1475
        return T::NotifyUpdate(aX, aY, aW, aH);
 
1476
    }
 
1477
 
 
1478
//    void paintEvent (QPaintEvent *pe)
 
1479
//    {
 
1480
//        QRect rect;
 
1481
//        VBOXFBOVERLAY_RESUT res = mOverlay.onPaintEvent(pe, &rect);
 
1482
//        switch(res)
 
1483
//        {
 
1484
//            case VBOXFBOVERLAY_MODIFIED:
 
1485
//            {
 
1486
//                QPaintEvent modified(rect);
 
1487
//                T::paintEvent(&modified);
 
1488
//            } break;
 
1489
//            case VBOXFBOVERLAY_UNTOUCHED:
 
1490
//                T::paintEvent(pe);
 
1491
//                break;
 
1492
//            default:
 
1493
//                break;
 
1494
//        }
 
1495
//    }
 
1496
 
 
1497
    void resizeEvent (VBoxResizeEvent *re)
 
1498
    {
 
1499
        mOverlay.onResizeEvent(re);
 
1500
        T::resizeEvent(re);
 
1501
        mOverlay.onResizeEventPostprocess(re);
 
1502
    }
 
1503
 
 
1504
    void viewportResized(QResizeEvent * re)
 
1505
    {
 
1506
        mOverlay.onViewportResized(re);
 
1507
        T::viewportResized(re);
 
1508
    }
 
1509
 
 
1510
    void viewportScrolled(int dx, int dy)
 
1511
    {
 
1512
        mOverlay.onViewportScrolled(dx, dy);
 
1513
        T::viewportScrolled(dx, dy);
 
1514
    }
 
1515
private:
 
1516
    VBoxQGLOverlay mOverlay;
 
1517
};
 
1518
 
 
1519
#endif
 
1520
 
 
1521
#endif /* #ifndef __VBoxFBOverlay_h__ */