src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    66         Matrix_RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject),
    66         Matrix_RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject),
    67         Matrix_BlitsUnsupported = (Matrix_NegativeScale|Matrix_RectsUnsupported)
    67         Matrix_BlitsUnsupported = (Matrix_NegativeScale|Matrix_RectsUnsupported)
    68     };
    68     };
    69 
    69 
    70     enum CompositionModeStatus {
    70     enum CompositionModeStatus {
    71         PorterDuff_None = 0x0,
    71         PorterDuff_None = 0x00,
    72         PorterDuff_SupportedBlits = 0x1,
    72         PorterDuff_SupportedBlits = 0x01,
    73         PorterDuff_SupportedPrimitives = 0x2
    73         PorterDuff_SupportedPrimitives = 0x02,
       
    74         PorterDuff_SupportedOpaquePrimitives = 0x04,
       
    75         PorterDuff_Dirty = 0x10
    74     };
    76     };
    75 
    77 
    76     enum ClipType {
    78     enum ClipType {
    77         ClipUnset,
    79         ClipUnset,
    78         NoClip,
    80         NoClip,
    93 
    95 
    94     inline void lock();
    96     inline void lock();
    95     inline void unlock();
    97     inline void unlock();
    96     static inline void unlock(QDirectFBPaintDevice *device);
    98     static inline void unlock(QDirectFBPaintDevice *device);
    97 
    99 
       
   100     inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const;
    98     inline bool isSimpleBrush(const QBrush &brush) const;
   101     inline bool isSimpleBrush(const QBrush &brush) const;
    99 
   102 
   100     void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos);
   103     void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos);
   101     void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
   104     void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
   102 
   105 
   402     const QPen &pen = state()->pen;
   405     const QPen &pen = state()->pen;
   403     const QBrush &brush = state()->brush;
   406     const QBrush &brush = state()->brush;
   404     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
   407     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
   405         return;
   408         return;
   406 
   409 
   407     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   410     if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
   408         || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
       
   409         || !d->simplePen
   411         || !d->simplePen
   410         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
   412         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
   411         || !d->isSimpleBrush(brush)) {
   413         || !d->isSimpleBrush(brush)
       
   414         || !d->testCompositionMode(&pen, &brush)) {
   412         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
   415         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
   413         d->lock();
   416         d->lock();
   414         QRasterPaintEngine::drawRects(rects, rectCount);
   417         QRasterPaintEngine::drawRects(rects, rectCount);
   415         return;
   418         return;
   416     }
   419     }
   432     const QPen &pen = state()->pen;
   435     const QPen &pen = state()->pen;
   433     const QBrush &brush = state()->brush;
   436     const QBrush &brush = state()->brush;
   434     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
   437     if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
   435         return;
   438         return;
   436 
   439 
   437     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   440     if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
   438         || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
       
   439         || !d->simplePen
   441         || !d->simplePen
   440         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
   442         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
   441         || !d->isSimpleBrush(brush)) {
   443         || !d->isSimpleBrush(brush)
       
   444         || !d->testCompositionMode(&pen, &brush)) {
   442         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
   445         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
   443         d->lock();
   446         d->lock();
   444         QRasterPaintEngine::drawRects(rects, rectCount);
   447         QRasterPaintEngine::drawRects(rects, rectCount);
   445         return;
   448         return;
   446     }
   449     }
   458 
   461 
   459 void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
   462 void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
   460 {
   463 {
   461     Q_D(QDirectFBPaintEngine);
   464     Q_D(QDirectFBPaintEngine);
   462 
   465 
   463     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   466     const QPen &pen = state()->pen;
   464         || !d->simplePen
   467     if (!d->simplePen
   465         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
   468         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
       
   469         || !d->testCompositionMode(&pen, 0)) {
   466         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
   470         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
   467         d->lock();
   471         d->lock();
   468         QRasterPaintEngine::drawLines(lines, lineCount);
   472         QRasterPaintEngine::drawLines(lines, lineCount);
   469         return;
   473         return;
   470     }
   474     }
   471 
   475 
   472     const QPen &pen = state()->pen;
       
   473     if (pen.style() != Qt::NoPen) {
   476     if (pen.style() != Qt::NoPen) {
   474         d->setDFBColor(pen.color());
   477         d->setDFBColor(pen.color());
   475         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
   478         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
   476     }
   479     }
   477 }
   480 }
   478 
   481 
   479 void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
   482 void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
   480 {
   483 {
   481     Q_D(QDirectFBPaintEngine);
   484     Q_D(QDirectFBPaintEngine);
   482 
   485 
   483     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   486     const QPen &pen = state()->pen;
   484         || !d->simplePen
   487     if (!d->simplePen
   485         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
   488         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
       
   489         || !d->testCompositionMode(&pen, 0)) {
   486         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
   490         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
   487         d->lock();
   491         d->lock();
   488         QRasterPaintEngine::drawLines(lines, lineCount);
   492         QRasterPaintEngine::drawLines(lines, lineCount);
   489         return;
   493         return;
   490     }
   494     }
   491 
   495 
   492     const QPen &pen = state()->pen;
       
   493     if (pen.style() != Qt::NoPen) {
   496     if (pen.style() != Qt::NoPen) {
   494         d->setDFBColor(pen.color());
   497         d->setDFBColor(pen.color());
   495         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
   498         CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
   496     }
   499     }
   497 }
   500 }
   712     if (brush.style() == Qt::NoBrush)
   715     if (brush.style() == Qt::NoBrush)
   713         return;
   716         return;
   714     if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
   717     if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
   715         switch (brush.style()) {
   718         switch (brush.style()) {
   716         case Qt::SolidPattern: {
   719         case Qt::SolidPattern: {
   717             if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   720             if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
   718                 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)) {
   721                 || !d->testCompositionMode(0, &brush)) {
   719                 break;
   722                 break;
   720             }
   723             }
   721             const QColor color = brush.color();
   724             const QColor color = brush.color();
   722             if (!color.isValid())
   725             if (!color.isValid())
   723                 return;
   726                 return;
   751 void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
   754 void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
   752 {
   755 {
   753     if (!color.isValid())
   756     if (!color.isValid())
   754         return;
   757         return;
   755     Q_D(QDirectFBPaintEngine);
   758     Q_D(QDirectFBPaintEngine);
   756     if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
   759     if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
   757         || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
   760         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
   758         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
   761         || !d->testCompositionMode(0, 0, &color)) {
   759         RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
   762         RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
   760         d->lock();
   763         d->lock();
   761         QRasterPaintEngine::fillRect(rect, color);
   764         QRasterPaintEngine::fillRect(rect, color);
   762     } else {
   765     } else {
   763         d->setDFBColor(color);
   766         d->setDFBColor(color);
   812 
   815 
   813 bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const
   816 bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const
   814 {
   817 {
   815     return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
   818     return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
   816 }
   819 }
       
   820 
       
   821 bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const
       
   822 {
       
   823     Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine);
       
   824     Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern);
       
   825     switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives
       
   826                                      |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) {
       
   827     case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives:
       
   828         return true;
       
   829     case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives:
       
   830         if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255)
       
   831             return false;
       
   832         if (brush) {
       
   833             if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) {
       
   834                 return false;
       
   835             }
       
   836         } else if (color && color->alpha() != 255) {
       
   837             return false;
       
   838         }
       
   839         return true;
       
   840     case QDirectFBPaintEnginePrivate::PorterDuff_None:
       
   841         return false;
       
   842     default:
       
   843         // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined
       
   844         break;
       
   845     }
       
   846     Q_ASSERT(0);
       
   847     return false;
       
   848 }
       
   849 
   817 
   850 
   818 void QDirectFBPaintEnginePrivate::lock()
   851 void QDirectFBPaintEnginePrivate::lock()
   819 {
   852 {
   820     // We will potentially get a new pointer to the buffer after a
   853     // We will potentially get a new pointer to the buffer after a
   821     // lock so we need to call the base implementation of prepare so
   854     // lock so we need to call the base implementation of prepare so
   886     case QPainter::CompositionMode_Clear:
   919     case QPainter::CompositionMode_Clear:
   887         surface->SetPorterDuff(surface, DSPD_CLEAR);
   920         surface->SetPorterDuff(surface, DSPD_CLEAR);
   888         break;
   921         break;
   889     case QPainter::CompositionMode_Source:
   922     case QPainter::CompositionMode_Source:
   890         surface->SetPorterDuff(surface, DSPD_SRC);
   923         surface->SetPorterDuff(surface, DSPD_SRC);
       
   924         compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives;
   891         break;
   925         break;
   892     case QPainter::CompositionMode_SourceOver:
   926     case QPainter::CompositionMode_SourceOver:
   893         compositionModeStatus |= PorterDuff_SupportedPrimitives;
   927         compositionModeStatus |= PorterDuff_SupportedPrimitives;
   894         surface->SetPorterDuff(surface, DSPD_SRC_OVER);
   928         surface->SetPorterDuff(surface, DSPD_SRC_OVER);
   895         break;
   929         break;
   943     if (opacity != 255) {
   977     if (opacity != 255) {
   944         blittingFlags |= DSBLIT_BLEND_COLORALPHA;
   978         blittingFlags |= DSBLIT_BLEND_COLORALPHA;
   945     }
   979     }
   946     surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
   980     surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
   947     surface->SetBlittingFlags(surface, blittingFlags);
   981     surface->SetBlittingFlags(surface, blittingFlags);
       
   982     if (compositionModeStatus & PorterDuff_Dirty) {
       
   983         setCompositionMode(q->state()->composition_mode);
       
   984     }
   948 }
   985 }
   949 
   986 
   950 static inline uint ALPHA_MUL(uint x, uint a)
   987 static inline uint ALPHA_MUL(uint x, uint a)
   951 {
   988 {
   952     uint t = x * a;
   989     uint t = x * a;
   960     const quint8 alpha = (opacity == 255 ?
   997     const quint8 alpha = (opacity == 255 ?
   961                           color.alpha() : ALPHA_MUL(color.alpha(), opacity));
   998                           color.alpha() : ALPHA_MUL(color.alpha(), opacity));
   962     surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
   999     surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
   963     surface->SetPorterDuff(surface, DSPD_NONE);
  1000     surface->SetPorterDuff(surface, DSPD_NONE);
   964     surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
  1001     surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
       
  1002     compositionModeStatus |= PorterDuff_Dirty;
   965 }
  1003 }
   966 
  1004 
   967 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)
  1005 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)
   968 {
  1006 {
   969 #ifdef QT_NO_DIRECTFB_IMAGECACHE
  1007 #ifdef QT_NO_DIRECTFB_IMAGECACHE