/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qpaintengine_blitter_p.h"

#include "private/qblittable_p.h"
#include "private/qpaintengine_raster_p.h"
#include "private/qpainter_p.h"
#include "private/qpixmap_blitter_p.h"

#ifndef QT_NO_BLITTABLE
QT_BEGIN_NAMESPACE

#define STATE_XFORM_SCALE       0x00000001
#define STATE_XFORM_COMPLEX     0x00000002

#define STATE_BRUSH_PATTERN     0x00000010
#define STATE_BRUSH_ALPHA       0x00000020

#define STATE_PEN_ENABLED       0x00000100

#define STATE_ANTIALIASING      0x00001000
#define STATE_ALPHA             0x00002000
#define STATE_BLENDING_COMPLEX  0x00004000

#define STATE_CLIPSYS_COMPLEX   0x00010000
#define STATE_CLIP_COMPLEX      0x00020000


class CapabilitiesToStateMask
{
public:
    CapabilitiesToStateMask(QBlittable::Capabilities capabilities)
        : m_capabilities(capabilities)
        , fillRectMask(0)
        , drawRectMask(0)
        , drawPixmapMask(0)
        , alphaFillRectMask(0)
        , opacityPixmapMask(0)
        , capabillitiesState(0)
    {
        if (capabilities & QBlittable::SolidRectCapability)
            setFillRectMask();
        if (capabilities & QBlittable::SourcePixmapCapability)
           setSourcePixmapMask();
        if (capabilities & QBlittable::SourceOverPixmapCapability)
           setSourceOverPixmapMask();
        if (capabilities & QBlittable::SourceOverScaledPixmapCapability)
            setSourceOverScaledPixmapMask();
        if (capabilities & QBlittable::AlphaFillRectCapability)
            setAlphaFillRectMask();
        if (capabilities & QBlittable::OpacityPixmapCapability)
            setOpacityPixmapMask();
    }

    inline bool canBlitterFillRect() const
    {
        return checkStateAgainstMask(capabillitiesState, fillRectMask);
    }

    inline bool canBlitterAlphaFillRect() const
    {
        return checkStateAgainstMask(capabillitiesState, alphaFillRectMask);
    }

    inline bool canBlitterDrawRectMask() const
    {
        return checkStateAgainstMask(capabillitiesState, drawRectMask);
    }

    bool canBlitterDrawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) const
    {
        if (pm.handle()->classId() != QPlatformPixmap::BlitterClass)
            return false;
        if (checkStateAgainstMask(capabillitiesState, drawPixmapMask)) {
            if (m_capabilities & (QBlittable::SourceOverPixmapCapability
                                  | QBlittable::SourceOverScaledPixmapCapability)) {
                if (r.size() != sr.size())
                    return m_capabilities & QBlittable::SourceOverScaledPixmapCapability;
                else
                    return m_capabilities & QBlittable::SourceOverPixmapCapability;
            }
            if ((m_capabilities & QBlittable::SourcePixmapCapability) && r.size() == sr.size() && !pm.hasAlphaChannel())
                return m_capabilities & QBlittable::SourcePixmapCapability;
        }
        return false;
    }

    bool canBlitterDrawPixmapOpacity(const QPixmap &pm) const
    {
        if (pm.handle()->classId() != QPlatformPixmap::BlitterClass)
            return false;

        return checkStateAgainstMask(capabillitiesState, opacityPixmapMask);
    }

    bool canBlitterDrawCachedGlyphs(const QTransform &transform, QFontEngine::GlyphFormat requestedGlyphFormat, bool complexClip) const
    {
        if (transform.type() > QTransform::TxScale)
            return false;
        if (!(m_capabilities & QBlittable::DrawScaledCachedGlyphsCapability))
            return false;
        if (requestedGlyphFormat == QFontEngine::Format_ARGB && !(m_capabilities & QBlittable::SubPixelGlyphsCapability))
            return false;
        if (complexClip && !(m_capabilities & QBlittable::ComplexClipCapability))
            return false;
        return true;
    }

    inline void updateState(uint mask, bool on) {
        updateStateBits(&capabillitiesState, mask, on);
    }

