changeset 19 | fcece45ef507 |
parent 18 | 2f34d5167611 |
child 30 | 5dc02b23752f |
18:2f34d5167611 | 19:fcece45ef507 |
---|---|
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 = 0x00, |
71 PorterDuff_None = 0x0, |
72 PorterDuff_SupportedBlits = 0x01, |
72 PorterDuff_Supported = 0x1, |
73 PorterDuff_SupportedPrimitives = 0x02, |
73 PorterDuff_PremultiplyColors = 0x2, |
74 PorterDuff_SupportedOpaquePrimitives = 0x04, |
74 PorterDuff_AlwaysBlend = 0x4 |
75 PorterDuff_Dirty = 0x10 |
|
76 }; |
75 }; |
77 |
76 |
78 enum ClipType { |
77 enum ClipType { |
79 ClipUnset, |
78 ClipUnset, |
80 NoClip, |
79 NoClip, |
95 |
94 |
96 inline void lock(); |
95 inline void lock(); |
97 inline void unlock(); |
96 inline void unlock(); |
98 static inline void unlock(QDirectFBPaintDevice *device); |
97 static inline void unlock(QDirectFBPaintDevice *device); |
99 |
98 |
100 inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const; |
|
101 inline bool isSimpleBrush(const QBrush &brush) const; |
99 inline bool isSimpleBrush(const QBrush &brush) const; |
102 |
100 |
103 void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); |
101 void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); |
104 void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src); |
102 void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src); |
105 |
103 |
128 quint8 opacity; |
126 quint8 opacity; |
129 |
127 |
130 ClipType clipType; |
128 ClipType clipType; |
131 QDirectFBPaintDevice *dfbDevice; |
129 QDirectFBPaintDevice *dfbDevice; |
132 uint compositionModeStatus; |
130 uint compositionModeStatus; |
131 bool isPremultiplied; |
|
133 |
132 |
134 bool inClip; |
133 bool inClip; |
135 QRect currentClip; |
134 QRect currentClip; |
136 |
135 |
137 QDirectFBPaintEngine *q; |
136 QDirectFBPaintEngine *q; |
166 } |
165 } |
167 }; |
166 }; |
168 static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB |
167 static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB |
169 #endif |
168 #endif |
170 |
169 |
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 |
172 #define VOID_ARG() static_cast<bool>(false) |
171 #define VOID_ARG() static_cast<bool>(false) |
173 enum PaintOperation { |
172 enum PaintOperation { |
174 DRAW_RECTS = 0x0001, DRAW_LINES = 0x0002, DRAW_IMAGE = 0x0004, |
173 DRAW_RECTS = 0x0001, DRAW_LINES = 0x0002, DRAW_IMAGE = 0x0004, |
175 DRAW_PIXMAP = 0x0008, DRAW_TILED_PIXMAP = 0x0010, STROKE_PATH = 0x0020, |
174 DRAW_PIXMAP = 0x0008, DRAW_TILED_PIXMAP = 0x0010, STROKE_PATH = 0x0020, |
176 DRAW_PATH = 0x0040, DRAW_POINTS = 0x0080, DRAW_ELLIPSE = 0x0100, |
175 DRAW_PATH = 0x0040, DRAW_POINTS = 0x0080, DRAW_ELLIPSE = 0x0100, |
177 DRAW_POLYGON = 0x0200, DRAW_TEXT = 0x0400, FILL_PATH = 0x0800, |
176 DRAW_POLYGON = 0x0200, DRAW_TEXT = 0x0400, FILL_PATH = 0x0800, |
178 FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, DRAW_ROUNDED_RECT = 0x4000, |
177 FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, DRAW_ROUNDED_RECT = 0x4000, |
179 ALL = 0xffff |
178 ALL = 0xffff |
180 }; |
179 }; |
181 #endif |
180 |
182 |
181 #ifdef QT_DEBUG |
182 static 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 |
|
240 static inline int rasterFallbacksMask(bool warn) |
|
241 { |
|
183 #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS |
242 #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 |
|
184 template <typename device, typename T1, typename T2, typename T3> |
263 template <typename device, typename T1, typename T2, typename T3> |
185 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, |
264 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, |
186 uint transformationType, bool simplePen, |
265 uint transformationType, bool simplePen, |
187 uint clipType, uint compositionModeStatus, |
266 uint clipType, uint compositionModeStatus, |
188 const char *nameOne, const T1 &one, |
267 const char *nameOne, const T1 &one, |
189 const char *nameTwo, const T2 &two, |
268 const char *nameTwo, const T2 &two, |
190 const char *nameThree, const T3 &three); |
269 const char *nameThree, const T3 &three); |
191 #endif |
270 #endif |
192 |
271 |
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) |
194 #define RASTERFALLBACK(op, one, two, three) \ |
273 #define RASTERFALLBACK(op, one, two, three) \ |
195 if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ |
274 { \ |
196 rasterFallbackWarn("Disabled raster engine operation", \ |
275 const bool disable = op & rasterFallbacksMask(false); \ |
197 __FUNCTION__, state()->painter->device(), \ |
276 if (op & rasterFallbacksMask(true)) \ |
198 d_func()->transformationType, \ |
277 rasterFallbackWarn(disable \ |
199 d_func()->simplePen, \ |
278 ? "Disabled raster engine operation" \ |
200 d_func()->clipType, \ |
279 : "Falling back to raster engine for", \ |
201 d_func()->compositionModeStatus, \ |
280 __FUNCTION__, \ |
202 #one, one, #two, two, #three, three); \ |
281 state()->painter->device(), \ |
203 if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ |
282 d_func()->transformationType, \ |
204 return; |
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 } |
|
205 #elif defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS |
290 #elif defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS |
206 #define RASTERFALLBACK(op, one, two, three) \ |
291 #define RASTERFALLBACK(op, one, two, three) \ |
207 if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ |
292 if (op & rasterFallbacksMask(false)) \ |
208 return; |
293 return; |
209 #elif defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS |
294 #elif defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS |
210 #define RASTERFALLBACK(op, one, two, three) \ |
295 #define RASTERFALLBACK(op, one, two, three) \ |
211 if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ |
296 if (op & rasterFallbacksMask(true)) \ |
212 rasterFallbackWarn("Falling back to raster engine for", \ |
297 rasterFallbackWarn("Falling back to raster engine for", \ |
213 __FUNCTION__, state()->painter->device(), \ |
298 __FUNCTION__, state()->painter->device(), \ |
214 d_func()->transformationType, \ |
299 d_func()->transformationType, \ |
215 d_func()->simplePen, \ |
300 d_func()->simplePen, \ |
216 d_func()->clipType, \ |
301 d_func()->clipType, \ |
285 |
370 |
286 if (!d->surface) { |
371 if (!d->surface) { |
287 qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", |
372 qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", |
288 device->devType()); |
373 device->devType()); |
289 } |
374 } |
375 d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format()); |
|
290 |
376 |
291 d->prepare(d->dfbDevice); |
377 d->prepare(d->dfbDevice); |
292 gccaps = AllFeatures; |
378 gccaps = AllFeatures; |
293 d->setCompositionMode(state()->composition_mode); |
379 d->setCompositionMode(state()->composition_mode); |
294 |
380 |
411 |
497 |
412 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
498 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
413 || !d->simplePen |
499 || !d->simplePen |
414 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
500 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
415 || !d->isSimpleBrush(brush) |
501 || !d->isSimpleBrush(brush) |
416 || !d->testCompositionMode(&pen, &brush)) { |
502 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
417 RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); |
503 RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); |
418 d->lock(); |
504 d->lock(); |
419 QRasterPaintEngine::drawRects(rects, rectCount); |
505 QRasterPaintEngine::drawRects(rects, rectCount); |
420 return; |
506 return; |
421 } |
507 } |
441 |
527 |
442 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
528 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
443 || !d->simplePen |
529 || !d->simplePen |
444 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
530 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
445 || !d->isSimpleBrush(brush) |
531 || !d->isSimpleBrush(brush) |
446 || !d->testCompositionMode(&pen, &brush)) { |
532 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
447 RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); |
533 RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); |
448 d->lock(); |
534 d->lock(); |
449 QRasterPaintEngine::drawRects(rects, rectCount); |
535 QRasterPaintEngine::drawRects(rects, rectCount); |
450 return; |
536 return; |
451 } |
537 } |
466 Q_D(QDirectFBPaintEngine); |
552 Q_D(QDirectFBPaintEngine); |
467 |
553 |
468 const QPen &pen = state()->pen; |
554 const QPen &pen = state()->pen; |
469 if (!d->simplePen |
555 if (!d->simplePen |
470 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
556 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
471 || !d->testCompositionMode(&pen, 0)) { |
557 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
472 RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); |
558 RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); |
473 d->lock(); |
559 d->lock(); |
474 QRasterPaintEngine::drawLines(lines, lineCount); |
560 QRasterPaintEngine::drawLines(lines, lineCount); |
475 return; |
561 return; |
476 } |
562 } |
486 Q_D(QDirectFBPaintEngine); |
572 Q_D(QDirectFBPaintEngine); |
487 |
573 |
488 const QPen &pen = state()->pen; |
574 const QPen &pen = state()->pen; |
489 if (!d->simplePen |
575 if (!d->simplePen |
490 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
576 || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip |
491 || !d->testCompositionMode(&pen, 0)) { |
577 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
492 RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); |
578 RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG()); |
493 d->lock(); |
579 d->lock(); |
494 QRasterPaintEngine::drawLines(lines, lineCount); |
580 QRasterPaintEngine::drawLines(lines, lineCount); |
495 return; |
581 return; |
496 } |
582 } |
524 images and the cost of caching the image (bytes used) is higher |
610 images and the cost of caching the image (bytes used) is higher |
525 than the max image cache size we fall back to raster engine. |
611 than the max image cache size we fall back to raster engine. |
526 */ |
612 */ |
527 |
613 |
528 #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE |
614 #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE |
529 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) |
615 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported) |
530 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
616 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
531 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
617 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
532 || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size()) |
618 || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size()) |
533 #ifndef QT_DIRECTFB_IMAGECACHE |
619 #ifndef QT_DIRECTFB_IMAGECACHE |
534 || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) |
620 || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) |
573 QRasterPaintEngine::drawPixmap(r, pixmap, sr); |
659 QRasterPaintEngine::drawPixmap(r, pixmap, sr); |
574 } else { |
660 } else { |
575 QPixmapData *data = pixmap.pixmapData(); |
661 QPixmapData *data = pixmap.pixmapData(); |
576 Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); |
662 Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); |
577 QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); |
663 QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); |
578 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) |
664 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported) |
579 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
665 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
580 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
666 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
581 || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) { |
667 || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) { |
582 RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); |
668 RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); |
583 const QImage *img = dfbData->buffer(); |
669 const QImage *img = dfbData->buffer(); |
604 Q_D(QDirectFBPaintEngine); |
690 Q_D(QDirectFBPaintEngine); |
605 if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { |
691 if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { |
606 RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); |
692 RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); |
607 d->lock(); |
693 d->lock(); |
608 QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); |
694 QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); |
609 } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) |
695 } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported) |
610 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
696 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
611 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
697 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
612 || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { |
698 || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { |
613 RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); |
699 RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); |
614 QPixmapData *pixmapData = pixmap.pixmapData(); |
700 QPixmapData *pixmapData = pixmap.pixmapData(); |
717 if (brush.style() == Qt::NoBrush) |
803 if (brush.style() == Qt::NoBrush) |
718 return; |
804 return; |
719 if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) { |
805 if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) { |
720 switch (brush.style()) { |
806 switch (brush.style()) { |
721 case Qt::SolidPattern: { |
807 case Qt::SolidPattern: { |
722 if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported |
|
723 || !d->testCompositionMode(0, &brush)) { |
|
724 break; |
|
725 } |
|
726 const QColor color = brush.color(); |
808 const QColor color = brush.color(); |
727 if (!color.isValid()) |
809 if (!color.isValid()) |
728 return; |
810 return; |
811 |
|
812 if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported |
|
813 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
|
814 break; |
|
815 } |
|
729 d->setDFBColor(color); |
816 d->setDFBColor(color); |
730 const QRect r = state()->matrix.mapRect(rect).toRect(); |
817 const QRect r = state()->matrix.mapRect(rect).toRect(); |
731 CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height())); |
818 CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height())); |
732 return; } |
819 return; } |
733 |
820 |
734 case Qt::TexturePattern: { |
821 case Qt::TexturePattern: { |
735 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) |
822 if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported) |
736 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
823 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) |
737 || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { |
824 || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { |
738 break; |
825 break; |
739 } |
826 } |
740 |
827 |
758 if (!color.isValid()) |
845 if (!color.isValid()) |
759 return; |
846 return; |
760 Q_D(QDirectFBPaintEngine); |
847 Q_D(QDirectFBPaintEngine); |
761 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
848 if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) |
762 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
849 || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) |
763 || !d->testCompositionMode(0, 0, &color)) { |
850 || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) { |
764 RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); |
851 RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); |
765 d->lock(); |
852 d->lock(); |
766 QRasterPaintEngine::fillRect(rect, color); |
853 QRasterPaintEngine::fillRect(rect, color); |
767 } else { |
854 } else { |
768 d->setDFBColor(color); |
855 d->setDFBColor(color); |
802 |
889 |
803 QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) |
890 QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) |
804 : surface(0), antialiased(false), simplePen(false), |
891 : surface(0), antialiased(false), simplePen(false), |
805 transformationType(0), opacity(255), |
892 transformationType(0), opacity(255), |
806 clipType(ClipUnset), dfbDevice(0), |
893 clipType(ClipUnset), dfbDevice(0), |
807 compositionModeStatus(0), inClip(false), q(p) |
894 compositionModeStatus(0), isPremultiplied(false), inClip(false), q(p) |
808 { |
895 { |
809 fb = QDirectFBScreen::instance()->dfb(); |
896 fb = QDirectFBScreen::instance()->dfb(); |
810 surfaceCache = new SurfaceCache; |
897 surfaceCache = new SurfaceCache; |
811 } |
898 } |
812 |
899 |
817 |
904 |
818 bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const |
905 bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const |
819 { |
906 { |
820 return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); |
907 return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); |
821 } |
908 } |
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 |
|
852 |
909 |
853 void QDirectFBPaintEnginePrivate::lock() |
910 void QDirectFBPaintEnginePrivate::lock() |
854 { |
911 { |
855 // We will potentially get a new pointer to the buffer after a |
912 // We will potentially get a new pointer to the buffer after a |
856 // lock so we need to call the base implementation of prepare so |
913 // lock so we need to call the base implementation of prepare so |
910 if (!surface) |
967 if (!surface) |
911 return; |
968 return; |
912 |
969 |
913 static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0; |
970 static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0; |
914 if (forceRasterFallBack) { |
971 if (forceRasterFallBack) { |
915 compositionModeStatus = 0; |
972 compositionModeStatus = PorterDuff_None; |
916 return; |
973 return; |
917 } |
974 } |
918 |
975 |
919 compositionModeStatus = PorterDuff_SupportedBlits; |
976 compositionModeStatus = PorterDuff_Supported|PorterDuff_PremultiplyColors|PorterDuff_AlwaysBlend; |
920 switch (mode) { |
977 switch (mode) { |
921 case QPainter::CompositionMode_Clear: |
978 case QPainter::CompositionMode_Clear: |
922 surface->SetPorterDuff(surface, DSPD_CLEAR); |
979 surface->SetPorterDuff(surface, DSPD_CLEAR); |
923 break; |
980 break; |
924 case QPainter::CompositionMode_Source: |
981 case QPainter::CompositionMode_Source: |
925 surface->SetPorterDuff(surface, DSPD_SRC); |
982 surface->SetPorterDuff(surface, DSPD_SRC); |
926 compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives; |
983 compositionModeStatus &= ~PorterDuff_AlwaysBlend; |
984 if (!isPremultiplied) |
|
985 compositionModeStatus &= ~PorterDuff_PremultiplyColors; |
|
927 break; |
986 break; |
928 case QPainter::CompositionMode_SourceOver: |
987 case QPainter::CompositionMode_SourceOver: |
929 compositionModeStatus |= PorterDuff_SupportedPrimitives; |
988 compositionModeStatus &= ~PorterDuff_AlwaysBlend; |
930 surface->SetPorterDuff(surface, DSPD_SRC_OVER); |
989 surface->SetPorterDuff(surface, DSPD_SRC_OVER); |
931 break; |
990 break; |
932 case QPainter::CompositionMode_DestinationOver: |
991 case QPainter::CompositionMode_DestinationOver: |
933 surface->SetPorterDuff(surface, DSPD_DST_OVER); |
992 surface->SetPorterDuff(surface, DSPD_DST_OVER); |
934 break; |
993 break; |
935 case QPainter::CompositionMode_SourceIn: |
994 case QPainter::CompositionMode_SourceIn: |
936 surface->SetPorterDuff(surface, DSPD_SRC_IN); |
995 surface->SetPorterDuff(surface, DSPD_SRC_IN); |
996 if (!isPremultiplied) |
|
997 compositionModeStatus &= ~PorterDuff_PremultiplyColors; |
|
937 break; |
998 break; |
938 case QPainter::CompositionMode_DestinationIn: |
999 case QPainter::CompositionMode_DestinationIn: |
939 surface->SetPorterDuff(surface, DSPD_DST_IN); |
1000 surface->SetPorterDuff(surface, DSPD_DST_IN); |
940 break; |
1001 break; |
941 case QPainter::CompositionMode_SourceOut: |
1002 case QPainter::CompositionMode_SourceOut: |
942 surface->SetPorterDuff(surface, DSPD_SRC_OUT); |
1003 surface->SetPorterDuff(surface, DSPD_SRC_OUT); |
943 break; |
1004 break; |
944 case QPainter::CompositionMode_DestinationOut: |
1005 case QPainter::CompositionMode_DestinationOut: |
945 surface->SetPorterDuff(surface, DSPD_DST_OUT); |
1006 surface->SetPorterDuff(surface, DSPD_DST_OUT); |
946 break; |
1007 break; |
1008 #if (Q_DIRECTFB_VERSION >= 0x010209) |
|
1009 case QPainter::CompositionMode_Destination: |
|
1010 surface->SetPorterDuff(surface, DSPD_DST); |
|
1011 break; |
|
1012 #endif |
|
947 #if (Q_DIRECTFB_VERSION >= 0x010000) |
1013 #if (Q_DIRECTFB_VERSION >= 0x010000) |
948 case QPainter::CompositionMode_SourceAtop: |
1014 case QPainter::CompositionMode_SourceAtop: |
949 surface->SetPorterDuff(surface, DSPD_SRC_ATOP); |
1015 surface->SetPorterDuff(surface, DSPD_SRC_ATOP); |
950 break; |
1016 break; |
951 case QPainter::CompositionMode_DestinationAtop: |
1017 case QPainter::CompositionMode_DestinationAtop: |
957 case QPainter::CompositionMode_Xor: |
1023 case QPainter::CompositionMode_Xor: |
958 surface->SetPorterDuff(surface, DSPD_XOR); |
1024 surface->SetPorterDuff(surface, DSPD_XOR); |
959 break; |
1025 break; |
960 #endif |
1026 #endif |
961 default: |
1027 default: |
962 compositionModeStatus = 0; |
1028 compositionModeStatus = PorterDuff_None; |
963 break; |
1029 break; |
964 } |
1030 } |
965 } |
1031 } |
966 |
1032 |
967 void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) |
1033 void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) |
979 if (opacity != 255) { |
1045 if (opacity != 255) { |
980 blittingFlags |= DSBLIT_BLEND_COLORALPHA; |
1046 blittingFlags |= DSBLIT_BLEND_COLORALPHA; |
981 } |
1047 } |
982 surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); |
1048 surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); |
983 surface->SetBlittingFlags(surface, blittingFlags); |
1049 surface->SetBlittingFlags(surface, blittingFlags); |
984 if (compositionModeStatus & PorterDuff_Dirty) { |
|
985 setCompositionMode(q->state()->composition_mode); |
|
986 } |
|
987 } |
1050 } |
988 |
1051 |
989 static inline uint ALPHA_MUL(uint x, uint a) |
1052 static inline uint ALPHA_MUL(uint x, uint a) |
990 { |
1053 { |
991 uint t = x * a; |
1054 uint t = x * a; |
994 } |
1057 } |
995 |
1058 |
996 void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) |
1059 void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) |
997 { |
1060 { |
998 Q_ASSERT(surface); |
1061 Q_ASSERT(surface); |
1062 Q_ASSERT(compositionModeStatus & PorterDuff_Supported); |
|
999 const quint8 alpha = (opacity == 255 ? |
1063 const quint8 alpha = (opacity == 255 ? |
1000 color.alpha() : ALPHA_MUL(color.alpha(), opacity)); |
1064 color.alpha() : ALPHA_MUL(color.alpha(), opacity)); |
1001 surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha); |
1065 QColor col; |
1002 surface->SetPorterDuff(surface, DSPD_NONE); |
1066 if (compositionModeStatus & PorterDuff_PremultiplyColors) { |
1003 surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND); |
1067 col = QColor(ALPHA_MUL(color.red(), alpha), |
1004 compositionModeStatus |= PorterDuff_Dirty; |
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); |
|
1005 } |
1076 } |
1006 |
1077 |
1007 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release) |
1078 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release) |
1008 { |
1079 { |
1009 #ifdef QT_NO_DIRECTFB_IMAGECACHE |
1080 #ifdef QT_NO_DIRECTFB_IMAGECACHE |
1281 const QRect r = mapRect(transform, rects[i]); |
1352 const QRect r = mapRect(transform, rects[i]); |
1282 surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height()); |
1353 surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height()); |
1283 } |
1354 } |
1284 } |
1355 } |
1285 |
1356 |
1286 #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS |
1357 #if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DEBUG |
1287 template <typename T> inline const T *ptr(const T &t) { return &t; } |
1358 template <typename T> inline const T *ptr(const T &t) { return &t; } |
1288 template <> inline const bool* ptr<bool>(const bool &) { return 0; } |
1359 template <> inline const bool* ptr<bool>(const bool &) { return 0; } |
1289 template <typename device, typename T1, typename T2, typename T3> |
1360 template <typename device, typename T1, typename T2, typename T3> |
1290 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, |
1361 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, |
1291 uint transformationType, bool simplePen, |
1362 uint transformationType, bool simplePen, |