Changeset 712


Ignore:
Timestamp:
Apr 27, 2010, 4:15:04 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Fixed widget painting in Dive mode when the screen color format is not 32-bit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/gui/painting/qwindowsurface_pm.cpp

    r710 r712  
    4242****************************************************************************/
    4343
    44 #include "qt_os2.h"
    45 #include "qlibrary.h"
     44#include <qdebug.h>
     45
     46//#define QDIVE_DEBUG
     47
     48#if defined QDIVE_DEBUG
     49#define DEBUG(a) qDebug a
     50#define DEBUG_VAR(v) DEBUG(() << #v << v)
     51#define DEBUG_VAR_HEX(v) DEBUG(() << #v << qDebugFmtHex(v))
     52#else
     53#define DEBUG(a) do {} while(0)
     54#define DEBUG_VAR(v) do {} while(0)
     55#define DEBUG_VAR_HEX(v) do {} while(0)
     56#endif
     57
     58#include <qt_os2.h>
     59#include <qlibrary.h>
    4660
    4761#include "qwindowsurface_pm_p.h"
    4862#include "private/qnativeimage_p.h"
    49 
    50 #include "qdebug.h"
    5163
    5264////////////////////////////////////////////////////////////////////////////////
     
    7789#define DIVE_BUFFER_GRAPHICS_PLANE                       0x00000001
    7890#define DIVE_BUFFER_ALTERNATE_PLANE                      0x00000002
     91
     92typedef struct _DIVE_CAPS {
     93
     94   ULONG  ulStructLen;            /* Set equal to sizeof(DIVE_CAPS)          */
     95   ULONG  ulPlaneCount;           /* Number of defined planes.               */
     96
     97   /* Info returned in the following fields pertains to ulPlaneID.           */
     98   BOOL   fScreenDirect;          /* TRUE if can get addressability to vram. */
     99   BOOL   fBankSwitched;          /* TRUE if vram is bank-switched.          */
     100   ULONG  ulDepth;                /* Number of bits per pixel.               */
     101   ULONG  ulHorizontalResolution; /* Screen width in pixels.                 */
     102   ULONG  ulVerticalResolution;   /* Screen height in pixels.                */
     103   ULONG  ulScanLineBytes;        /* Screen scan line size in bytes.         */
     104   FOURCC fccColorEncoding;       /* Colorspace encoding of the screen.      */
     105   ULONG  ulApertureSize;         /* Size of vram aperture in bytes.         */
     106
     107   ULONG  ulInputFormats;         /* Number of input color formats.          */
     108   ULONG  ulOutputFormats;        /* Number of output color formats.         */
     109   ULONG  ulFormatLength;         /* Length of format buffer.                */
     110   PVOID  pFormatData;            /* Pointer to color format buffer FOURCC's.*/
     111
     112   } DIVE_CAPS;
     113typedef DIVE_CAPS *PDIVE_CAPS;
    79114
    80115typedef struct _SETUP_BLITTER {
     
    140175
    141176static
     177ULONG (APIENTRY *DiveQueryCaps) ( PDIVE_CAPS pDiveCaps,
     178                                  ULONG      ulPlaneBufNum ) = 0;
     179
     180static
    142181ULONG (APIENTRY *DiveOpen) ( HDIVE *phDiveInst,
    143182                             BOOL   fNonScreenInstance,
     
    186225static struct { const char *name; void **entry; } diveDllFuncs[] =
    187226{
     227    FUNC_ENTRY(DiveQueryCaps),
    188228    FUNC_ENTRY(DiveOpen),
    189229    FUNC_ENTRY(DiveSetupBlitter),
     
    200240static bool diveDllOK = false;
    201241
     242static DIVE_CAPS diveCaps = { 0 };
     243
    202244////////////////////////////////////////////////////////////////////////////////
    203245
    204246QT_BEGIN_NAMESPACE
     247
     248// Returns a directly matching QImage format for the given FOURCC (including
     249// bit order and depth, scan line size etc.) or Format_Invalid.
     250static QImage::Format fourccToFormat(FOURCC fourcc)
     251{
     252    switch (fourcc) {
     253        case FOURCC_R555: return QImage::Format_RGB555;
     254        case FOURCC_R565: return QImage::Format_RGB16;
     255        case FOURCC_RGB3: return QImage::Format_RGB888;
     256        case FOURCC_BGR4: return QImage::Format_RGB32;
     257        default: return QImage::Format_Invalid;
     258    }
     259}
     260
     261// Returns a FOURCC that is best for the buffer used to blit to the given
     262// screen FOURCC. Returns 0 (FOURC_SCRN) if there is no suitable conversion,
     263// otherwise it is guaranteed that the returned value is accepted by
     264// fourccToFormat().
     265static FOURCC fourccScreenToBuffer(FOURCC fourcc)
     266{
     267    // return it as is if supported by fourccToFormat()
     268    if (fourccToFormat(fourcc) != QImage::Format_Invalid)
     269        return fourcc;
     270
     271    // otherwise, use FOURCC_RGB3 (which in theory should always work; if not,
     272    // we will add exceptions here and return 0 in such cases). Note that
     273    // although working with 32-bit pixels would be faster, we cannot return
     274    // FOURCC_BGR4 here because DiveBlitImage() is known to crahsh when the
     275    // source buffer is BGR4 and the screen is not (at least, it's the case
     276    // with recent SNAP versions)
     277    return FOURCC_RGB3;
     278}
    205279
    206280struct QPMDiveWindowSurfacePrivate
     
    235309    memset(&d->setup, 0, sizeof(SETUP_BLITTER));
    236310
    237     // Note that DiveBlitImage() seems to ignore fccSrcColorFormat and
    238     // fccSrcColorFormat which is not a big surprise because both values are
    239     // known (the source color format is specified at buffer creation time
    240     // and the screen color format is always known). Also note that specifying
    241     // values other than FOURCC_LUT8/R565/BGR3 causes a crash in DiveBlitImage()
    242     // no matter what the actual source format is. FOURCC_SCRN seems to work.
    243     d->setup.fccSrcColorFormat = FOURCC_SCRN;
     311    // note that fccSrcColorFormat overrides the value specified during the
     312    // source buffer creation, so they must match
     313    d->setup.fccSrcColorFormat = fourccScreenToBuffer(diveCaps.fccColorEncoding);
    244314    d->setup.fccDstColorFormat = FOURCC_SCRN;
    245315
     
    296366void QPMDiveWindowSurface::doFlush(const QRect &from, const QPoint &to)
    297367{
    298 #if 0
    299     qDebug() << "QPMDiveWindowSurface::doFlush:" << window()
    300              << "from" << from << "to" << to;
    301 #endif
     368    DEBUG(() << "QPMDiveWindowSurface::doFlush:" << window()
     369             << "from" << from << "to" << to);
    302370
    303371    // make sure from doesn't exceed the backing storage size (it may happen
     
    320388        d->setup.lScreenPosY = ptl.y;
    321389        d->setup.ulStructLen = offsetof(SETUP_BLITTER, ulNumDstRects);
     390
     391        DEBUG(() << "QPMDiveWindowSurface::doFlush:" << "posDirty"
     392                 << ptl.x << ptl.y);
    322393    }
    323394
     
    353424        GpiDestroyRegion(hps, hrgn);
    354425        window()->releasePS(hps);
     426
     427#if defined(QDIVE_DEBUG)
     428        DEBUG(() << "QPMDiveWindowSurface::doFlush:" << "vrnDirty");
     429        for (size_t i = 0; i < d->setup.ulNumDstRects; ++i)
     430            DEBUG(() << " " << i << ":" << d->setup.pVisDstRects[i]);
     431#endif
    355432    }
    356433
     
    441518        QImage *oldImage = d->image;
    442519
    443         d->image = new QImage(width, height, QImage::Format_RGB32);
     520        QImage::Format format = fourccToFormat(d->setup.fccSrcColorFormat);
     521        Q_ASSERT(format != QImage::Format_Invalid);
     522        d->image = new QImage(width, height, format);
    444523
    445524        // associate the image data pointer with the buffer number
    446525        DiveFreeImageBuffer(d->hDive, d->bufNum);
    447526        d->bufNum = 0;
    448         ULONG rc = DiveAllocImageBuffer(d->hDive, &d->bufNum, FOURCC_BGR4,
     527        ULONG rc = DiveAllocImageBuffer(d->hDive, &d->bufNum,
     528                                        d->setup.fccSrcColorFormat,
    449529                                        width, height,
    450530                                        d->image->bytesPerLine(),
    451531                                        (PBYTE)const_cast<const QImage *>(d->image)->bits());
    452 
    453532        if (rc != DIVE_SUCCESS) {
    454533            qWarning("QPMDiveWindowSurface::setGeometry: DiveAllocImageBuffer "
     
    528607            }
    529608        }
     609
     610        if (diveDllOK) {
     611            diveCaps.ulStructLen = sizeof(diveCaps);
     612            DiveQueryCaps(&diveCaps, DIVE_BUFFER_SCREEN);
     613
     614            DEBUG_VAR(diveCaps.fScreenDirect);
     615            DEBUG_VAR(diveCaps.fBankSwitched);
     616            DEBUG_VAR(diveCaps.ulDepth);
     617            DEBUG_VAR(diveCaps.ulHorizontalResolution);
     618            DEBUG_VAR(diveCaps.ulVerticalResolution);
     619            DEBUG_VAR(diveCaps.ulScanLineBytes);
     620            DEBUG(() << "diveCaps.fccColorEncoding"
     621                     << ((char*)&diveCaps.fccColorEncoding)[0]
     622                     << ((char*)&diveCaps.fccColorEncoding)[1]
     623                     << ((char*)&diveCaps.fccColorEncoding)[2]
     624                     << ((char*)&diveCaps.fccColorEncoding)[3]);
     625
     626            FOURCC bestBufFormat = fourccScreenToBuffer(diveCaps.fccColorEncoding);
     627            DEBUG(() << "bestBufFormat"
     628                     << ((char*)&bestBufFormat)[0]
     629                     << ((char*)&bestBufFormat)[1]
     630                     << ((char*)&bestBufFormat)[2]
     631                     << ((char*)&bestBufFormat)[3]);
     632
     633            if (bestBufFormat == 0) {
     634                // there is no working pixel format for the buffer for
     635                // DiveBlitImage() to work correctly with the current screen
     636                // format, give up
     637                diveDllOK = false;
     638            }
     639        }
     640
     641        DEBUG_VAR(diveDllOK);
    530642    }
    531643
Note: See TracChangeset for help on using the changeset viewer.