private:

    static inline void updateStateBits(uint *state, uint mask, bool on)
    {
        *state = on ? (*state | mask) : (*state & ~mask);
    }

    static inline bool checkStateAgainstMask(uint state, uint mask)
    {
        return !state || (state & mask && !(state & ~mask));
    }

    void setFillRectMask() {
        updateStateBits(&fillRectMask, STATE_XFORM_SCALE, false);
        updateStateBits(&fillRectMask, STATE_XFORM_COMPLEX, false);

        updateStateBits(&fillRectMask, STATE_BRUSH_PATTERN, false);
        updateStateBits(&fillRectMask, STATE_BRUSH_ALPHA, false);

        updateStateBits(&fillRectMask, STATE_PEN_ENABLED, true);

        //Sub-pixel aliasing should not be sent to the blitter
        updateStateBits(&fillRectMask, STATE_ANTIALIASING, true);
        updateStateBits(&fillRectMask, STATE_ALPHA, false);
        updateStateBits(&fillRectMask, STATE_BLENDING_COMPLEX, false);

        updateStateBits(&fillRectMask, STATE_CLIPSYS_COMPLEX, false);
        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, false);
        updateStateBits(&drawPixmapMask, STATE_XFORM_COMPLEX, false);

        updateStateBits(&drawPixmapMask, STATE_BRUSH_PATTERN, true);
        updateStateBits(&drawPixmapMask, STATE_BRUSH_ALPHA, false);

        updateStateBits(&drawPixmapMask, STATE_PEN_ENABLED, true);

        updateStateBits(&drawPixmapMask, STATE_ANTIALIASING, true);
        updateStateBits(&drawPixmapMask, STATE_ALPHA, false);
        updateStateBits(&drawPixmapMask, STATE_BLENDING_COMPLEX, false);

        updateStateBits(&drawPixmapMask, STATE_CLIPSYS_COMPLEX, false);
        updateStateBits(&drawPixmapMask, STATE_CLIP_COMPLEX, false);
    }

    void setSourceOverPixmapMask() {
        setSourcePixmapMask();
    }

    void setSourceOverScaledPixmapMask() {
        setSourceOverPixmapMask();
        updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true);
    }

    void setOpacityPixmapMask() {
        updateStateBits(&opacityPixmapMask, STATE_XFORM_SCALE, true);
        updateStateBits(&opacityPixmapMask, STATE_XFORM_COMPLEX, false);

        updateStateBits(&opacityPixmapMask, STATE_BRUSH_PATTERN, true);
        updateStateBits(&opacityPixmapMask, STATE_BRUSH_ALPHA, true);

        updateStateBits(&opacityPixmapMask, STATE_PEN_ENABLED, true);

        updateStateBits(&opacityPixmapMask, STATE_ANTIALIASING, true);
        updateStateBits(&opacityPixmapMask, STATE_ALPHA, true);
        updateStateBits(&opacityPixmapMask, STATE_BLENDING_COMPLEX, false);

        updateStateBits(&opacityPixmapMask, STATE_CLIPSYS_COMPLEX, false);
        updateStateBits(&opacityPixmapMask, STATE_CLIP_COMPLEX, false);
    }

    QBlittable::Capabilities m_capabilities;
    uint fillRectMask;
    uint drawRectMask;
    uint drawPixmapMask;
    uint alphaFillRectMask;
    uint opacityPixmapMask;
    uint capabillitiesState;
};

