From 6a1ee9667f42b98bd0a28d4beef8e15adbc241e1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 1 Jan 2012 22:12:34 +0100 Subject: [PATCH] blitter: Base QBlitterPaintEngine on QRasterPaintEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: I39bff11b32b1fe20284c7e8df60050de5991bb6e Reviewed-by: Jørgen Lind --- src/gui/image/qpixmap_blitter_p.h | 32 ++++ src/gui/painting/qpaintengine_blitter.cpp | 206 ++++++++++++---------- src/gui/painting/qpaintengine_blitter_p.h | 46 ++--- 3 files changed, 159 insertions(+), 125 deletions(-) diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index b0a9b7f848..50ac16889a 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 QBlittablePlatformPixmap::markRasterOverlay(const QRectF *rects, int #endif } +inline void QBlittablePlatformPixmap::markRasterOverlay(const QPointF *points, int pointCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(points); + Q_UNUSED(pointCount); +#endif +} + +inline void QBlittablePlatformPixmap::markRasterOverlay(const QPoint *points, int pointCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(points); + Q_UNUSED(pointCount); +#endif +} + +inline void QBlittablePlatformPixmap::markRasterOverlay(const QPainterPath& path) +{ +#ifdef QT_BLITTER_RASTEROVERLAY +#error "not ported yet" +#else + Q_UNUSED(path); +#endif +} + inline void QBlittablePlatformPixmap::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 6eeb97bb82..f8d6f037fa 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -180,19 +180,17 @@ private: uint capabillitiesState; }; -class QBlitterPaintEnginePrivate : public QPaintEngineExPrivate +class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate { Q_DECLARE_PUBLIC(QBlitterPaintEngine); public: QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p) - : QPaintEngineExPrivate() + : QRasterPaintEnginePrivate() , pmData(p) , caps(pmData->blittable()->capabilities()) , hasXForm(false) - { - raster.reset(new QRasterPaintEngine(p->buffer())); - } + {} void lock(); void unlock(); @@ -209,12 +207,6 @@ public: void updateTransformState(QPainterState *s); void updateClipState(QPainterState *s); - void systemStateChanged() { - raster->d_func()->systemStateChanged(); - } - - QScopedPointer raster; - QBlittablePlatformPixmap *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->clipData(); - 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->clipData();; + 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); } @@ -354,77 +344,70 @@ void QBlitterPaintEnginePrivate::clipAndDrawPixmap(const QRectF &clip, } QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePlatformPixmap *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; @@ -432,31 +415,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) { @@ -467,7 +441,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); } } @@ -479,7 +453,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); } } @@ -516,7 +490,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 = this->clipData(); + const QClipData *clipData = d->clip(); if (clipData->hasRectClip) { QRect targetRect = QRect(x, y, blitWidth, blitHeight).intersected(clipData->clipRect); if (targetRect.isValid()) { @@ -554,7 +528,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); } } @@ -567,7 +541,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); } } @@ -579,10 +553,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); @@ -592,7 +571,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 = this->clipData(); + const QClipData *clipData = d->clip(); if (clipData) { if (clipData->hasRectClip) { d->clipAndDrawPixmap(clipData->clipRect, targetRect, pm, sr); @@ -602,54 +581,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(points, pointCount); + QRasterPaintEngine::drawPolygon(points, pointCount, mode); +} + +void QBlitterPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) +{ + Q_D(QBlitterPaintEngine); + d->lock(); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPolygon(points, pointCount, mode); +} + +void QBlitterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData) { Q_D(QBlitterPaintEngine); d->lock(); d->pmData->markRasterOverlay(path); - d->raster->stroke(path, pen); + QRasterPaintEngine::fillPath(path, fillData); } -void QBlitterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) +void QBlitterPaintEngine::fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clip(path, op); - d->updateClipState(state()); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::fillPolygon(points, pointCount, mode); } -void QBlitterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op){ - Q_D(QBlitterPaintEngine); - d->lock(); - d->raster->clip(rect, op); - d->updateClipState(state()); -} - -void QBlitterPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) +void QBlitterPaintEngine::drawEllipse(const QRectF &r) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->clip(region, op); - d->updateClipState(state()); + d->pmData->markRasterOverlay(r); + QRasterPaintEngine::drawEllipse(r); } -void QBlitterPaintEngine::clipEnabledChanged() +void QBlitterPaintEngine::drawImage(const QPointF &pos, const QImage &image) { - Q_D(QBlitterPaintEngine); - d->lock(); - d->raster->clipEnabledChanged(); - d->updateClipState(state()); + drawImage(QRectF(pos, image.size()), image, image.rect()); } void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, @@ -658,34 +643,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::drawPoints(const QPointF *points, int pointCount) +{ + Q_D(QBlitterPaintEngine); + d->lock(); + d->pmData->markRasterOverlay(points, pointCount); + QRasterPaintEngine::drawPoints(points, pointCount); +} + +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::drawStaticTextItem(QStaticTextItem *sti) { Q_D(QBlitterPaintEngine); d->lock(); - d->raster->drawStaticTextItem(sti); + QRasterPaintEngine::drawStaticTextItem(sti); +#ifdef QT_BLITTER_RASTEROVERLAY //#### d->pmData->markRasterOverlay(sti); qWarning("not implemented: markRasterOverlay for QStaticTextItem"); - -} - -void QBlitterPaintEngine::drawEllipse(const QRectF &r) -{ - Q_D(QBlitterPaintEngine); - d->lock(); - d->pmData->markRasterOverlay(r); - d->raster->drawEllipse(r); +#endif } QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h index 105cf489c2..bb6eba496f 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 QBlittablePlatformPixmap; class QBlittable; -class Q_GUI_EXPORT QBlitterPaintEngine : public QPaintEngineEx +class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine { Q_DECLARE_PRIVATE(QBlitterPaintEngine); public: QBlitterPaintEngine(QBlittablePlatformPixmap *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 *clipData(){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