src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -68,9 +68,11 @@
     };
 
     enum CompositionModeStatus {
-        PorterDuff_None = 0x0,
-        PorterDuff_SupportedBlits = 0x1,
-        PorterDuff_SupportedPrimitives = 0x2
+        PorterDuff_None = 0x00,
+        PorterDuff_SupportedBlits = 0x01,
+        PorterDuff_SupportedPrimitives = 0x02,
+        PorterDuff_SupportedOpaquePrimitives = 0x04,
+        PorterDuff_Dirty = 0x10
     };
 
     enum ClipType {
@@ -95,6 +97,7 @@
     inline void unlock();
     static inline void unlock(QDirectFBPaintDevice *device);
 
+    inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const;
     inline bool isSimpleBrush(const QBrush &brush) const;
 
     void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos);
@@ -404,11 +407,11 @@
     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
         return;
 
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-        || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+    if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
         || !d->simplePen
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
-        || !d->isSimpleBrush(brush)) {
+        || !d->isSimpleBrush(brush)
+        || !d->testCompositionMode(&pen, &brush)) {
         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
         d->lock();
         QRasterPaintEngine::drawRects(rects, rectCount);
@@ -434,11 +437,11 @@
     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
         return;
 
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-        || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+    if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
         || !d->simplePen
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
-        || !d->isSimpleBrush(brush)) {
+        || !d->isSimpleBrush(brush)
+        || !d->testCompositionMode(&pen, &brush)) {
         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
         d->lock();
         QRasterPaintEngine::drawRects(rects, rectCount);
@@ -460,16 +463,16 @@
 {
     Q_D(QDirectFBPaintEngine);
 
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-        || !d->simplePen
-        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+    const QPen &pen = state()->pen;
+    if (!d->simplePen
+        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+        || !d->testCompositionMode(&pen, 0)) {
         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
         d->lock();
         QRasterPaintEngine::drawLines(lines, lineCount);
         return;
     }
 
-    const QPen &pen = state()->pen;
     if (pen.style() != Qt::NoPen) {
         d->setDFBColor(pen.color());
         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
@@ -480,16 +483,16 @@
 {
     Q_D(QDirectFBPaintEngine);
 
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-        || !d->simplePen
-        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+    const QPen &pen = state()->pen;
+    if (!d->simplePen
+        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+        || !d->testCompositionMode(&pen, 0)) {
         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
         d->lock();
         QRasterPaintEngine::drawLines(lines, lineCount);
         return;
     }
 
-    const QPen &pen = state()->pen;
     if (pen.style() != Qt::NoPen) {
         d->setDFBColor(pen.color());
         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
@@ -714,8 +717,8 @@
     if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
         switch (brush.style()) {
         case Qt::SolidPattern: {
-            if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-                || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)) {
+            if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
+                || !d->testCompositionMode(0, &brush)) {
                 break;
             }
             const QColor color = brush.color();
@@ -753,9 +756,9 @@
     if (!color.isValid())
         return;
     Q_D(QDirectFBPaintEngine);
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
-        || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
-        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+    if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+        || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+        || !d->testCompositionMode(0, 0, &color)) {
         RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
         d->lock();
         QRasterPaintEngine::fillRect(rect, color);
@@ -815,6 +818,36 @@
     return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
 }
 
+bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const
+{
+    Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine);
+    Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern);
+    switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives
+                                     |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) {
+    case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives:
+        return true;
+    case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives:
+        if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255)
+            return false;
+        if (brush) {
+            if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) {
+                return false;
+            }
+        } else if (color && color->alpha() != 255) {
+            return false;
+        }
+        return true;
+    case QDirectFBPaintEnginePrivate::PorterDuff_None:
+        return false;
+    default:
+        // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined
+        break;
+    }
+    Q_ASSERT(0);
+    return false;
+}
+
+
 void QDirectFBPaintEnginePrivate::lock()
 {
     // We will potentially get a new pointer to the buffer after a
@@ -888,6 +921,7 @@
         break;
     case QPainter::CompositionMode_Source:
         surface->SetPorterDuff(surface, DSPD_SRC);
+        compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives;
         break;
     case QPainter::CompositionMode_SourceOver:
         compositionModeStatus |= PorterDuff_SupportedPrimitives;
@@ -945,6 +979,9 @@
     }
     surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
     surface->SetBlittingFlags(surface, blittingFlags);
+    if (compositionModeStatus & PorterDuff_Dirty) {
+        setCompositionMode(q->state()->composition_mode);
+    }
 }
 
 static inline uint ALPHA_MUL(uint x, uint a)
@@ -962,6 +999,7 @@
     surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
     surface->SetPorterDuff(surface, DSPD_NONE);
     surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
+    compositionModeStatus |= PorterDuff_Dirty;
 }
 
 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)