class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate
{
    Q_DECLARE_PUBLIC(QBlitterPaintEngine)
public:
    QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p)
        : QRasterPaintEnginePrivate()
        , pmData(p)
        , caps(pmData->blittable()->capabilities())
        , hasXForm(false)

    {}

    void lock();
    void unlock();
    void fillRect(const QRectF &rect, const QColor &color, bool alpha);
    void clipAndDrawPixmap(const QRectF &clip, const QRectF &target, const QPixmap &pm, const QRectF &sr, bool opacity);


    void updateCompleteState(QPainterState *s);
    void updatePenState(QPainterState *s);
    void updateBrushState(QPainterState *s);
    void updateOpacityState(QPainterState *s);
    void updateCompositionModeState(QPainterState *s);
    void updateRenderHintsState(QPainterState *s);
    void updateTransformState(QPainterState *s);
    void updateClipState(QPainterState *s);

    QBlittablePlatformPixmap *pmData;
    CapabilitiesToStateMask caps;
    uint hasXForm;
};


inline void QBlitterPaintEnginePrivate::lock()
{
    if (!pmData->blittable()->isLocked())
        rasterBuffer->prepare(pmData->buffer());
}

inline void QBlitterPaintEnginePrivate::unlock()
{
    pmData->blittable()->unlock();
}

// State tracking to make decisions
void QBlitterPaintEnginePrivate::updateCompleteState(QPainterState *s)
{
    updatePenState(s);
    updateBrushState(s);
    updateOpacityState(s);
    updateCompositionModeState(s);
    updateRenderHintsState(s);
    updateTransformState(s);
    updateClipState(s);
}

void QBlitterPaintEnginePrivate::updatePenState(QPainterState *s)
{
    caps.updateState(STATE_PEN_ENABLED, qpen_style(s->pen) != Qt::NoPen);
}

void QBlitterPaintEnginePrivate::updateBrushState(QPainterState *s)
{
    Qt::BrushStyle style = qbrush_style(s->brush);

    caps.updateState(STATE_BRUSH_PATTERN, style != Qt::SolidPattern);
    caps.updateState(STATE_BRUSH_ALPHA,
                        qbrush_color(s->brush).alpha() < 255);
}

void QBlitterPaintEnginePrivate::updateOpacityState(QPainterState *s)
{
    bool translucent = s->opacity < 1;
    caps.updateState(STATE_ALPHA, translucent);
}

void QBlitterPaintEnginePrivate::updateCompositionModeState(QPainterState *s)
{
    bool nonTrivial = s->composition_mode != QPainter::CompositionMode_SourceOver
                      && s->composition_mode != QPainter::CompositionMode_Source;

    caps.updateState(STATE_BLENDING_COMPLEX, nonTrivial);
}

void QBlitterPaintEnginePrivate::updateRenderHintsState(QPainterState *s)
{
    bool aa = s->renderHints & QPainter::Antialiasing;
    caps.updateState(STATE_ANTIALIASING, aa);
}

void QBlitterPaintEnginePrivate::updateTransformState(QPainterState *s)
{
    QTransform::TransformationType type = s->matrix.type();

    // consider scaling operations with a negative factor as "complex" for now.
    // as some blitters could handle axisymmetrical operations, we should improve blitter
    // paint engine to handle them as a capability
    caps.updateState(STATE_XFORM_COMPLEX, (type > QTransform::TxScale) ||
        ((type == QTransform::TxScale) && ((s->matrix.m11() < 0.0) || (s->matrix.m22() < 0.0))));
    caps.updateState(STATE_XFORM_SCALE, type > QTransform::TxTranslate);

    hasXForm = type >= QTransform::TxTranslate;
}

void QBlitterPaintEnginePrivate::updateClipState(QPainterState *)
{
    const QClipData *clipData = clip();
    bool complexClip = clipData && !(clipData->hasRectClip || clipData->hasRegionClip);
    caps.updateState(STATE_CLIP_COMPLEX, complexClip);
}

