From aab15782e21bf0aaea7f2211278e9aa9fc78c6d7 Mon Sep 17 00:00:00 2001 From: Julien Brianceau Date: Mon, 10 Sep 2012 15:02:23 +0200 Subject: qpa: add non-opaque fill support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add non-opaque fill support for qpa through new QBlittable flag "AlphaFillRectCapability" and add related implementation in DirectFB qpa platform. Change-Id: I863a270e24c96c432489099a34dc1f3a2be52280 Reviewed-by: Qt Doc Bot Reviewed-by: Jørgen Lind --- src/gui/painting/qpaintengine_blitter.cpp | 66 +++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 11 deletions(-) (limited to 'src/gui/painting/qpaintengine_blitter.cpp') diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index d4e0a5967b..20dd98b9bf 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -73,6 +73,7 @@ public: , fillRectMask(0) , drawRectMask(0) , drawPixmapMask(0) + , alphaFillRectMask(0) , capabillitiesState(0) { if (capabilities & QBlittable::SolidRectCapability) @@ -83,6 +84,8 @@ public: setSourceOverPixmapMask(); if (capabilities & QBlittable::SourceOverScaledPixmapCapability) setSourceOverScaledPixmapMask(); + if (capabilities & QBlittable::AlphaFillRectCapability) + setAlphaFillRectMask(); } inline bool canBlitterFillRect() const @@ -90,6 +93,11 @@ public: return checkStateAgainstMask(capabillitiesState, fillRectMask); } + inline bool canBlitterAlphaFillRect() const + { + return checkStateAgainstMask(capabillitiesState, alphaFillRectMask); + } + inline bool canBlitterDrawRectMask() const { return checkStateAgainstMask(capabillitiesState, drawRectMask); @@ -147,6 +155,24 @@ private: updateStateBits(&fillRectMask, STATE_CLIP_COMPLEX, false); } + void setAlphaFillRectMask() { + updateStateBits(&alphaFillRectMask, STATE_XFORM_SCALE, false); + updateStateBits(&alphaFillRectMask, STATE_XFORM_COMPLEX, false); + + updateStateBits(&alphaFillRectMask, STATE_BRUSH_PATTERN, false); + updateStateBits(&alphaFillRectMask, STATE_BRUSH_ALPHA, true); + + updateStateBits(&alphaFillRectMask, STATE_PEN_ENABLED, true); + + //Sub-pixel aliasing should not be sent to the blitter + updateStateBits(&alphaFillRectMask, STATE_ANTIALIASING, true); + updateStateBits(&alphaFillRectMask, STATE_ALPHA, false); + updateStateBits(&alphaFillRectMask, STATE_BLENDING_COMPLEX, false); + + updateStateBits(&alphaFillRectMask, STATE_CLIPSYS_COMPLEX, false); + updateStateBits(&alphaFillRectMask, STATE_CLIP_COMPLEX, false); + } + void setSourcePixmapMask() { updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true); updateStateBits(&drawPixmapMask, STATE_XFORM_COMPLEX, false); @@ -177,6 +203,7 @@ private: uint fillRectMask; uint drawRectMask; uint drawPixmapMask; + uint alphaFillRectMask; uint capabillitiesState; }; @@ -194,7 +221,7 @@ public: void lock(); void unlock(); - void fillRect(const QRectF &rect, const QColor &color); + void fillRect(const QRectF &rect, const QColor &color, bool alpha); void clipAndDrawPixmap(const QRectF &clip, const QRectF &target, const QPixmap &pm, const QRectF &sr); @@ -287,7 +314,7 @@ void QBlitterPaintEnginePrivate::updateClipState(QPainterState *) caps.updateState(STATE_CLIP_COMPLEX, complexClip); } -void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &color) +void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &color, bool alpha) { Q_Q(QBlitterPaintEngine); pmData->unmarkRasterOverlay(rect); @@ -298,14 +325,20 @@ void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &colo if (clipData) { if (clipData->hasRectClip) { unlock(); - pmData->blittable()->fillRect(targetRect & clipData->clipRect, color); + if (alpha) + pmData->blittable()->alphaFillRect(targetRect & clipData->clipRect, color, q->state()->compositionMode()); + else + pmData->blittable()->fillRect(targetRect & clipData->clipRect, color); } else if (clipData->hasRegionClip) { QVector rects = clipData->clipRegion.rects(); for (int i = 0; i < rects.size(); ++i) { QRect intersectRect = rects.at(i).intersected(targetRect.toRect()); if (!intersectRect.isEmpty()) { unlock(); - pmData->blittable()->fillRect(intersectRect, color); + if (alpha) + pmData->blittable()->alphaFillRect(intersectRect, color, q->state()->compositionMode()); + else + pmData->blittable()->fillRect(intersectRect, color); } } } @@ -314,11 +347,17 @@ void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &colo && targetRect.width() <= q->paintDevice()->width() && targetRect.height() <= q->paintDevice()->height()) { unlock(); - pmData->blittable()->fillRect(targetRect, color); + if (alpha) + pmData->blittable()->alphaFillRect(targetRect, color, q->state()->compositionMode()); + else + pmData->blittable()->fillRect(targetRect, color); } else { QRectF deviceRect(0, 0, q->paintDevice()->width(), q->paintDevice()->height()); unlock(); - pmData->blittable()->fillRect(deviceRect & targetRect, color); + if (alpha) + pmData->blittable()->alphaFillRect(deviceRect & targetRect, color, q->state()->compositionMode()); + else + pmData->blittable()->fillRect(deviceRect & targetRect, color); } } } @@ -460,8 +499,10 @@ void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color) { Q_D(QBlitterPaintEngine); - if (d->caps.canBlitterFillRect() && color.alpha() == 0xff) { - d->fillRect(rect, color); + if (d->caps.canBlitterAlphaFillRect()) { + d->fillRect(rect, color, true); + } else if (d->caps.canBlitterFillRect() && color.alpha() == 0xff) { + d->fillRect(rect, color, false); } else { d->lock(); d->pmData->markRasterOverlay(rect); @@ -477,9 +518,12 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) Q_D(QBlitterPaintEngine); if (qbrush_style(brush) == Qt::SolidPattern + && d->caps.canBlitterAlphaFillRect()) { + d->fillRect(rect, qbrush_color(brush), true); + } else if (qbrush_style(brush) == Qt::SolidPattern && qbrush_color(brush).alpha() == 0xff && d->caps.canBlitterFillRect()) { - d->fillRect(rect, qbrush_color(brush)); + d->fillRect(rect, qbrush_color(brush), false); } else if (brush.style() == Qt::TexturePattern && d->caps.canBlitterDrawPixmap(rect, brush.texture(), rect)) { bool rectIsFilled = false; @@ -550,7 +594,7 @@ void QBlitterPaintEngine::drawRects(const QRect *rects, int rectCount) Q_D(QBlitterPaintEngine); if (d->caps.canBlitterDrawRectMask()) { for (int i=0; ifillRect(rects[i], qbrush_color(state()->brush)); + d->fillRect(rects[i], qbrush_color(state()->brush), false); } else { d->pmData->markRasterOverlay(rects, rectCount); QRasterPaintEngine::drawRects(rects, rectCount); @@ -562,7 +606,7 @@ void QBlitterPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QBlitterPaintEngine); if (d->caps.canBlitterDrawRectMask()) { for (int i = 0; i < rectCount; ++i) - d->fillRect(rects[i], qbrush_color(state()->brush)); + d->fillRect(rects[i], qbrush_color(state()->brush), false); } else { d->pmData->markRasterOverlay(rects, rectCount); QRasterPaintEngine::drawRects(rects, rectCount); -- cgit v1.2.3