diff options
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp')
-rw-r--r-- | src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 622 |
1 files changed, 287 insertions, 335 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index fb3ecc9..ba5d71a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -54,6 +54,70 @@ #include <private/qpixmapdata_p.h> #include <private/qpixmap_raster_p.h> +#ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS +template <typename T> inline const T *ptr(const T &t) { return &t; } +template <> inline const bool* ptr<bool>(const bool &) { return 0; } +template <typename device, typename T1, typename T2, typename T3> +static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, + bool matrixScale, bool matrixRotShear, bool simplePen, + bool dfbHandledClip, bool forceRasterPrimitives, + const char *nameOne, const T1 &one, + const char *nameTwo, const T2 &two, + const char *nameThree, const T3 &three) +{ + QString out; + QDebug dbg(&out); + dbg << msg << (QByteArray(func) + "()") << "painting on"; + if (dev->devType() == QInternal::Widget) { + dbg << static_cast<const QWidget*>(dev); + } else { + dbg << dev << "of type" << dev->devType(); + } + + dbg << "matrixScale" << matrixScale + << "matrixRotShear" << matrixRotShear + << "simplePen" << simplePen + << "dfbHandledClip" << dfbHandledClip + << "forceRasterPrimitives" << forceRasterPrimitives; + + const T1 *t1 = ptr(one); + const T2 *t2 = ptr(two); + const T3 *t3 = ptr(three); + + if (t1) { + dbg << nameOne << *t1; + if (t2) { + dbg << nameTwo << *t2; + if (t3) { + dbg << nameThree << *t3; + } + } + } + qWarning("%s", qPrintable(out)); +} +#endif + +#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS +#define RASTERFALLBACK(one, two, three) rasterFallbackWarn("Disabled raster engine operation", \ + __FUNCTION__, state()->painter->device(), \ + d_func()->matrixScale, d_func()->matrixRotShear, \ + d_func()->simplePen, d_func()->dfbCanHandleClip(), \ + d_func()->forceRasterPrimitives, \ + #one, one, #two, two, #three, three); \ + return; +#elif defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS +#define RASTERFALLBACK(one, two, three) return; +#elif defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS +#define RASTERFALLBACK(one, two, three) rasterFallbackWarn("Falling back to raster engine for", \ + __FUNCTION__, state()->painter->device(), \ + d_func()->matrixScale, d_func()->matrixRotShear, \ + d_func()->simplePen, d_func()->dfbCanHandleClip(), \ + d_func()->forceRasterPrimitives, \ + #one, one, #two, two, #three, three); +#else +#define RASTERFALLBACK(one, two, three) +#endif + static inline uint ALPHA_MUL(uint x, uint a) { uint t = x * a; @@ -61,17 +125,6 @@ static inline uint ALPHA_MUL(uint x, uint a) return t; } -static inline QRect mapRect(const QTransform &transform, const QRect &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)); -} - -static inline QRect mapRect(const QTransform &transform, const QRectF &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)). - toRect(); -} - class SurfaceCache { public: @@ -112,7 +165,7 @@ CachedImage::CachedImage(const QImage &image) description = QDirectFBScreen::getSurfaceDescription(image); QDirectFBScreen* screen = QDirectFBScreen::instance(); - tmpSurface = screen->createDFBSurface(&description); + tmpSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!tmpSurface) { qWarning("CachedImage CreateSurface failed!"); return; @@ -124,7 +177,7 @@ CachedImage::CachedImage(const QImage &image) description.flags = DFBSurfaceDescriptionFlags(description.flags & ~DSDESC_PREALLOCATED); - s = screen->createDFBSurface(&description); + s = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!s) qWarning("QDirectFBPaintEngine failed caching image"); @@ -159,7 +212,7 @@ IDirectFBSurface* SurfaceCache::getSurface(const uint *buf, int size) DFBSurfaceDescription description; description = QDirectFBScreen::getSurfaceDescription(buf, size); - surface = QDirectFBScreen::instance()->createDFBSurface(&description); + surface = QDirectFBScreen::instance()->createDFBSurface(&description, QDirectFBScreen::TrackSurface); if (!surface) qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface"); @@ -192,31 +245,30 @@ public: IDirectFBSurface *surface; QPen pen; - QBrush brush; bool antialiased; + bool forceRasterPrimitives; bool simplePen; - bool simpleBrush; bool matrixRotShear; bool matrixScale; void setTransform(const QTransform &m); void setPen(const QPen &pen); - void setBrush(const QBrush &brush); void setCompositionMode(QPainter::CompositionMode mode); - void setOpacity(const qreal value); + void setOpacity(quint8 value); void setRenderHints(QPainter::RenderHints hints); - inline void setDFBColor(const QColor &color) const; + inline void setDFBColor(const QColor &color); - inline bool lock(); + inline void lock(); inline void unlock(); inline bool dfbCanHandleClip(const QRect &rect) const; inline bool dfbCanHandleClip(const QRectF &rect) const; inline bool dfbCanHandleClip() const; + inline bool isSimpleBrush(const QBrush &brush) const; void drawLines(const QLine *lines, int count) const; void drawLines(const QLineF *lines, int count) const; @@ -227,48 +279,47 @@ public: void fillRects(const QRectF *rects, int count) const; void drawRects(const QRectF *rects, int count) const; + void drawPixmap(const QRectF &dest, const QPixmap &pixmap, const QRectF &src); void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap); void drawImage(const QRectF &dest, const QImage &image, const QRectF &src); - void updateClip(); - void updateFlags(); + inline void updateClip(); inline void setClipDirty(); - void systemStateChanged(); //Needed to be notified when system clip changes + void systemStateChanged(); void begin(QPaintDevice *device); void end(); + void prepareForBlit(bool alpha); SurfaceCache *surfaceCache; - + QTransform transform; + int lastLockedHeight; private: -// QRegion rectsToClippedRegion(const QRect *rects, int n) const; -// QRegion rectsToClippedRegion(const QRectF *rects, int n) const; - IDirectFB *fb; DFBSurfaceDescription fbDescription; int fbWidth; int fbHeight; quint8 opacity; - QTransform transform; - quint32 drawFlags; - quint32 blitFlags; - quint32 duffFlags; - bool dirtyFlags; + quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode; + DFBSurfacePorterDuffRule porterDuffRule; + bool dirtyClip; bool dfbHandledClip; + QDirectFBPaintDevice *dfbDevice; QDirectFBPaintEngine *q; }; QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) - : surface(0), antialiased(false), simplePen(false), - simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1), - opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true), - dfbHandledClip(false), q(p) + : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), + matrixRotShear(false), matrixScale(false), lastLockedHeight(-1), + fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), + blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), + dfbHandledClip(false), dfbDevice(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -279,7 +330,6 @@ QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate() { - unlock(); delete surfaceCache; } @@ -300,32 +350,30 @@ bool QDirectFBPaintEnginePrivate::dfbCanHandleClip() const return dfbHandledClip; } +bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const +{ + return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); +} + void QDirectFBPaintEnginePrivate::setClipDirty() { dirtyClip = true; } - -bool QDirectFBPaintEnginePrivate::lock() +void QDirectFBPaintEnginePrivate::lock() { // We will potentially get a new pointer to the buffer after a // lock so we need to call the base implementation of prepare so // it updates its rasterBuffer to point to the new buffer address. - if (device->devType() == QInternal::CustomRaster) { - prepare(static_cast<QCustomRasterPaintDevice*>(device)); - return true; - } - return false; + lastLockedHeight = dfbDevice->height(); + + Q_ASSERT(dfbDevice); + prepare(dfbDevice); } void QDirectFBPaintEnginePrivate::unlock() { - QPaintDevice *device = q->paintDevice(); - if (!device) //XXX This should probably be an assert - return; - - Q_ASSERT(device->devType() == QInternal::CustomRaster); - QDirectFBPaintDevice* dfbDevice = static_cast<QDirectFBPaintDevice*>(device); + Q_ASSERT(dfbDevice); dfbDevice->unlockDirectFB(); } @@ -338,35 +386,31 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) { - QDirectFBPaintDevice* dfbDevice = 0; - + lastLockedHeight = -1; if (device->devType() == QInternal::CustomRaster) dfbDevice = static_cast<QDirectFBPaintDevice*>(device); else if (device->devType() == QInternal::Pixmap) { QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData(); - if (data->classId() == QPixmapData::DirectFBClass) { - QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data); - dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData); - } + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data); + dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData); } if (dfbDevice) - surface = dfbDevice->directFbSurface(); + surface = dfbDevice->directFBSurface(); if (!surface) { qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", device->devType()); } + forceRasterPrimitives = dfbDevice->forceRasterPrimitives(); surface->GetSize(surface, &fbWidth, &fbHeight); setTransform(QTransform()); antialiased = false; - drawFlags = DSDRAW_BLEND; - blitFlags = DSBLIT_BLEND_ALPHACHANNEL; - duffFlags = DSPD_SRC_OVER; opacity = 255; - dirtyFlags = true; + setCompositionMode(q->state()->compositionMode()); dirtyClip = true; setPen(q->state()->pen); setDFBColor(pen.color()); @@ -374,6 +418,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) void QDirectFBPaintEnginePrivate::end() { + dfbDevice = 0; surface->ReleaseSource(surface); surface->SetClip(surface, NULL); surface = 0; @@ -383,105 +428,80 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p) { pen = p; simplePen = (pen.style() == Qt::NoPen) || - (pen.style() == Qt::SolidLine && !antialiased + (pen.style() == Qt::SolidLine + && !antialiased + && (pen.brush().style() == Qt::SolidPattern) && (pen.widthF() <= 1 && !matrixScale)); } -void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b) -{ - // TODO: accelerate texture pattern - brush = b; - simpleBrush = (brush.style() == Qt::NoBrush) || - (brush.style() == Qt::SolidPattern && !antialiased); -} - void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) { - drawFlags &= ~(DSDRAW_XOR); - blitFlags &= ~(DSBLIT_XOR); - - // TODO: check these mappings!!!! - quint32 duff = DSPD_NONE; - quint32 blit = blitFlags; + blitFlagsFromCompositionMode = DSBLIT_NOFX; + drawFlagsFromCompositionMode = DSDRAW_NOFX; + bool blend = true; switch (mode) { case QPainter::CompositionMode_SourceOver: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OVER; break; case QPainter::CompositionMode_DestinationOver: - duff = DSPD_DST_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_OVER; break; case QPainter::CompositionMode_Clear: - duff = DSPD_CLEAR; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_CLEAR; + blend = false; break; case QPainter::CompositionMode_Source: - duff = DSPD_SRC; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC; + blend = false; break; case QPainter::CompositionMode_Destination: - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_NONE; // ### need to double check this + blend = false; return; case QPainter::CompositionMode_SourceIn: - duff = DSPD_SRC_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_IN; break; case QPainter::CompositionMode_DestinationIn: - duff = DSPD_DST_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_IN; break; case QPainter::CompositionMode_SourceOut: - duff = DSPD_SRC_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OUT; break; case QPainter::CompositionMode_DestinationOut: - duff = DSPD_DST_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_SourceAtop: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_DestinationAtop: - duff = DSPD_DST_OVER; + porterDuffRule = DSPD_DST_OUT; break; case QPainter::CompositionMode_Xor: - duff = DSPD_NONE; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - drawFlags |= DSDRAW_XOR; - blit |= DSBLIT_XOR; - dirtyFlags = true; + porterDuffRule = DSPD_XOR; + blitFlagsFromCompositionMode |= DSBLIT_XOR; + drawFlagsFromCompositionMode |= DSDRAW_XOR; break; +// case QPainter::CompositionMode_Plus: // ??? +// porterDuffRule = DSPD_ADD; +// break; default: qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): " "mode %d not implemented", mode); - break; + return; } - - if (duff != duffFlags || blit != blitFlags) { - duffFlags = duff; - blitFlags = blit; - dirtyFlags = true; + // intentially not comparing with current porterDuffRule. surface might have changed. + if (blend) { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL; + drawFlagsFromCompositionMode |= DSDRAW_BLEND; + } + if (opacity != 255) { + setOpacity(opacity); } } -void QDirectFBPaintEnginePrivate::setOpacity(const qreal value) +void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) { - const bool wasOpaque = (opacity == 255); - opacity = quint8(value * 255); - const bool opaque = (opacity == 255); - - if (opaque == wasOpaque) - return; - - if (opaque) - blitFlags &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - else - blitFlags |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - - dirtyFlags = true; + opacity = op; + if (opacity == 255) { + blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA; + } else { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA; + } } void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) @@ -493,133 +513,83 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) } } -void QDirectFBPaintEnginePrivate::updateFlags() +void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { - if (!dirtyFlags) - return; - surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawFlags)); - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); - surface->SetPorterDuff(surface, DFBSurfacePorterDuffRule(duffFlags)); - dirtyFlags = false; + quint32 blittingFlags = blitFlagsFromCompositionMode; + if (alpha) { + surface->SetPorterDuff(surface, + (blittingFlags & DSBLIT_BLEND_COLORALPHA) + ? DSPD_NONE + : porterDuffRule); + } else { + blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; + surface->SetPorterDuff(surface, DSPD_NONE); + } + surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); + surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); } -void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) const +void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) { + Q_ASSERT(surface); const quint8 alpha = (opacity == 255 ? color.alpha() : ALPHA_MUL(color.alpha(), opacity)); surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha); + quint32 drawingFlags = drawFlagsFromCompositionMode; + if (alpha == 255) { + drawingFlags &= ~DSDRAW_BLEND; + } + surface->SetPorterDuff(surface, DSPD_NONE); + // PorterDuff messes up alpha values for primitives + surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags)); } void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const { - QVarLengthArray<DFBRegion> regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]); - - // TODO: clip! - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); } void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const { - QVarLengthArray<DFBRegion> regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]).toLine(); - - // TODO: clip! - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); } -/* ### Commented out until it can be implemented properly using raster's QClipData -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); - region += clip & r; - } - - return region; -} - -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); - region += clip & r; - } - - return region; -} -*/ - void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) const { const QVector<QRect> rects = region.rects(); const int n = rects.size(); - QVarLengthArray<DFBRectangle> dfbRects(n); - - for (int i = 0; i < n; ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); - - } - surface->FillRectangles(surface, dfbRects.data(), n); + fillRects(rects.constData(), n); } void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const { - QVarLengthArray<DFBRectangle> dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + const QRect r = transform.mapRect(rects[i]); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); } - surface->FillRectangles(surface, dfbRects.data(), n); } void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const { - QVarLengthArray<DFBRectangle> dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + const QRect r = transform.mapRect(rects[i]).toRect(); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); } - surface->FillRectangles(surface, dfbRects.data(), n); } void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -628,7 +598,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -638,21 +608,13 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, const QPixmap &pixmap, const QRectF &src) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - IDirectFBSurface *s = dfbData->directFbSurface(); + IDirectFBSurface *s = dfbData->directFBSurface(); const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, dest); + const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; DFBResult result; @@ -664,27 +626,17 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, } if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - IDirectFBSurface *s = dfbData->directFbSurface(); - const QRect dr = ::mapRect(transform, dest); + IDirectFBSurface *s = dfbData->directFBSurface(); + const QRect dr = transform.mapRect(dest).toRect(); DFBResult result = DFB_OK; if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) { @@ -706,7 +658,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, result = surface->BatchBlit(surface, s, rects.constData(), points.constData(), points.size()); } else { - const QRect sr = ::mapRect(transform, QRect(0, 0, pixmap.width(), pixmap.height())); + const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); const int dx = sr.width(); const int dy = sr.height(); const DFBRectangle sRect = { 0, 0, dx, dy }; @@ -725,25 +677,13 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); - - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, - const QImage &srcImage, + const QImage &image, const QRectF &src) { - QImage image = srcImage; - if (QDirectFBScreen::getSurfacePixelFormat(image) == DSPF_UNKNOWN) { - QImage::Format format; - if (image.hasAlphaChannel()) - format = QImage::Format_ARGB32_Premultiplied; - else - format = QImage::Format_RGB32; - image = image.convertToFormat(format); - } - + Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN); CachedImage *img = imageCache[image.cacheKey()]; IDirectFBSurface *imgSurface = 0; bool doRelease = false; @@ -767,7 +707,8 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, DFBSurfaceDescription description; description = QDirectFBScreen::getSurfaceDescription(image); - imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description); + imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description, + QDirectFBScreen::DontTrackSurface); if (!imgSurface) { qWarning("QDirectFBPaintEnginePrivate::drawImage"); return; @@ -781,17 +722,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, } const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, dest); + const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !image.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } + prepareForBlit(image.hasAlphaChannel()); if (dr.size() == sr.size()) { surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y()); } else { @@ -799,10 +733,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, dr.width(), dr.height() }; surface->StretchBlit(surface, imgSurface, &sRect, &dRect); } - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); - if (doRelease) - QDirectFBScreen::instance()->releaseDFBSurface(imgSurface); + if (doRelease) { + surface->ReleaseSource(surface); + imgSurface->Release(imgSurface); + } } void QDirectFBPaintEnginePrivate::updateClip() @@ -882,19 +816,10 @@ void QDirectFBPaintEngine::penChanged() QRasterPaintEngine::penChanged(); } -void QDirectFBPaintEngine::brushChanged() -{ - Q_D(QDirectFBPaintEngine); - d->setBrush(state()->brush); - - QRasterPaintEngine::brushChanged(); -} - void QDirectFBPaintEngine::opacityChanged() { Q_D(QDirectFBPaintEngine); - d->setOpacity(state()->opacity); - + d->setOpacity(quint8(state()->opacity * 255)); QRasterPaintEngine::opacityChanged(); } @@ -902,7 +827,6 @@ void QDirectFBPaintEngine::compositionModeChanged() { Q_D(QDirectFBPaintEngine); d->setCompositionMode(state()->compositionMode()); - QRasterPaintEngine::compositionModeChanged(); } @@ -928,11 +852,9 @@ void QDirectFBPaintEngine::setState(QPainterState *s) { Q_D(QDirectFBPaintEngine); QRasterPaintEngine::setState(s); - if (d->surface) - d->updateClip(); + d->setClipDirty(); d->setPen(state()->pen); - d->setBrush(state()->brush); - d->setOpacity(state()->opacity); + d->setOpacity(quint8(state()->opacity * 255)); d->setCompositionMode(state()->compositionMode()); d->setTransform(state()->transform()); } @@ -941,6 +863,9 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2)); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); QRasterPaintEngine::clip(path, op); } @@ -948,15 +873,24 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + if (!d->clip()->hasRectClip && d->clip()->enabled) { + const QPoint bottom = d->transform.map(QPoint(0, rect.bottom())); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); + } + QRasterPaintEngine::clip(rect, op); } - void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) { + const QBrush &brush = state()->brush; + if (!d->dfbCanHandleClip() || d->matrixRotShear + || !d->simplePen || d->forceRasterPrimitives + || !d->isSimpleBrush(brush)) { + RASTERFALLBACK(rectCount, static_cast<bool>(false), static_cast<bool>(false)); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; @@ -964,13 +898,11 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) d->unlock(); - if (d->brush != Qt::NoBrush) { - d->updateFlags(); - d->setDFBColor(d->brush.color()); + if (brush != Qt::NoBrush) { + d->setDFBColor(brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -980,7 +912,10 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) { + const QBrush &brush = state()->brush; + if (!d->dfbCanHandleClip() || d->matrixRotShear + || !d->simplePen || d->forceRasterPrimitives + || !d->isSimpleBrush(brush)) { d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; @@ -988,13 +923,11 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) d->unlock(); - if (d->brush != Qt::NoBrush) { - d->updateFlags(); - d->setDFBColor(d->brush.color()); + if (brush != Qt::NoBrush) { + d->setDFBColor(brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -1004,7 +937,8 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->simplePen || !d->dfbCanHandleClip()) { + if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) { + RASTERFALLBACK(lineCount, static_cast<bool>(false), static_cast<bool>(false)); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; @@ -1012,7 +946,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -1022,7 +955,8 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->simplePen || !d->dfbCanHandleClip()) { + if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) { + RASTERFALLBACK(lineCount, static_cast<bool>(false), static_cast<bool>(false)); d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; @@ -1030,7 +964,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -1045,9 +978,11 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->updateClip(); - if (!d->dfbCanHandleClip(r) || d->matrixRotShear) + if (!d->dfbCanHandleClip(r) || d->matrixRotShear + || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) #endif { + RASTERFALLBACK(r, image.size(), sr); d->lock(); QRasterPaintEngine::drawImage(r, image, sr, flags); return; @@ -1055,7 +990,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->unlock(); - d->updateFlags(); d->drawImage(r, image, sr); #endif } @@ -1072,17 +1006,16 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, d->updateClip(); if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { + // not using RASTERFALLBACK since this is the way we do bitmaps? d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { + RASTERFALLBACK(r, pixmap.size(), sr); const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(); d->lock(); QRasterPaintEngine::drawImage(r, *img, sr); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawPixmap(r, pixmap, sr); } } @@ -1101,18 +1034,16 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { - QImage* img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(); + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { + RASTERFALLBACK(r, pixmap.size(), sp); + const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(); + d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); - d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pix, sp); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawTiledPixmap(r, pixmap); } } @@ -1127,6 +1058,7 @@ void QDirectFBPaintEngine::stroke(const QVectorPath &path, const QPen &pen) void QDirectFBPaintEngine::drawPath(const QPainterPath &path) { + RASTERFALLBACK(path.boundingRect(), static_cast<bool>(false), static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawPath(path); @@ -1134,6 +1066,7 @@ void QDirectFBPaintEngine::drawPath(const QPainterPath &path) void QDirectFBPaintEngine::drawPoints(const QPointF *points, int pointCount) { + RASTERFALLBACK(pointCount, static_cast<bool>(false), static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawPoints(points, pointCount); @@ -1141,6 +1074,7 @@ void QDirectFBPaintEngine::drawPoints(const QPointF *points, int pointCount) void QDirectFBPaintEngine::drawPoints(const QPoint *points, int pointCount) { + RASTERFALLBACK(pointCount, static_cast<bool>(false), static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawPoints(points, pointCount); @@ -1148,6 +1082,7 @@ void QDirectFBPaintEngine::drawPoints(const QPoint *points, int pointCount) void QDirectFBPaintEngine::drawEllipse(const QRectF &rect) { + RASTERFALLBACK(rect, static_cast<bool>(false), static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawEllipse(rect); @@ -1156,6 +1091,7 @@ void QDirectFBPaintEngine::drawEllipse(const QRectF &rect) void QDirectFBPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { + RASTERFALLBACK(pointCount, mode, static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawPolygon(points, pointCount, mode); @@ -1164,6 +1100,7 @@ void QDirectFBPaintEngine::drawPolygon(const QPointF *points, int pointCount, void QDirectFBPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { + RASTERFALLBACK(pointCount, mode, static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawPolygon(points, pointCount, mode); @@ -1172,6 +1109,7 @@ void QDirectFBPaintEngine::drawPolygon(const QPoint *points, int pointCount, void QDirectFBPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) { + RASTERFALLBACK(p, textItem.text(), static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::drawTextItem(p, textItem); @@ -1179,6 +1117,7 @@ void QDirectFBPaintEngine::drawTextItem(const QPointF &p, void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { + RASTERFALLBACK(path, brush, static_cast<bool>(false)); Q_D(QDirectFBPaintEngine); d->lock(); QRasterPaintEngine::fill(path, brush); @@ -1191,17 +1130,19 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) d->updateClip(); if (d->dfbCanHandleClip(rect) && !d->matrixRotShear) { switch (brush.style()) { - case Qt::SolidPattern: + case Qt::SolidPattern: { + if (d->forceRasterPrimitives) + break; d->unlock(); - d->updateFlags(); d->setDFBColor(brush.color()); - d->fillRects(&rect, 1); - return; + const QRect r = d->transform.mapRect(rect).toRect(); + d->surface->FillRectangle(d->surface, r.x(), r.y(), + r.width(), r.height()); + return; } case Qt::TexturePattern: if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) { //could handle certain types of brush.transform() E.g. scale d->unlock(); - d->updateFlags(); d->drawTiledPixmap(rect, brush.texture()); return; } @@ -1210,6 +1151,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) break; } } + RASTERFALLBACK(rect, brush, static_cast<bool>(false)); d->lock(); QRasterPaintEngine::fillRect(rect, brush); } @@ -1218,14 +1160,16 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear) { + if (!d->dfbCanHandleClip() || d->matrixRotShear || d->forceRasterPrimitives) { + RASTERFALLBACK(rect, color, static_cast<bool>(false)); d->lock(); QRasterPaintEngine::fillRect(rect, color); } else { d->unlock(); - d->updateFlags(); d->setDFBColor(color); - d->fillRects(&rect, 1); + const QRect r = d->transform.mapRect(rect).toRect(); + d->surface->FillRectangle(d->surface, r.x(), r.y(), + r.width(), r.height()); } } @@ -1233,31 +1177,38 @@ void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count, uint color) { Q_D(QDirectFBPaintEngine); - color = INV_PREMUL(color); - - QVarLengthArray<DFBRegion> lines(count); - int j = 0; - for (int i = 0; i < count; ++i) { - if (spans[i].coverage == 255) { - lines[j].x1 = spans[i].x; - lines[j].y1 = spans[i].y; - lines[j].x2 = spans[i].x + spans[i].len - 1; - lines[j].y2 = spans[i].y; - ++j; - } else { - DFBSpan span = { spans[i].x, spans[i].len }; - uint c = BYTE_MUL(color, spans[i].coverage); + if (d->forceRasterPrimitives) { + RASTERFALLBACK(count, color, static_cast<bool>(false)); + d->lock(); + QRasterPaintEngine::drawColorSpans(spans, count, color); + } else { + color = INV_PREMUL(color); + + QVarLengthArray<DFBRegion> lines(count); + int j = 0; + for (int i = 0; i < count; ++i) { + if (spans[i].coverage == 255) { + lines[j].x1 = spans[i].x; + lines[j].y1 = spans[i].y; + lines[j].x2 = spans[i].x + spans[i].len - 1; + lines[j].y2 = spans[i].y; + ++j; + } else { + DFBSpan span = { spans[i].x, spans[i].len }; + uint c = BYTE_MUL(color, spans[i].coverage); + // ### how does this play with setDFBColor + d->surface->SetColor(d->surface, + qRed(c), qGreen(c), qBlue(c), qAlpha(c)); + d->surface->FillSpans(d->surface, spans[i].y, &span, 1); + } + } + if (j > 0) { d->surface->SetColor(d->surface, - qRed(c), qGreen(c), qBlue(c), qAlpha(c)); - d->surface->FillSpans(d->surface, spans[i].y, &span, 1); + qRed(color), qGreen(color), qBlue(color), + qAlpha(color)); + d->surface->DrawLines(d->surface, lines.data(), j); } } - if (j > 0) { - d->surface->SetColor(d->surface, - qRed(color), qGreen(color), qBlue(color), - qAlpha(color)); - d->surface->DrawLines(d->surface, lines.data(), j); - } } void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, @@ -1266,6 +1217,7 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, { Q_D(QDirectFBPaintEngine); IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize); + // ### how does this play with setDFBColor src->SetColor(src, 0, 0, 0, const_alpha); const DFBRectangle rect = { 0, 0, length, 1 }; d->surface->Blit(d->surface, src, &rect, x, y); |