void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &color, bool alpha)
{
    Q_Q(QBlitterPaintEngine);
    pmData->unmarkRasterOverlay(rect);
    QRectF targetRect = rect;
    if (hasXForm)
        targetRect = q->state()->matrix.mapRect(rect);
    const QClipData *clipData = clip();
    if (clipData) {
        if (clipData->hasRectClip) {
            unlock();
            if (alpha)
                pmData->blittable()->alphaFillRect(targetRect & clipData->clipRect, color, q->state()->compositionMode());
            else
                pmData->blittable()->fillRect(targetRect & clipData->clipRect, color);
        } else if (clipData->hasRegionClip) {
            for (const QRect &rect : clipData->clipRegion) {
                QRect intersectRect = rect.intersected(targetRect.toRect());
                if (!intersectRect.isEmpty()) {
                    unlock();
                    if (alpha)
                        pmData->blittable()->alphaFillRect(intersectRect, color, q->state()->compositionMode());
                    else
                        pmData->blittable()->fillRect(intersectRect, color);
                }
            }
        }
    } else {
        if (targetRect.x() >= 0 && targetRect.y() >= 0
            && targetRect.width() <= q->paintDevice()->width()
            && targetRect.height() <= q->paintDevice()->height()) {
            unlock();
            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();
            if (alpha)
                pmData->blittable()->alphaFillRect(deviceRect & targetRect, color, q->state()->compositionMode());
            else
                pmData->blittable()->fillRect(deviceRect & targetRect, color);
        }
    }
}

void QBlitterPaintEnginePrivate::clipAndDrawPixmap(const QRectF &clip,
                                                   const QRectF &target,
                                                   const QPixmap &pm,
                                                   const QRectF &sr,
                                                   bool  opacity)
{
    Q_Q(QBlitterPaintEngine);
    QRectF intersectedRect = clip.intersected(target);
    if (intersectedRect.isEmpty())
        return;
    QRectF source = sr;
    if (intersectedRect.size() != target.size()) {
        if (sr.size() == target.size()) {
            // no resize
            qreal deltaTop = target.top() - intersectedRect.top();
            qreal deltaLeft = target.left() - intersectedRect.left();
            qreal deltaBottom = target.bottom() - intersectedRect.bottom();
            qreal deltaRight = target.right() - intersectedRect.right();
            source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom);
        } else {
            // resize case
            qreal hFactor = sr.size().width() / target.size().width();
            qreal vFactor = sr.size().height() / target.size().height();
            qreal deltaTop = (target.top() - intersectedRect.top()) * vFactor;
            qreal deltaLeft = (target.left() - intersectedRect.left()) * hFactor;
            qreal deltaBottom = (target.bottom() - intersectedRect.bottom()) * vFactor;
            qreal deltaRight = (target.right() - intersectedRect.right()) * hFactor;
            source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom);
        }
    }
    pmData->unmarkRasterOverlay(intersectedRect);
    if (opacity)
        pmData->blittable()->drawPixmapOpacity(intersectedRect, pm, source, q->state()->compositionMode(), q->state()->opacity);
    else
        pmData->blittable()->drawPixmap(intersectedRect, pm, source);
}

QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePlatformPixmap *p)
    : QRasterPaintEngine(*(new QBlitterPaintEnginePrivate(p)), p->buffer())
{}

// State tracking
void QBlitterPaintEngine::penChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::penChanged();
    d->updatePenState(state());
}

void QBlitterPaintEngine::brushChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::brushChanged();
    d->updateBrushState(state());
}

void QBlitterPaintEngine::opacityChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::opacityChanged();
    d->updateOpacityState(state());
}

void QBlitterPaintEngine::compositionModeChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::compositionModeChanged();
    d->updateCompositionModeState(state());
}

void QBlitterPaintEngine::renderHintsChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::renderHintsChanged();
    d->updateRenderHintsState(state());
}

void QBlitterPaintEngine::transformChanged()
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::transformChanged();
    d->updateTransformState(state());
}

void QBlitterPaintEngine::clipEnabledChanged()
{
    Q_D(QBlitterPaintEngine);
    QRasterPaintEngine::clipEnabledChanged();
    d->updateClipState(state());
}

