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 |