diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2012-01-23 10:42:54 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-27 17:49:30 (GMT) |
commit | 6907626962f845ae5d713f4e8f6bfefdd15724f6 (patch) | |
tree | 7faf510d429615e3f1acdd8f78d7f0eac479054a | |
parent | d3991bfeb1c2b14e85f8080323065be0babd3e11 (diff) | |
download | Qt-6907626962f845ae5d713f4e8f6bfefdd15724f6.zip Qt-6907626962f845ae5d713f4e8f6bfefdd15724f6.tar.gz Qt-6907626962f845ae5d713f4e8f6bfefdd15724f6.tar.bz2 |
blitter: Base QBlitterPaintEngine on QRasterPaintEngine
The original intention was to identify a clipping bug, it turns out
that during a ::begin() (and systemChanged) we should forward the
QPaintEnginePrivate state to our proxy engine.
Instead of using the proxy-pattern subclass rasterengine and
specialize the paths we are able to accelerate using the blitter
interface. This will avoid similiar problems in the future. I have
no performance measurement to show which of the two approaches is
faster/slower.
Change-Id: I5ee0de566f4568103f741af697bdabbb097927e4
Based-On: I39bff11b32b1fe20284c7e8df60050de5991bb6e
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
-rw-r--r-- | src/gui/image/qpixmap_blitter_p.h | 32 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_blitter.cpp | 190 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_blitter_p.h | 46 |
3 files changed, 151 insertions, 117 deletions
diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index b3cdd02..0ee8703 100644 --- a/src/gui/image/qpixmap_blitter_p.h +++ b/src/gui/image/qpixmap_blitter_p.h @@ -72,8 +72,11 @@ public: void markRasterOverlay(const QRectF &); void markRasterOverlay(const QPointF &, const QTextItem &); void markRasterOverlay(const QVectorPath &); + void markRasterOverlay(const QPainterPath &); void markRasterOverlay(const QRect *rects, int rectCount); void markRasterOverlay(const QRectF *rects, int rectCount); + void markRasterOverlay(const QPointF *points, int pointCount); + void markRasterOverlay(const QPoint *points, int pointCount); void unmarkRasterOverlay(const QRectF &); #ifdef QT_BLITTER_RASTEROVERLAY @@ -153,6 +156,35 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rec #endif } +inline void QBlittablePixmapData::markRasterOverlay(const QPointF *points, int pointCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(points); + Q_UNUSED(pointCount); +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QPoint *points, int pointCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(points); + Q_UNUSED(pointCount); +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QPainterPath& path) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(path); +#endif +} + inline void QBlittablePixmapData::unmarkRasterOverlay(const QRectF &rect) { #ifdef QT_BLITTER_RASTEROVERLAY diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index ba2ac40..0b95842 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -181,19 +181,17 @@ private: uint capabillitiesState; }; -class QBlitterPaintEnginePrivate : public QPaintEngineExPrivate +class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate { Q_DECLARE_PUBLIC(QBlitterPaintEngine); public: QBlitterPaintEnginePrivate(QBlittablePixmapData *p) - : QPaintEngineExPrivate() + : QRasterPaintEnginePrivate() , pmData(p) , caps(pmData->blittable()->capabilities()) , hasXForm(false) - { - raster.reset(new QRasterPaintEngine(p->buffer())); - } + {} void lock(); void unlock(); @@ -210,12 +208,6 @@ public: void updateTransformState(QPainterState *s); void updateClipState(QPainterState *s); - void systemStateChanged() { - raster->d_func()->systemStateChanged(); - } - - QScopedPointer<QRasterPaintEngine> raster; - QBlittablePixmapData *pmData; CapabilitiesToStateMask caps; uint hasXForm; @@ -224,7 +216,7 @@ public: inline void QBlitterPaintEnginePrivate::lock() { if (!pmData->blittable()->isLocked()) - raster->d_func()->rasterBuffer->prepare(pmData->buffer()); + rasterBuffer->prepare(pmData->buffer()); } inline void QBlitterPaintEnginePrivate::unlock() @@ -290,10 +282,8 @@ void QBlitterPaintEnginePrivate::updateTransformState(QPainterState *s) void QBlitterPaintEnginePrivate::updateClipState(QPainterState *) { - Q_Q(QBlitterPaintEngine); - - const QClipData *clip = q->clip(); - bool complexClip = clip && !(clip->hasRectClip || clip->hasRegionClip); + const QClipData *clipData = clip(); + bool complexClip = clipData && !(clipData->hasRectClip || clipData->hasRegionClip); caps.updateState(STATE_CLIP_COMPLEX, complexClip); } @@ -304,7 +294,7 @@ void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &colo QRectF targetRect = rect; if (hasXForm) targetRect = q->state()->matrix.mapRect(rect); - const QClipData *clipData = q->clip(); + const QClipData *clipData = clip(); if (clipData) { if (clipData->hasRectClip) { unlock(); @@ -321,12 +311,12 @@ void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &colo } } else { if (targetRect.x() >= 0 && targetRect.y() >= 0 - && targetRect.width() <= raster->paintDevice()->width() - && targetRect.height() <= raster->paintDevice()->height()) { + && targetRect.width() <= q->paintDevice()->width() + && targetRect.height() <= q->paintDevice()->height()) { unlock(); pmData->blittable()->fillRect(targetRect, color); } else { - QRectF deviceRect(0, 0, raster->paintDevice()->width(), raster->paintDevice()->height()); + QRectF deviceRect(0, 0, q->paintDevice()->width(), q->paintDevice()->height()); unlock(); pmData->blittable()->fillRect(deviceRect & targetRect, color); } @@ -351,77 +341,70 @@ void QBlitterPaintEnginePrivate::clipAndDrawPixmap(const QRectF &clip, const QRe } QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePixmapData *p) - : QPaintEngineEx(*(new QBlitterPaintEnginePrivate(p))) -{} - -QBlitterPaintEngine::~QBlitterPaintEngine() + : QRasterPaintEngine(*(new QBlitterPaintEnginePrivate(p)), p->buffer()) {} // State tracking void QBlitterPaintEngine::penChanged() { Q_D(QBlitterPaintEngine); - d->lock(); - d->raster->penChanged(); + QRasterPaintEngine::penChanged(); d->updatePenState(state()); } void QBlitterPaintEngine::brushChanged() { Q_D(QBlitterPaintEngine); - d->raster->brushChanged(); + QRasterPaintEngine::brushChanged(); d->updateBrushState(state()); } -void QBlitterPaintEngine::brushOriginChanged() -{ - Q_D(QBlitterPaintEngine); - d->raster->brushOriginChanged(); -} - void QBlitterPaintEngine::opacityChanged() { Q_D(QBlitterPaintEngine); - d->raster->opacityChanged(); + + QRasterPaintEngine::opacityChanged(); d->updateOpacityState(state()); } void QBlitterPaintEngine::compositionModeChanged() { Q_D(QBlitterPaintEngine); - d->raster->compositionModeChanged(); + + QRasterPaintEngine::compositionModeChanged(); d->updateCompositionModeState(state()); } void QBlitterPaintEngine::renderHintsChanged() { Q_D(QBlitterPaintEngine); - d->raster->renderHintsChanged(); + + QRasterPaintEngine::renderHintsChanged(); d->updateRenderHintsState(state()); } void QBlitterPaintEngine::transformChanged() { Q_D(QBlitterPaintEngine); - d->raster->transformChanged(); + + QRasterPaintEngine::transformChanged(); d->updateTransformState(state()); } -QPainterState *QBlitterPaintEngine::createState(QPainterState *orig) const +void QBlitterPaintEngine::clipEnabledChanged() { - Q_D(const QBlitterPaintEngine); - return d->raster->createState(orig); + Q_D(QBlitterPaintEngine); + QRasterPaintEngine::clipEnabledChanged(); + d->updateClipState(state()); } bool QBlitterPaintEngine::begin(QPaintDevice *pdev) { - Q_D(QBlitterPaintEngine); - - setActive(true); - bool ok = d->raster->begin(pdev); + bool ok = QRasterPaintEngine::begin(pdev); #ifdef QT_BLITTER_RASTEROVERLAY + Q_D(QBlitterPaintEngine); d->pmData->unmergeOverlay(); #endif return ok; @@ -429,31 +412,22 @@ bool QBlitterPaintEngine::begin(QPaintDevice *pdev) bool QBlitterPaintEngine::end() { - Q_D(QBlitterPaintEngine); - - setActive(false); #ifdef QT_BLITTER_RASTEROVERLAY + Q_D(QBlitterPaintEngine); d->pmData->mergeOverlay(); #endif - return d->raster->end(); + + return QRasterPaintEngine::end(); } void QBlitterPaintEngine::setState(QPainterState *s) { Q_D(QBlitterPaintEngine); - d->lock(); - QPaintEngineEx::setState(s); - d->raster->setState(s); + QRasterPaintEngine::setState(s); d->updateCompleteState(s); } -inline QRasterPaintEngine *QBlitterPaintEngine::raster() const -{ - Q_D(const QBlitterPaintEngine); - return d->raster.data(); -} - // Accelerated paths void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { @@ -464,7 +438,7 @@ void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) } else { d->lock(); d->pmData->markRasterOverlay(path); - d->raster->fill(path, brush); + QRasterPaintEngine::fill(path, brush); } } @@ -476,7 +450,7 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color) } else { d->lock(); d->pmData->markRasterOverlay(rect); - d->raster->fillRect(rect, color); + QRasterPaintEngine::fillRect(rect, color); } } @@ -513,7 +487,7 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) blitWidth = transformedRect.right() -x; if (y + blitHeight > transformedRect.bottom()) blitHeight = transformedRect.bottom() - y; - const QClipData *clipData = clip(); + const QClipData *clipData = d->clip(); if (clipData->hasRectClip) { QRect targetRect = QRect(x, y, blitWidth, blitHeight).intersected(clipData->clipRect); if (targetRect.isValid()) { @@ -551,7 +525,7 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) } else { d->lock(); d->pmData->markRasterOverlay(rect); - d->raster->fillRect(rect, brush); + QRasterPaintEngine::fillRect(rect, brush); } } @@ -564,7 +538,7 @@ void QBlitterPaintEngine::drawRects(const QRect *rects, int rectCount) d->fillRect(rects[i], qbrush_color(state()->brush)); } else { d->pmData->markRasterOverlay(rects, rectCount); - QPaintEngineEx::drawRects(rects, rectCount); + QRasterPaintEngine::drawRects(rects, rectCount); } } @@ -576,10 +550,15 @@ void QBlitterPaintEngine::drawRects(const QRectF *rects, int rectCount) d->fillRect(rects[i], qbrush_color(state()->brush)); } else { d->pmData->markRasterOverlay(rects, rectCount); - QPaintEngineEx::drawRects(rects, rectCount); + QRasterPaintEngine::drawRects(rects, rectCount); } } +void QBlitterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm) +{ + drawPixmap(QRectF(pos, pm.size()), pm, pm.rect()); +} + void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) { Q_D(QBlitterPaintEngine); @@ -589,7 +568,7 @@ void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const Q QRectF targetRect = r; if (d->hasXForm) targetRect = state()->matrix.mapRect(r); - const QClipData *clipData = clip(); + const QClipData *clipData = d->clip(); if (clipData) { if (clipData->hasRectClip) { d->clipAndDrawPixmap(clipData->clipRect, targetRect, pm, sr); @@ -599,54 +578,60 @@ void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const Q d->clipAndDrawPixmap(rects.at(i), targetRect, pm, sr); } } else { - QRectF deviceRect(0,0,d->raster->paintDevice()->width(), d->raster->paintDevice()->height()); + QRectF deviceRect(0, 0, paintDevice()->width(), paintDevice()->height()); d->clipAndDrawPixmap(deviceRect, targetRect, pm, sr); } }else { d->lock(); d->pmData->markRasterOverlay(r); - d->raster->drawPixmap(r, pm, sr); + QRasterPaintEngine::drawPixmap(r, pm, sr); } } // Overriden methods to lock the graphics memory -void QBlitterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) +void QBlitterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QBlitterPaintEngine); d->lock(); - d->pmData->markRasterOverlay(path); - d->raster->stroke(path, pen); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPolygon(points, pointCount, mode); } -void QBlitterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) +void QBlitterPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clip(path, op); - d->updateClipState(state()); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPolygon(points, pointCount, mode); } -void QBlitterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op){ +void QBlitterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData) +{ Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clip(rect, op); - d->updateClipState(state()); + d->pmData->markRasterOverlay(path); + QRasterPaintEngine::fillPath(path, fillData); } -void QBlitterPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) +void QBlitterPaintEngine::fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clip(region, op); - d->updateClipState(state()); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::fillPolygon(points, pointCount, mode); } -void QBlitterPaintEngine::clipEnabledChanged() +void QBlitterPaintEngine::drawEllipse(const QRectF &r) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clipEnabledChanged(); - d->updateClipState(state()); + d->pmData->markRasterOverlay(r); + QRasterPaintEngine::drawEllipse(r); +} + +void QBlitterPaintEngine::drawImage(const QPointF &pos, const QImage &image) +{ + drawImage(QRectF(pos, image.size()), image, image.rect()); } void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, @@ -655,34 +640,59 @@ void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRe Q_D(QBlitterPaintEngine); d->lock(); d->pmData->markRasterOverlay(r); - d->raster->drawImage(r, pm, sr, flags); + QRasterPaintEngine::drawImage(r, pm, sr, flags); +} + +void QBlitterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) +{ + Q_D(QBlitterPaintEngine); + d->lock(); + d->pmData->markRasterOverlay(r); + QRasterPaintEngine::drawTiledPixmap(r, pm, sr); } void QBlitterPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &ti) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->drawTextItem(pos, ti); d->pmData->markRasterOverlay(pos, ti); + QRasterPaintEngine::drawTextItem(pos, ti); } -void QBlitterPaintEngine::drawStaticTextItem(QStaticTextItem *sti) +void QBlitterPaintEngine::drawPoints(const QPointF *points, int pointCount) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->drawStaticTextItem(sti); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPoints(points, pointCount); +} -//#### d->pmData->markRasterOverlay(sti); - qWarning("not implemented: markRasterOverlay for QStaticTextItem"); +void QBlitterPaintEngine::drawPoints(const QPoint *points, int pointCount) +{ + Q_D(QBlitterPaintEngine); + d->lock(); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPoints(points, pointCount); +} +void QBlitterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) +{ + Q_D(QBlitterPaintEngine); + d->lock(); + d->pmData->markRasterOverlay(path); + QRasterPaintEngine::stroke(path, pen); } -void QBlitterPaintEngine::drawEllipse(const QRectF &r) +void QBlitterPaintEngine::drawStaticTextItem(QStaticTextItem *sti) { Q_D(QBlitterPaintEngine); d->lock(); - d->pmData->markRasterOverlay(r); - d->raster->drawEllipse(r); + QRasterPaintEngine::drawStaticTextItem(sti); + +#ifdef QT_BLITTER_RASTEROVERLAY +//#### d->pmData->markRasterOverlay(sti); + qWarning("not implemented: markRasterOverlay for QStaticTextItem"); +#endif } QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h index 2cdb61a..14a30bc 100644 --- a/src/gui/painting/qpaintengine_blitter_p.h +++ b/src/gui/painting/qpaintengine_blitter_p.h @@ -42,7 +42,6 @@ #ifndef QPAINTENGINE_BLITTER_P_H #define QPAINTENGINE_BLITTER_P_H -#include "private/qpaintengineex_p.h" #include "private/qpaintengine_raster_p.h" #ifndef QT_NO_BLITTABLE @@ -52,14 +51,11 @@ class QBlitterPaintEnginePrivate; class QBlittablePixmapData; class QBlittable; -class Q_GUI_EXPORT QBlitterPaintEngine : public QPaintEngineEx +class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine { Q_DECLARE_PRIVATE(QBlitterPaintEngine); public: QBlitterPaintEngine(QBlittablePixmapData *p); - ~QBlitterPaintEngine(); - - virtual QPainterState *createState(QPainterState *orig) const; virtual QPaintEngine::Type type() const { return Blitter; } @@ -68,42 +64,38 @@ public: // Call down into QBlittable virtual void fill(const QVectorPath &path, const QBrush &brush); - virtual void stroke(const QVectorPath &path, const QPen &pen); virtual void fillRect(const QRectF &rect, const QBrush &brush); virtual void fillRect(const QRectF &rect, const QColor &color); virtual void drawRects(const QRect *rects, int rectCount); virtual void drawRects(const QRectF *rects, int rectCount); - virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); + void drawPixmap(const QPointF &p, const QPixmap &pm); + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); + // State tracking + void setState(QPainterState *s); virtual void clipEnabledChanged(); virtual void penChanged(); virtual void brushChanged(); - virtual void brushOriginChanged(); virtual void opacityChanged(); virtual void compositionModeChanged(); virtual void renderHintsChanged(); virtual void transformChanged(); // Override to lock the QBlittable before using raster - virtual void clip(const QVectorPath &path, Qt::ClipOperation op); - virtual void clip(const QRect &rect, Qt::ClipOperation op); - virtual void clip(const QRegion ®ion, Qt::ClipOperation op); - - virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags); - - virtual void drawTextItem(const QPointF &pos, const QTextItem &ti); - virtual void drawStaticTextItem(QStaticTextItem *); - - virtual void drawEllipse(const QRectF &r); - - virtual void setState(QPainterState *s); - - inline QPainterState *state() { return raster()->state(); } - inline const QPainterState *state() const { const QPainterState *state = raster()->state(); return state;} - inline const QClipData *clip(){return raster()->d_func()->clip();} - -private: - QRasterPaintEngine *raster() const; + void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); + void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); + void fillPath(const QPainterPath &path, QSpanData *fillData); + void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); + void drawEllipse(const QRectF &rect); + void drawImage(const QPointF &p, const QImage &img); + void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, + Qt::ImageConversionFlags flags = Qt::AutoColor); + void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr); + void drawTextItem(const QPointF &p, const QTextItem &textItem); + void drawPoints(const QPointF *points, int pointCount); + void drawPoints(const QPoint *points, int pointCount); + void stroke(const QVectorPath &path, const QPen &pen); + void drawStaticTextItem(QStaticTextItem *); }; QT_END_NAMESPACE |