bool QBlitterPaintEngine::begin(QPaintDevice *pdev)
{
    Q_D(QBlitterPaintEngine);
    bool ok = QRasterPaintEngine::begin(pdev);
#ifdef QT_BLITTER_RASTEROVERLAY
    d->pmData->unmergeOverlay();
#endif
    d->pdev = pdev;
    return ok;
}

bool QBlitterPaintEngine::end()
{
#ifdef QT_BLITTER_RASTEROVERLAY
    Q_D(QBlitterPaintEngine);
    d->pmData->mergeOverlay();
#endif

    return QRasterPaintEngine::end();
}

void QBlitterPaintEngine::setState(QPainterState *s)
{
    Q_D(QBlitterPaintEngine);

    QRasterPaintEngine::setState(s);
    d->updateCompleteState(s);
}

// Accelerated paths
void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
{
    Q_D(QBlitterPaintEngine);
    if (path.shape() == QVectorPath::RectangleHint) {
        QRectF rect(((const QPointF *) path.points())[0], ((const QPointF *) path.points())[2]);
        fillRect(rect, brush);
    } else {
        d->lock();
        d->pmData->markRasterOverlay(path);
        QRasterPaintEngine::fill(path, brush);
    }
}

void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color)
{
    Q_D(QBlitterPaintEngine);
    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);
        QRasterPaintEngine::fillRect(rect, color);
    }
}

void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
{
    if (rect.size().isEmpty())
        return;

    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), false);
    } else if ((brush.style() == Qt::TexturePattern) &&
               (brush.transform().type() <= QTransform::TxTranslate) &&
                ((d->caps.canBlitterDrawPixmapOpacity(brush.texture())) ||
                 (d->caps.canBlitterDrawPixmap(rect, brush.texture(), rect)))) {
        bool rectIsFilled = false;
        QRectF transformedRect = state()->matrix.mapRect(rect);
        qreal x = transformedRect.x();
        qreal y = transformedRect.y();
        QPixmap pm = brush.texture();
        d->unlock();
        int srcX = int(rect.x() - state()->brushOrigin.x() - brush.transform().dx()) % pm.width();
        if (srcX < 0)
            srcX = pm.width() + srcX;
        const int startX = srcX;
        int srcY = int(rect.y() - state()->brushOrigin.y() - brush.transform().dy()) % pm.height();
        if (srcY < 0)
            srcY = pm.height() + srcY;
        while (!rectIsFilled) {
            qreal blitWidth = (pm.width() ) - srcX;
            qreal blitHeight = (pm.height() ) - srcY;
            if (x + blitWidth > transformedRect.right())
                blitWidth = transformedRect.right() -x;
            if (y + blitHeight > transformedRect.bottom())
                blitHeight = transformedRect.bottom() - y;
            const QClipData *clipData = d->clip();
            if (clipData->hasRectClip) {
                QRect targetRect = QRect(x, y, blitWidth, blitHeight).intersected(clipData->clipRect);
                if (targetRect.isValid()) {
                    int tmpSrcX  = srcX + (targetRect.x() - x);
                    int tmpSrcY = srcY + (targetRect.y() - y);
                    QRect srcRect(tmpSrcX, tmpSrcY, targetRect.width(), targetRect.height());
                    d->pmData->blittable()->drawPixmap(targetRect, pm, srcRect);
                }
            } else if (clipData->hasRegionClip) {
                QRect unclippedTargetRect(x, y, blitWidth, blitHeight);
                const QRegion targetRegion = clipData->clipRegion.intersected(unclippedTargetRect);
                for (const QRect &targetRect : targetRegion) {
                    if (!targetRect.isValid() || targetRect.isEmpty())
                        continue;
                    int tmpSrcX = srcX + (targetRect.x() - x);
                    int tmpSrcY = srcY + (targetRect.y() - y);
                    QRect srcRect(tmpSrcX, tmpSrcY, targetRect.width(), targetRect.height());
                    d->pmData->blittable()->drawPixmap(targetRect, pm, srcRect);
                }
            }
            x+=blitWidth;
            if (qFuzzyCompare(x, transformedRect.right())) {
                x = transformedRect.x();
                srcX = startX;
                srcY = 0;
                y += blitHeight;
                if (qFuzzyCompare(y, transformedRect.bottom()))
                    rectIsFilled = true;
            } else
                srcX = 0;
        }
    } else {
        d->lock();
        d->pmData->markRasterOverlay(rect);
        QRasterPaintEngine::fillRect(rect, brush);
    }

}

