From 373b8f06fa331c61efd9ba5075844df60a6a4412 Mon Sep 17 00:00:00 2001 From: Charles Yin Date: Mon, 27 Aug 2012 11:36:42 +1000 Subject: [PATCH] Use the new antialiasing property for canvas painting Change-Id: I76f21d055696978f2f6936006eea038dd73cce6c Reviewed-by: Michael Brasser --- src/quick/items/context2d/qquickcanvascontext.cpp | 3 ++- src/quick/items/context2d/qquickcanvascontext_p.h | 2 +- src/quick/items/context2d/qquickcanvasitem.cpp | 7 +++++- src/quick/items/context2d/qquickcontext2d.cpp | 21 +++++++++-------- src/quick/items/context2d/qquickcontext2d_p.h | 2 +- .../items/context2d/qquickcontext2dtexture.cpp | 27 +++++++++++++++------- .../items/context2d/qquickcontext2dtexture_p.h | 4 +++- src/quick/items/context2d/qquickcontext2dtile.cpp | 14 +++++++---- src/quick/items/context2d/qquickcontext2dtile_p.h | 2 +- .../qquickcanvasitem/data/CanvasComponent.qml | 1 - 10 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/quick/items/context2d/qquickcanvascontext.cpp b/src/quick/items/context2d/qquickcanvascontext.cpp index 39f178b..e40b689 100644 --- a/src/quick/items/context2d/qquickcanvascontext.cpp +++ b/src/quick/items/context2d/qquickcanvascontext.cpp @@ -53,13 +53,14 @@ QQuickCanvasContext::~QQuickCanvasContext() { } -void QQuickCanvasContext::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth) +void QQuickCanvasContext::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing) { Q_UNUSED(canvasSize); Q_UNUSED(tileSize); Q_UNUSED(canvasWindow); Q_UNUSED(dirtyRect); Q_UNUSED(smooth); + Q_UNUSED(antialiasing); } void QQuickCanvasContext::flush() diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h index 37ce698..66b1fc8 100644 --- a/src/quick/items/context2d/qquickcanvascontext_p.h +++ b/src/quick/items/context2d/qquickcanvascontext_p.h @@ -67,7 +67,7 @@ public: // Init (ignore options if necessary) virtual void init(QQuickCanvasItem *canvasItem, const QVariantMap &args) = 0; - virtual void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth); + virtual void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing); virtual void flush(); virtual void setV8Engine(QV8Engine *engine) = 0; diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 4eb8f62..5a29928 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -647,7 +647,7 @@ void QQuickCanvasItem::updatePolish() Q_D(QQuickCanvasItem); if (d->contextInitialized) - d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth); + d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing); if (d->animationCallbacks.size() > 0 && isVisible()) { QMap > animationCallbacks = d->animationCallbacks; @@ -691,6 +691,11 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (!node) node = new QSGSimpleTextureNode; + if (d->smooth) + node->setFiltering(QSGTexture::Linear); + else + node->setFiltering(QSGTexture::Nearest); + if (d->renderStrategy == QQuickCanvasItem::Cooperative) d->context->flush(); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 981e075..cb7f44a 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -3397,7 +3397,7 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args m_texture->setTileSize(canvasItem->tileSize()); m_texture->setCanvasSize(canvasItem->canvasSize().toSize()); m_texture->setSmooth(canvasItem->smooth()); - + m_texture->setAntialiasing(canvasItem->antialiasing()); m_thread = QThread::currentThread(); QThread *renderThread = m_thread; @@ -3426,16 +3426,17 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args reset(); } -void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth) +void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing) { - QMetaObject::invokeMethod(m_texture, - "canvasChanged", - Qt::AutoConnection, - Q_ARG(QSize, canvasSize), - Q_ARG(QSize, tileSize), - Q_ARG(QRect, canvasWindow), - Q_ARG(QRect, dirtyRect), - Q_ARG(bool, smooth)); + QMetaObject::invokeMethod(m_texture + , "canvasChanged" + , Qt::AutoConnection + , Q_ARG(QSize, canvasSize) + , Q_ARG(QSize, tileSize) + , Q_ARG(QRect, canvasWindow) + , Q_ARG(QRect, dirtyRect) + , Q_ARG(bool, smooth) + , Q_ARG(bool, antialiasing)); } void QQuickContext2D::flush() diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h index 295be05..b9621dd 100644 --- a/src/quick/items/context2d/qquickcontext2d_p.h +++ b/src/quick/items/context2d/qquickcontext2d_p.h @@ -169,7 +169,7 @@ public: QStringList contextNames() const; void init(QQuickCanvasItem *canvasItem, const QVariantMap &args); - void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth); + void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing); void flush(); void sync(); QThread *thread() const {return m_thread;} diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index a315d30..169c03b 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -93,7 +93,8 @@ QQuickContext2DTexture::QQuickContext2DTexture() , m_dirtyCanvas(false) , m_canvasWindowChanged(false) , m_dirtyTexture(false) - , m_smooth(false) + , m_smooth(true) + , m_antialiasing(false) , m_tiledCanvas(false) , m_painting(false) { @@ -141,6 +142,11 @@ void QQuickContext2DTexture::setSmooth(bool smooth) m_smooth = smooth; } +void QQuickContext2DTexture::setAntialiasing(bool antialiasing) +{ + m_antialiasing = antialiasing; +} + void QQuickContext2DTexture::setItem(QQuickCanvasItem* item) { m_item = item; @@ -174,7 +180,7 @@ bool QQuickContext2DTexture::setDirtyRect(const QRect &r) return doDirty; } -void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth) +void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing) { QSize ts = tileSize; if (ts.width() > canvasSize.width()) @@ -198,6 +204,7 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& setDirtyRect(dirtyRect); setSmooth(smooth); + setAntialiasing(antialiasing); } void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb) @@ -213,12 +220,16 @@ void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb QPainter p; p.begin(device); + if (m_antialiasing) + p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true); + else + p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false); + if (m_smooth) - p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing - | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); + p.setRenderHint(QPainter::SmoothPixmapTransform, true); else - p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing - | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false); + p.setRenderHint(QPainter::SmoothPixmapTransform, false); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); ccb->replay(&p, m_state); @@ -262,7 +273,7 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb) QQuickContext2D::State oldState = m_state; foreach (QQuickContext2DTile* tile, m_tiles) { if (tile->dirty()) { - ccb->replay(tile->createPainter(m_smooth), oldState); + ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState); tile->drawFinished(); tile->markDirty(false); } @@ -444,7 +455,7 @@ bool QQuickContext2DFBOTexture::doMultisampling() const extensionsChecked = true; } - return multisamplingSupported && m_smooth; + return multisamplingSupported && m_antialiasing; } void QQuickContext2DFBOTexture::grabImage(const QRectF& rf) diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 6841855..3730021 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -77,6 +77,7 @@ public: bool setTileSize(const QSize &size); bool setCanvasWindow(const QRect& canvasWindow); void setSmooth(bool smooth); + void setAntialiasing(bool antialiasing); bool setDirtyRect(const QRect &dirtyRect); bool canvasDestroyed(); @@ -86,7 +87,7 @@ Q_SIGNALS: public Q_SLOTS: void markDirtyTexture(); void setItem(QQuickCanvasItem* item); - void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth); + void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing); void paint(QQuickContext2DCommandBuffer *ccb); virtual void grabImage(const QRectF& region = QRectF()) = 0; @@ -115,6 +116,7 @@ protected: uint m_canvasWindowChanged : 1; uint m_dirtyTexture : 1; uint m_smooth : 1; + uint m_antialiasing : 1; uint m_tiledCanvas : 1; uint m_painting : 1; }; diff --git a/src/quick/items/context2d/qquickcontext2dtile.cpp b/src/quick/items/context2d/qquickcontext2dtile.cpp index 046300a..71aa0c9 100644 --- a/src/quick/items/context2d/qquickcontext2dtile.cpp +++ b/src/quick/items/context2d/qquickcontext2dtile.cpp @@ -60,7 +60,7 @@ QQuickContext2DTile::~QQuickContext2DTile() m_painter.end(); } -QPainter* QQuickContext2DTile::createPainter(bool smooth) +QPainter* QQuickContext2DTile::createPainter(bool smooth, bool antialiasing) { if (m_painter.isActive()) m_painter.end(); @@ -78,12 +78,16 @@ QPainter* QQuickContext2DTile::createPainter(bool smooth) v = 150; m_painter.fillRect(QRect(0, 0, m_rect.width(), m_rect.height()), QColor(v, v, v, 255)); #endif + + if (antialiasing) + m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true); + else + m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false); + if (smooth) - m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing - | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); + m_painter.setRenderHint(QPainter::SmoothPixmapTransform, true); else - m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing - | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false); + m_painter.setRenderHint(QPainter::SmoothPixmapTransform, false); m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver); m_painter.translate(-m_rect.left(), -m_rect.top()); diff --git a/src/quick/items/context2d/qquickcontext2dtile_p.h b/src/quick/items/context2d/qquickcontext2dtile_p.h index 2e6d61c..11f3618 100644 --- a/src/quick/items/context2d/qquickcontext2dtile_p.h +++ b/src/quick/items/context2d/qquickcontext2dtile_p.h @@ -64,7 +64,7 @@ public: QRect rect() const {return m_rect;} virtual void setRect(const QRect& r) = 0; - virtual QPainter* createPainter(bool smooth = false); + virtual QPainter* createPainter(bool smooth, bool antialiasing); virtual void drawFinished() {} protected: diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml index 12c1c89..b9e8d75 100644 --- a/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml +++ b/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml @@ -6,7 +6,6 @@ Component { Canvas { id:c width:100;height:100 - smooth:false //this line is needed for some tests (smooth painting can change the colors and alpha channel values) onPaint :{} //this line is needed for some tests (make sure onPaint handler always called property alias paintCount:spyPaint.count property alias paintedCount:spyPainted.count -- 2.7.4