Ignore:
Timestamp:
Aug 2, 2010, 9:27:30 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp

    r651 r769  
    6969
    7070    enum CompositionModeStatus {
    71         PorterDuff_None = 0x00,
    72         PorterDuff_SupportedBlits = 0x01,
    73         PorterDuff_SupportedPrimitives = 0x02,
    74         PorterDuff_SupportedOpaquePrimitives = 0x04,
    75         PorterDuff_Dirty = 0x10
     71        PorterDuff_None = 0x0,
     72        PorterDuff_Supported = 0x1,
     73        PorterDuff_PremultiplyColors = 0x2,
     74        PorterDuff_AlwaysBlend = 0x4
    7675    };
    7776
     
    9897    static inline void unlock(QDirectFBPaintDevice *device);
    9998
    100     inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const;
    10199    inline bool isSimpleBrush(const QBrush &brush) const;
    102100
     
    131129    QDirectFBPaintDevice *dfbDevice;
    132130    uint compositionModeStatus;
     131    bool isPremultiplied;
    133132
    134133    bool inClip;
     
    169168#endif
    170169
    171 #if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
     170#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS || defined QT_DEBUG
    172171#define VOID_ARG() static_cast<bool>(false)
    173172enum PaintOperation {
     
    179178    ALL = 0xffff
    180179};
    181 #endif
    182 
     180
     181#ifdef QT_DEBUG
     182static void initRasterFallbacksMasks(int *warningMask, int *disableMask)
     183{
     184    struct {
     185        const char *name;
     186        PaintOperation operation;
     187    } const operations[] = {
     188        { "DRAW_RECTS", DRAW_RECTS },
     189        { "DRAW_LINES", DRAW_LINES },
     190        { "DRAW_IMAGE", DRAW_IMAGE },
     191        { "DRAW_PIXMAP", DRAW_PIXMAP },
     192        { "DRAW_TILED_PIXMAP", DRAW_TILED_PIXMAP },
     193        { "STROKE_PATH", STROKE_PATH },
     194        { "DRAW_PATH", DRAW_PATH },
     195        { "DRAW_POINTS", DRAW_POINTS },
     196        { "DRAW_ELLIPSE", DRAW_ELLIPSE },
     197        { "DRAW_POLYGON", DRAW_POLYGON },
     198        { "DRAW_TEXT", DRAW_TEXT },
     199        { "FILL_PATH", FILL_PATH },
     200        { "FILL_RECT", FILL_RECT },
     201        { "DRAW_COLORSPANS", DRAW_COLORSPANS },
     202        { "DRAW_ROUNDED_RECT", DRAW_ROUNDED_RECT },
     203        { "ALL", ALL },
     204        { 0, ALL }
     205    };
     206
     207    QStringList warning = QString::fromLatin1(qgetenv("QT_DIRECTFB_WARN_ON_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
     208                                                                                                              QString::SkipEmptyParts);
     209    QStringList disable = QString::fromLatin1(qgetenv("QT_DIRECTFB_DISABLE_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
     210                                                                                                              QString::SkipEmptyParts);
     211    *warningMask = 0;
     212    *disableMask = 0;
     213    if (!warning.isEmpty() || !disable.isEmpty()) {
     214        for (int i=0; operations[i].name; ++i) {
     215            const QString name = QString::fromLatin1(operations[i].name);
     216            int idx = warning.indexOf(name);
     217            if (idx != -1) {
     218                *warningMask |= operations[i].operation;
     219                warning.erase(warning.begin() + idx);
     220            }
     221            idx = disable.indexOf(name);
     222            if (idx != -1) {
     223                *disableMask |= operations[i].operation;
     224                disable.erase(disable.begin() + idx);
     225            }
     226        }
     227    }
     228    if (!warning.isEmpty()) {
     229        qWarning("QDirectFBPaintEngine QT_DIRECTFB_WARN_ON_RASTERFALLBACKS Unknown operation(s): %s",
     230                 qPrintable(warning.join(QLatin1String("|"))));
     231    }
     232    if (!disable.isEmpty()) {
     233        qWarning("QDirectFBPaintEngine QT_DIRECTFB_DISABLE_RASTERFALLBACKS Unknown operation(s): %s",
     234                 qPrintable(disable.join(QLatin1String("|"))));
     235    }
     236
     237}
     238#endif
     239
     240static inline int rasterFallbacksMask(bool warn)
     241{
    183242#ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
     243    if (warn)
     244        return QT_DIRECTFB_WARN_ON_RASTERFALLBACKS;
     245#endif
     246#ifdef QT_DIRECTFB_DISABLE_RASTERFALLBACKS
     247    if (!warn)
     248        return QT_DIRECTFB_DISABLE_RASTERFALLBACKS;
     249#endif
     250#ifndef QT_DEBUG
     251    return 0;
     252#else
     253    static int warnMask = -1;
     254    static int disableMask = -1;
     255    if (warnMask == -1)
     256        initRasterFallbacksMasks(&warnMask, &disableMask);
     257    return warn ? warnMask : disableMask;
     258#endif
     259}
     260#endif
     261
     262#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DEBUG
    184263template <typename device, typename T1, typename T2, typename T3>
    185264static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
     
    191270#endif
    192271
    193 #if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
     272#if defined QT_DEBUG || (defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS)
    194273#define RASTERFALLBACK(op, one, two, three)                             \
    195     if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS))                     \
    196         rasterFallbackWarn("Disabled raster engine operation",          \
    197                            __FUNCTION__, state()->painter->device(),    \
    198                            d_func()->transformationType,                \
    199                            d_func()->simplePen,                         \
    200                            d_func()->clipType,                          \
    201                            d_func()->compositionModeStatus,             \
    202                            #one, one, #two, two, #three, three);        \
    203     if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS))                     \
    204         return;
     274    {                                                                   \
     275        const bool disable = op & rasterFallbacksMask(false);           \
     276        if (op & rasterFallbacksMask(true))                             \
     277            rasterFallbackWarn(disable                                  \
     278                               ? "Disabled raster engine operation"     \
     279                               : "Falling back to raster engine for",   \
     280                               __FUNCTION__,                            \
     281                               state()->painter->device(),              \
     282                               d_func()->transformationType,            \
     283                               d_func()->simplePen,                     \
     284                               d_func()->clipType,                      \
     285                               d_func()->compositionModeStatus,         \
     286                               #one, one, #two, two, #three, three);    \
     287        if (disable)                                                    \
     288            return;                                                     \
     289    }
    205290#elif defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
    206 #define RASTERFALLBACK(op, one, two, three)             \
    207     if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS))     \
     291#define RASTERFALLBACK(op, one, two, three)                             \
     292    if (op & rasterFallbacksMask(false))                                \
    208293        return;
    209294#elif defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
    210295#define RASTERFALLBACK(op, one, two, three)                             \
    211     if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS))                     \
     296    if (op & rasterFallbacksMask(true))                                 \
    212297        rasterFallbackWarn("Falling back to raster engine for",         \
    213298                           __FUNCTION__, state()->painter->device(),    \
     
    288373               device->devType());
    289374    }
     375    d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format());
    290376
    291377    d->prepare(d->dfbDevice);
     
    414500        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
    415501        || !d->isSimpleBrush(brush)
    416         || !d->testCompositionMode(&pen, &brush)) {
     502        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
    417503        RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
    418504        d->lock();
     
    444530        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
    445531        || !d->isSimpleBrush(brush)
    446         || !d->testCompositionMode(&pen, &brush)) {
     532        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
    447533        RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
    448534        d->lock();
     
    469555    if (!d->simplePen
    470556        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
    471         || !d->testCompositionMode(&pen, 0)) {
     557        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
    472558        RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
    473559        d->lock();
     
    489575    if (!d->simplePen
    490576        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
    491         || !d->testCompositionMode(&pen, 0)) {
     577        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
    492578        RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
    493579        d->lock();
     
    527613
    528614#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
    529     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
     615    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
    530616        || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
    531617        || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
     
    576662        Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
    577663        QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
    578         if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
     664        if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
    579665            || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
    580666            || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
     
    607693        d->lock();
    608694        QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
    609     } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
     695    } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
    610696               || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
    611697               || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
     
    720806        switch (brush.style()) {
    721807        case Qt::SolidPattern: {
    722             if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
    723                 || !d->testCompositionMode(0, &brush)) {
    724                 break;
    725             }
    726808            const QColor color = brush.color();
    727809            if (!color.isValid())
    728810                return;
     811
     812            if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
     813                || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
     814                break;
     815            }
    729816            d->setDFBColor(color);
    730817            const QRect r = state()->matrix.mapRect(rect).toRect();
     
    733820
    734821        case Qt::TexturePattern: {
    735             if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
     822            if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
    736823                || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
    737824                || (!d->supportsStretchBlit() && state()->matrix.isScaling())) {
     
    761848    if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
    762849        || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
    763         || !d->testCompositionMode(0, 0, &color)) {
     850        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
    764851        RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
    765852        d->lock();
     
    805892      transformationType(0), opacity(255),
    806893      clipType(ClipUnset), dfbDevice(0),
    807       compositionModeStatus(0), inClip(false), q(p)
     894      compositionModeStatus(0), isPremultiplied(false), inClip(false), q(p)
    808895{
    809896    fb = QDirectFBScreen::instance()->dfb();
     
    820907    return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
    821908}
    822 
    823 bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const
    824 {
    825     Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine);
    826     Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern);
    827     switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives
    828                                      |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) {
    829     case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives:
    830         return true;
    831     case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives:
    832         if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255)
    833             return false;
    834         if (brush) {
    835             if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) {
    836                 return false;
    837             }
    838         } else if (color && color->alpha() != 255) {
    839             return false;
    840         }
    841         return true;
    842     case QDirectFBPaintEnginePrivate::PorterDuff_None:
    843         return false;
    844     default:
    845         // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined
    846         break;
    847     }
    848     Q_ASSERT(0);
    849     return false;
    850 }
    851 
    852909
    853910void QDirectFBPaintEnginePrivate::lock()
     
    913970    static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0;
    914971    if (forceRasterFallBack) {
    915         compositionModeStatus = 0;
     972        compositionModeStatus = PorterDuff_None;
    916973        return;
    917974    }
    918975
    919     compositionModeStatus = PorterDuff_SupportedBlits;
     976    compositionModeStatus = PorterDuff_Supported|PorterDuff_PremultiplyColors|PorterDuff_AlwaysBlend;
    920977    switch (mode) {
    921978    case QPainter::CompositionMode_Clear:
     
    924981    case QPainter::CompositionMode_Source:
    925982        surface->SetPorterDuff(surface, DSPD_SRC);
    926         compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives;
     983        compositionModeStatus &= ~PorterDuff_AlwaysBlend;
     984        if (!isPremultiplied)
     985            compositionModeStatus &= ~PorterDuff_PremultiplyColors;
    927986        break;
    928987    case QPainter::CompositionMode_SourceOver:
    929         compositionModeStatus |= PorterDuff_SupportedPrimitives;
     988        compositionModeStatus &= ~PorterDuff_AlwaysBlend;
    930989        surface->SetPorterDuff(surface, DSPD_SRC_OVER);
    931990        break;
     
    935994    case QPainter::CompositionMode_SourceIn:
    936995        surface->SetPorterDuff(surface, DSPD_SRC_IN);
     996        if (!isPremultiplied)
     997            compositionModeStatus &= ~PorterDuff_PremultiplyColors;
    937998        break;
    938999    case QPainter::CompositionMode_DestinationIn:
     
    9451006        surface->SetPorterDuff(surface, DSPD_DST_OUT);
    9461007        break;
     1008#if (Q_DIRECTFB_VERSION >= 0x010209)
     1009    case QPainter::CompositionMode_Destination:
     1010        surface->SetPorterDuff(surface, DSPD_DST);
     1011        break;
     1012#endif
    9471013#if (Q_DIRECTFB_VERSION >= 0x010000)
    9481014    case QPainter::CompositionMode_SourceAtop:
     
    9601026#endif
    9611027    default:
    962         compositionModeStatus = 0;
     1028        compositionModeStatus = PorterDuff_None;
    9631029        break;
    9641030    }
     
    9821048    surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
    9831049    surface->SetBlittingFlags(surface, blittingFlags);
    984     if (compositionModeStatus & PorterDuff_Dirty) {
    985         setCompositionMode(q->state()->composition_mode);
    986     }
    9871050}
    9881051
     
    9971060{
    9981061    Q_ASSERT(surface);
     1062    Q_ASSERT(compositionModeStatus & PorterDuff_Supported);
    9991063    const quint8 alpha = (opacity == 255 ?
    10001064                          color.alpha() : ALPHA_MUL(color.alpha(), opacity));
    1001     surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
    1002     surface->SetPorterDuff(surface, DSPD_NONE);
    1003     surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
    1004     compositionModeStatus |= PorterDuff_Dirty;
     1065    QColor col;
     1066    if (compositionModeStatus & PorterDuff_PremultiplyColors) {
     1067        col = QColor(ALPHA_MUL(color.red(), alpha),
     1068                     ALPHA_MUL(color.green(), alpha),
     1069                     ALPHA_MUL(color.blue(), alpha),
     1070                     alpha);
     1071    } else {
     1072        col = QColor(color.red(), color.green(), color.blue(), alpha);
     1073    }
     1074    surface->SetColor(surface, col.red(), col.green(), col.blue(), col.alpha());
     1075    surface->SetDrawingFlags(surface, alpha == 255 && !(compositionModeStatus & PorterDuff_AlwaysBlend) ? DSDRAW_NOFX : DSDRAW_BLEND);
    10051076}
    10061077
     
    12841355}
    12851356
    1286 #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
     1357#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DEBUG
    12871358template <typename T> inline const T *ptr(const T &t) { return &t; }
    12881359template <> inline const bool* ptr<bool>(const bool &) { return 0; }
Note: See TracChangeset for help on using the changeset viewer.