void QBlitterPaintEngine::drawRects(const QRect *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), false);
    } else {
        d->pmData->markRasterOverlay(rects, rectCount);
        QRasterPaintEngine::drawRects(rects, rectCount);
    }
}

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), false);
    } else {
        d->pmData->markRasterOverlay(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);
    bool canDrawOpacity;

    canDrawOpacity = d->caps.canBlitterDrawPixmapOpacity(pm);
    if (canDrawOpacity || (d->caps.canBlitterDrawPixmap(r, pm, sr))) {

        d->unlock();
        QRectF targetRect = r;
        if (d->hasXForm)
            targetRect = state()->matrix.mapRect(r);
        const QClipData *clipData = d->clip();
        if (clipData) {
            if (clipData->hasRectClip) {
                d->clipAndDrawPixmap(clipData->clipRect, targetRect, pm, sr, canDrawOpacity);
            } else if (clipData->hasRegionClip) {
                for (const QRect &rect : clipData->clipRegion)
                    d->clipAndDrawPixmap(rect, targetRect, pm, sr, canDrawOpacity);
            }
        } else {
            QRectF deviceRect(0, 0, paintDevice()->width(), paintDevice()->height());
            d->clipAndDrawPixmap(deviceRect, targetRect, pm, sr, canDrawOpacity);
        }
    }else {
        d->lock();
        d->pmData->markRasterOverlay(r);
        QRasterPaintEngine::drawPixmap(r, pm, sr);
    }
}

// Overridden methods to lock the graphics memory
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);
    QRasterPaintEngine::fillPath(path, fillData);
}

void QBlitterPaintEngine::fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
    Q_D(QBlitterPaintEngine);
    d->lock();
    d->pmData->markRasterOverlay(points, pointCount);
    QRasterPaintEngine::fillPolygon(points, pointCount, mode);
}

void QBlitterPaintEngine::drawEllipse(const QRectF &r)
{
    Q_D(QBlitterPaintEngine);
    d->lock();
    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,
                                    Qt::ImageConversionFlags flags)
{
    Q_D(QBlitterPaintEngine);
    d->lock();
    d->pmData->markRasterOverlay(r);
    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->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();
    QRasterPaintEngine::drawStaticTextItem(sti);

#ifdef QT_BLITTER_RASTEROVERLAY
//#### d->pmData->markRasterOverlay(sti);
    qWarning("not implemented: markRasterOverlay for QStaticTextItem");
#endif
}

bool QBlitterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine)
{
    Q_D(QBlitterPaintEngine);
    QFontEngine::GlyphFormat glyphFormat = d->glyphCacheFormat;
    if (fontEngine->glyphFormat != QFontEngine::Format_None)
        glyphFormat = fontEngine->glyphFormat;

    const QClipData *clipData = d->clip();
    const bool complexClip = clipData && !clipData->hasRectClip;

    const QPainterState *s = state();
    if (d->caps.canBlitterDrawCachedGlyphs(s->transform(), glyphFormat, complexClip)) {
        d->unlock();
        const bool result = d->pmData->blittable()->drawCachedGlyphs(s, glyphFormat, numGlyphs, glyphs, positions, fontEngine);
        // Lock again as the raster paint engine might draw decorations now.
        d->lock();
        return result;
    } else {
        return QRasterPaintEngine::drawCachedGlyphs(numGlyphs, glyphs, positions, fontEngine);
    }
}

QT_END_NAMESPACE
#endif //QT_NO_BLITTABLE

