aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Yin <yinyunqiao@gmail.com>2012-06-06 07:09:07 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-31 07:44:12 +0200
commit4236e7f7ee1d78c5adfebe719afb8b8a6dcd094b (patch)
tree9889d51119657f74951ad7642dc6a89c8c0d068b
parent9b671727010ccc45cc51840630b159cd34dd983d (diff)
Refactor context2d thread logic
1. Use QQuickContext2DRenderThread for Threaded rendering 2. Make FBO target works with all render strategies 3. Remove some unnessary locks, call texture methods by invoking meta calls 4. Run existing tests with all render targets and strategies (except Cooperative) Change-Id: I0db5c91d848b86bcc1536c30d7a5804b66a817f1 Reviewed-by: Yunqiao Yin <charles.yin@nokia.com>
-rw-r--r--examples/quick/canvas/bezierCurve/bezierCurve.qml2
-rw-r--r--examples/quick/canvas/clip/clip.qml2
-rw-r--r--examples/quick/canvas/contents/Stocks.qml147
-rw-r--r--examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml2
-rw-r--r--examples/quick/canvas/roundedrect/roundedrect.qml2
-rw-r--r--examples/quick/canvas/smile/smile.qml2
-rw-r--r--examples/quick/canvas/squircle/squircle.qml2
-rw-r--r--examples/quick/canvas/tiger/tiger.qml2
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp25
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h2
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp86
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h10
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp5
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp274
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h45
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml15
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_image.qml4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml9
18 files changed, 172 insertions, 464 deletions
diff --git a/examples/quick/canvas/bezierCurve/bezierCurve.qml b/examples/quick/canvas/bezierCurve/bezierCurve.qml
index f18c4a1608..6337b12eec 100644
--- a/examples/quick/canvas/bezierCurve/bezierCurve.qml
+++ b/examples/quick/canvas/bezierCurve/bezierCurve.qml
@@ -64,8 +64,6 @@ Item {
property real scaleY : scaleYCtrl.value
property real rotate : rotateCtrl.value
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
Behavior on scaleX { SpringAnimation { spring: 2; damping: 0.2; loops:Animation.Infinite } }
diff --git a/examples/quick/canvas/clip/clip.qml b/examples/quick/canvas/clip/clip.qml
index 3fdc3e4906..55c7913476 100644
--- a/examples/quick/canvas/clip/clip.qml
+++ b/examples/quick/canvas/clip/clip.qml
@@ -65,8 +65,6 @@ Item {
property real alpha:alphaCtrl.value
property string imagefile:"../contents/qt-logo.png"
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
Component.onCompleted:loadImage(canvas.imagefile);
onAlphaChanged:requestPaint();
diff --git a/examples/quick/canvas/contents/Stocks.qml b/examples/quick/canvas/contents/Stocks.qml
deleted file mode 100644
index 043bca132e..0000000000
--- a/examples/quick/canvas/contents/Stocks.qml
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-
-ListModel {
- id:stocks
- //Data from : http://en.wikipedia.org/wiki/NASDAQ-100
-
- ListElement {name:"Activision Blizzard"; stockId:"ATVI"}
- ListElement {name:"Adobe Systems Incorporated"; stockId:"ADBE"}
- ListElement {name:"Akamai Technologies, Inc"; stockId:"AKAM"}
- ListElement {name:"Alexion Pharmaceuticals"; stockId:"ALXN"}
- ListElement {name:"Altera Corporation"; stockId:"ALTR"}
- ListElement {name:"Amazon.com, Inc."; stockId:"AMZN"}
- ListElement {name:"Amgen Inc."; stockId:"AMGN"}
- ListElement {name:"Apollo Group, Inc."; stockId:"APOL"}
- ListElement {name:"Apple Inc."; stockId:"AAPL"}
- ListElement {name:"Applied Materials, Inc."; stockId:"AMAT"}
- ListElement {name:"Autodesk, Inc."; stockId:"ADSK"}
- ListElement {name:"Automatic Data Processing, Inc."; stockId:"ADP"}
- ListElement {name:"Baidu.com, Inc."; stockId:"BIDU"}
- ListElement {name:"Bed Bath & Beyond Inc."; stockId:"BBBY"}
- ListElement {name:"Biogen Idec, Inc"; stockId:"BIIB"}
- ListElement {name:"BMC Software, Inc."; stockId:"BMC"}
- ListElement {name:"Broadcom Corporation"; stockId:"BRCM"}
- ListElement {name:"C. H. Robinson Worldwide, Inc."; stockId:"CHRW"}
- ListElement {name:"CA, Inc."; stockId:"CA"}
- ListElement {name:"Celgene Corporation"; stockId:"CELG"}
- ListElement {name:"Cephalon, Inc."; stockId:"CEPH"}
- ListElement {name:"Cerner Corporation"; stockId:"CERN"}
- ListElement {name:"Check Point Software Technologies Ltd."; stockId:"CHKP"}
- ListElement {name:"Cisco Systems, Inc."; stockId:"CSCO"}
- ListElement {name:"Citrix Systems, Inc."; stockId:"CTXS"}
- ListElement {name:"Cognizant Technology Solutions Corporation"; stockId:"CTSH"}
- ListElement {name:"Comcast Corporation"; stockId:"CMCSA"}
- ListElement {name:"Costco Wholesale Corporation"; stockId:"COST"}
- ListElement {name:"Ctrip.com International, Ltd."; stockId:"CTRP"}
- ListElement {name:"Dell Inc."; stockId:"DELL"}
- ListElement {name:"DENTSPLY International Inc."; stockId:"XRAY"}
- ListElement {name:"DirecTV"; stockId:"DTV"}
- ListElement {name:"Dollar Tree, Inc."; stockId:"DLTR"}
- ListElement {name:"eBay Inc."; stockId:"EBAY"}
- ListElement {name:"Electronic Arts Inc."; stockId:"ERTS"}
- ListElement {name:"Expedia, Inc."; stockId:"EXPE"}
- ListElement {name:"Expeditors International of Washington, Inc."; stockId:"EXPD"}
- ListElement {name:"Express Scripts, Inc."; stockId:"ESRX"}
- ListElement {name:"F5 Networks, Inc."; stockId:"FFIV"}
- ListElement {name:"Fastenal Company"; stockId:"FAST"}
- ListElement {name:"First Solar, Inc."; stockId:"FSLR"}
- ListElement {name:"Fiserv, Inc."; stockId:"FISV"}
- ListElement {name:"Flextronics International Ltd."; stockId:"FLEX"}
- ListElement {name:"FLIR Systems, Inc."; stockId:"FLIR"}
- ListElement {name:"Garmin Ltd."; stockId:"GRMN"}
- ListElement {name:"Gilead Sciences, Inc."; stockId:"GILD"}
- ListElement {name:"Google Inc."; stockId:"GOOG"}
- ListElement {name:"Green Mountain Coffee Roasters, Inc."; stockId:"GMCR"}
- ListElement {name:"Henry Schein, Inc."; stockId:"HSIC"}
- ListElement {name:"Illumina, Inc."; stockId:"ILMN"}
- ListElement {name:"Infosys Technologies"; stockId:"INFY"}
- ListElement {name:"Intel Corporation"; stockId:"INTC"}
- ListElement {name:"Intuit, Inc."; stockId:"INTU"}
- ListElement {name:"Intuitive Surgical Inc."; stockId:"ISRG"}
- ListElement {name:"Joy Global Inc."; stockId:"JOYG"}
- ListElement {name:"KLA Tencor Corporation"; stockId:"KLAC"}
- ListElement {name:"Lam Research Corporation"; stockId:"LRCX"}
- ListElement {name:"Liberty Media Corporation, Interactive Series A"; stockId:"LINTA"}
- ListElement {name:"Life Technologies Corporation"; stockId:"LIFE"}
- ListElement {name:"Linear Technology Corporation"; stockId:"LLTC"}
- ListElement {name:"Marvell Technology Group, Ltd."; stockId:"MRVL"}
- ListElement {name:"Mattel, Inc."; stockId:"MAT"}
- ListElement {name:"Maxim Integrated Products"; stockId:"MXIM"}
- ListElement {name:"Microchip Technology Incorporated"; stockId:"MCHP"}
- ListElement {name:"Micron Technology, Inc."; stockId:"MU"}
- ListElement {name:"Microsoft Corporation"; stockId:"MSFT"}
- ListElement {name:"Mylan, Inc."; stockId:"MYL"}
- ListElement {name:"NetApp, Inc."; stockId:"NTAP"}
- ListElement {name:"Netflix, Inc."; stockId:"NFLX"}
- ListElement {name:"News Corporation, Ltd."; stockId:"NWSA"}
- ListElement {name:"NII Holdings, Inc."; stockId:"NIHD"}
- ListElement {name:"NVIDIA Corporation"; stockId:"NVDA"}
- ListElement {name:"O'Reilly Automotive, Inc."; stockId:"ORLY"}
- ListElement {name:"Oracle Corporation"; stockId:"ORCL"}
- ListElement {name:"PACCAR Inc."; stockId:"PCAR"}
- ListElement {name:"Paychex, Inc."; stockId:"PAYX"}
- ListElement {name:"Priceline.com, Incorporated"; stockId:"PCLN"}
- ListElement {name:"Qiagen N.V."; stockId:"QGEN"}
- ListElement {name:"QUALCOMM Incorporated"; stockId:"QCOM"}
- ListElement {name:"Research in Motion Limited"; stockId:"RIMM"}
- ListElement {name:"Ross Stores Inc."; stockId:"ROST"}
- ListElement {name:"SanDisk Corporation"; stockId:"SNDK"}
- ListElement {name:"Seagate Technology Holdings"; stockId:"STX"}
- ListElement {name:"Sears Holdings Corporation"; stockId:"SHLD"}
- ListElement {name:"Sigma-Aldrich Corporation"; stockId:"SIAL"}
- ListElement {name:"Staples Inc."; stockId:"SPLS"}
- ListElement {name:"Starbucks Corporation"; stockId:"SBUX"}
- ListElement {name:"Stericycle, Inc"; stockId:"SRCL"}
- ListElement {name:"Symantec Corporation"; stockId:"SYMC"}
- ListElement {name:"Teva Pharmaceutical Industries Ltd."; stockId:"TEVA"}
- ListElement {name:"Urban Outfitters, Inc."; stockId:"URBN"}
- ListElement {name:"VeriSign, Inc."; stockId:"VRSN"}
- ListElement {name:"Vertex Pharmaceuticals"; stockId:"VRTX"}
- ListElement {name:"Virgin Media, Inc."; stockId:"VMED"}
- ListElement {name:"Vodafone Group, plc."; stockId:"VOD"}
- ListElement {name:"Warner Chilcott, Ltd."; stockId:"WCRX"}
- ListElement {name:"Whole Foods Market, Inc."; stockId:"WFM"}
- ListElement {name:"Wynn Resorts Ltd."; stockId:"WYNN"}
- ListElement {name:"Xilinx, Inc."; stockId:"XLNX"}
- ListElement {name:"Yahoo! Inc."; stockId:"YHOO"}
-}
diff --git a/examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml b/examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml
index f0e2d11747..e7121c1a59 100644
--- a/examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml
+++ b/examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml
@@ -64,8 +64,6 @@ Item {
property real scaleY : scaleYCtrl.value
property real rotate : rotateCtrl.value
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
onLineWidthChanged:requestPaint();
onFillChanged:requestPaint();
diff --git a/examples/quick/canvas/roundedrect/roundedrect.qml b/examples/quick/canvas/roundedrect/roundedrect.qml
index a773895563..568b387fd7 100644
--- a/examples/quick/canvas/roundedrect/roundedrect.qml
+++ b/examples/quick/canvas/roundedrect/roundedrect.qml
@@ -54,8 +54,6 @@ Item {
width:320
height:280
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
property int radius: rCtrl.value
property int rectx: rxCtrl.value
diff --git a/examples/quick/canvas/smile/smile.qml b/examples/quick/canvas/smile/smile.qml
index 4ab040ce94..00ded9303a 100644
--- a/examples/quick/canvas/smile/smile.qml
+++ b/examples/quick/canvas/smile/smile.qml
@@ -55,8 +55,6 @@ Item {
width:320
height:280
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
property string strokeStyle:"green"
property string fillStyle:"yellow"
diff --git a/examples/quick/canvas/squircle/squircle.qml b/examples/quick/canvas/squircle/squircle.qml
index e3e764058d..a102dc4286 100644
--- a/examples/quick/canvas/squircle/squircle.qml
+++ b/examples/quick/canvas/squircle/squircle.qml
@@ -60,8 +60,6 @@ Item {
width:320
height:250
smooth:true
- renderTarget:Canvas.Image
- renderStrategy: Canvas.Immediate
property string strokeStyle:"blue"
property string fillStyle:"steelblue"
diff --git a/examples/quick/canvas/tiger/tiger.qml b/examples/quick/canvas/tiger/tiger.qml
index 620ba6a715..92fe2fe1a9 100644
--- a/examples/quick/canvas/tiger/tiger.qml
+++ b/examples/quick/canvas/tiger/tiger.qml
@@ -56,8 +56,6 @@ Item {
width:320
height:280
smooth:true
- renderTarget:Canvas.FramebufferObject
- renderStrategy: Canvas.Cooperative
property string strokeStyle:"steelblue"
property string fillStyle:"yellow"
property bool fill:true
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 939e7b4fba..16f08d3a3a 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -545,7 +545,6 @@ void QQuickCanvasItem::setRenderStrategy(QQuickCanvasItem::RenderStrategy strate
qmlInfo(this) << "Canvas:renderStrategy not changeable once context is active.";
return;
}
-
d->renderStrategy = strategy;
emit renderStrategyChanged();
}
@@ -603,6 +602,16 @@ void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry, const QRectF &
requestPaint();
}
+void QQuickCanvasItem::releaseResources()
+{
+ Q_D(QQuickCanvasItem);
+
+ if (d->context) {
+ delete d->context;
+ d->context = 0;
+ }
+}
+
void QQuickCanvasItem::componentComplete()
{
QQuickItem::componentComplete();
@@ -678,17 +687,9 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (!d->contextInitialized)
return 0;
- class CanvasTextureNode : public QSGSimpleTextureNode
- {
- public:
- CanvasTextureNode() : QSGSimpleTextureNode() {}
- ~CanvasTextureNode() {delete texture();}
- };
-
- CanvasTextureNode *node = static_cast<CanvasTextureNode*>(oldNode);
- if (!node) {
- node = new CanvasTextureNode;
- }
+ QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode*>(oldNode);
+ if (!node)
+ node = new QSGSimpleTextureNode;
if (d->renderStrategy == QQuickCanvasItem::Cooperative)
d->context->flush();
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index 4e592bcba7..be95c4a775 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -177,7 +177,7 @@ protected:
void updatePolish();
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-
+ void releaseResources();
private:
Q_DECLARE_PRIVATE(QQuickCanvasItem)
Q_INVOKABLE void delayedCreate();
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index f448c3fdfb..40a9b8e34c 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -63,8 +63,6 @@
#include <QtCore/qnumeric.h>
#include <private/qquickwindow_p.h>
#include <private/qquickwindowmanager_p.h>
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qplatformintegration.h>
#ifdef Q_OS_QNX
#include <ctype.h>
@@ -3265,6 +3263,11 @@ static int textAlignOffset(QQuickContext2D::TextAlignType value, const QFontMetr
return offset;
}
+void QQuickContext2D::setGrabbedImage(const QImage& grab)
+{
+ m_grabbedImage = grab;
+ m_grabbed = true;
+}
QQmlRefPointer<QQuickCanvasPixmap> QQuickContext2D::createPixmap(const QUrl& url)
{
@@ -3347,12 +3350,15 @@ QQuickContext2D::QQuickContext2D(QObject *parent)
, m_windowManager(0)
, m_surface(0)
, m_glContext(0)
+ , m_thread(0)
+ , m_grabbed(false)
{
}
QQuickContext2D::~QQuickContext2D()
{
delete m_buffer;
+ m_texture->deleteLater();
}
v8::Handle<v8::Object> QQuickContext2D::v8value() const
@@ -3378,15 +3384,10 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
switch (m_renderTarget) {
case QQuickCanvasItem::Image:
- m_texture = new QQuickContext2DImageTexture(m_renderStrategy == QQuickCanvasItem::Threaded);
+ m_texture = new QQuickContext2DImageTexture;
break;
case QQuickCanvasItem::FramebufferObject:
- {
m_texture = new QQuickContext2DFBOTexture;
- // No BufferQueueingOpenGL, falls back to Cooperative mode
- if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL))
- m_renderStrategy = QQuickCanvasItem::Cooperative;
- }
break;
}
@@ -3396,7 +3397,9 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
m_texture->setSmooth(canvasItem->smooth());
- QThread *renderThread = QThread::currentThread();
+ m_thread = QThread::currentThread();
+
+ QThread *renderThread = m_thread;
QThread *sceneGraphThread = window->openglContext() ? window->openglContext()->thread() : 0;
if (m_renderStrategy == QQuickCanvasItem::Threaded)
@@ -3404,6 +3407,9 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
else if (m_renderStrategy == QQuickCanvasItem::Cooperative)
renderThread = sceneGraphThread;
+ if (renderThread && renderThread != QThread::currentThread())
+ m_texture->moveToThread(renderThread);
+
if (m_renderTarget == QQuickCanvasItem::FramebufferObject && renderThread != sceneGraphThread) {
QOpenGLContext *cc = QQuickWindowPrivate::get(window)->context->glContext();
m_surface = window;
@@ -3421,32 +3427,24 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
{
- m_texture->canvasChanged(canvasSize, tileSize, canvasWindow, dirtyRect, 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));
}
void QQuickContext2D::flush()
{
- if (!m_buffer->isEmpty()) {
- QMutexLocker lock(&m_bufferMutex);
- m_bufferQueue.enqueue(m_buffer);
- m_buffer = new QQuickContext2DCommandBuffer;
- } else
- return;
-
- switch (m_renderStrategy) {
- case QQuickCanvasItem::Immediate:
- // Cause the texture to consume paint commands immediately
- m_texture->paint();
- break;
- case QQuickCanvasItem::Threaded:
- // wake up thread to consume paint commands
- m_texture->paint();
- break;
- case QQuickCanvasItem::Cooperative:
- // NOTE: On SG Thread
- m_texture->paint();
- break;
- }
+ if (m_buffer)
+ QMetaObject::invokeMethod(m_texture,
+ "paint",
+ Qt::AutoConnection,
+ Q_ARG(QQuickContext2DCommandBuffer*, m_buffer));
+ m_buffer = new QQuickContext2DCommandBuffer();
}
QSGDynamicTexture *QQuickContext2D::texture() const
@@ -3456,16 +3454,22 @@ QSGDynamicTexture *QQuickContext2D::texture() const
QImage QQuickContext2D::toImage(const QRectF& bounds)
{
- switch (m_renderStrategy) {
- case QQuickCanvasItem::Immediate:
- case QQuickCanvasItem::Threaded:
- flush();
- break;
- case QQuickCanvasItem::Cooperative:
- break;
+ flush();
+ if (m_texture->thread() == QThread::currentThread())
+ m_texture->grabImage(bounds);
+ else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
+ qWarning() << "Pixel read back is not support in Cooperative mode, please try Theaded or Immediate mode";
+ return QImage();
+ } else {
+ QMetaObject::invokeMethod(m_texture,
+ "grabImage",
+ Qt::BlockingQueuedConnection,
+ Q_ARG(QRectF, bounds));
}
-
- return m_texture->toImage(bounds);
+ QImage img = m_grabbedImage;
+ m_grabbedImage = QImage();
+ m_grabbed = false;
+ return img;
}
@@ -3696,7 +3700,7 @@ void QQuickContext2D::setV8Engine(QV8Engine *engine)
QQuickContext2DCommandBuffer* QQuickContext2D::nextBuffer()
{
- QMutexLocker lock(&m_bufferMutex);
+ QMutexLocker lock(&m_mutex);
return m_bufferQueue.isEmpty() ? 0 : m_bufferQueue.dequeue();
}
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index e2952ca580..295be051ba 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -53,7 +53,7 @@
#include <QtCore/qstack.h>
#include <QtCore/qqueue.h>
#include <private/qv8engine_p.h>
-
+#include <QtCore/QWaitCondition>
//#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
@@ -172,6 +172,7 @@ public:
void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
void flush();
void sync();
+ QThread *thread() const {return m_thread;}
QSGDynamicTexture *texture() const;
QImage toImage(const QRectF& bounds);
@@ -228,6 +229,7 @@ public:
QOpenGLContext *glContext() { return m_glContext; }
QSurface *surface() { return m_surface; }
+ void setGrabbedImage(const QImage& grab);
State state;
QStack<QQuickContext2D::State> m_stateStack;
@@ -246,7 +248,11 @@ public:
QQuickCanvasItem::RenderTarget m_renderTarget;
QQuickCanvasItem::RenderStrategy m_renderStrategy;
QQueue<QQuickContext2DCommandBuffer*> m_bufferQueue;
- QMutex m_bufferMutex;
+ QThread *m_thread;
+ QImage m_grabbedImage;
+ bool m_grabbed:1;
+
+ QMutex m_mutex;
};
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index 196981d971..47f7e1a90d 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -499,6 +499,11 @@ QQuickContext2DCommandBuffer::QQuickContext2DCommandBuffer()
, imageIdx(0)
, pixmapIdx(0)
{
+ static bool registered = false;
+ if (!registered) {
+ qRegisterMetaType<QQuickContext2DCommandBuffer*>("QQuickContext2DCommandBuffer*");
+ registered = true;
+ }
}
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index 2cb183d715..a315d30f8f 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -50,7 +50,6 @@
#include <QOpenGLFramebufferObject>
#include <QOpenGLFramebufferObjectFormat>
#include <QtCore/QThread>
-#include <QtCore/QCoreApplication>
QT_BEGIN_NAMESPACE
@@ -88,19 +87,14 @@ struct GLAcquireContext {
QOpenGLContext *ctx;
};
-Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance)
-
-
QQuickContext2DTexture::QQuickContext2DTexture()
: m_context(0)
, m_item(0)
, m_dirtyCanvas(false)
, m_canvasWindowChanged(false)
, m_dirtyTexture(false)
- , m_threadRendering(false)
, m_smooth(false)
, m_tiledCanvas(false)
- , m_doGrabImage(false)
, m_painting(false)
{
}
@@ -117,12 +111,9 @@ QSize QQuickContext2DTexture::textureSize() const
void QQuickContext2DTexture::markDirtyTexture()
{
- const bool inGrab = m_doGrabImage;
-
m_dirtyTexture = true;
updateTexture();
- if (!inGrab)
- emit textureChanged();
+ emit textureChanged();
}
bool QQuickContext2DTexture::setCanvasSize(const QSize &size)
@@ -185,8 +176,6 @@ bool QQuickContext2DTexture::setDirtyRect(const QRect &r)
void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
{
- lock();
-
QSize ts = tileSize;
if (ts.width() > canvasSize.width())
ts.setWidth(canvasSize.width());
@@ -209,20 +198,15 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize&
setDirtyRect(dirtyRect);
setSmooth(smooth);
-
- unlock();
}
-void QQuickContext2DTexture::paintWithoutTiles()
+void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb)
{
- QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer();
-
if (!ccb || ccb->isEmpty())
return;
QPaintDevice* device = beginPainting();
if (!device) {
- delete ccb;
endPainting();
return;
}
@@ -238,100 +222,58 @@ void QQuickContext2DTexture::paintWithoutTiles()
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
ccb->replay(&p, m_state);
- ccb->clear();
- delete ccb;
-
endPainting();
-
markDirtyTexture();
}
bool QQuickContext2DTexture::canvasDestroyed()
{
- bool noCanvas = false;
- lock();
- noCanvas = m_item == 0;
- unlock();
- return noCanvas;
+ return m_item == 0;
}
-void QQuickContext2DTexture::paint()
+void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)
{
- if (canvasDestroyed())
+ if (canvasDestroyed()) {
+ delete ccb;
return;
+ }
GLAcquireContext currentContext(m_context->glContext(), m_context->surface());
- if (m_threadRendering && QThread::currentThread() != globalCanvasThreadRenderInstance()) {
- Q_ASSERT(thread() == globalCanvasThreadRenderInstance());
- QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection);
+ if (!m_tiledCanvas) {
+ paintWithoutTiles(ccb);
+ delete ccb;
return;
}
- if (!m_tiledCanvas) {
- paintWithoutTiles();
- } else {
- lock();
- QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
- unlock();
-
- if (!tiledRegion.isEmpty()) {
- if (m_threadRendering && !m_doGrabImage) {
- QRect dirtyRect;
-
- lock();
- foreach (QQuickContext2DTile* tile, m_tiles) {
- if (tile->dirty()) {
- if (dirtyRect.isEmpty())
- dirtyRect = tile->rect();
- else
- dirtyRect |= tile->rect();
- }
- }
- unlock();
+ QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
+ if (!tiledRegion.isEmpty()) {
+ QRect dirtyRect;
+ foreach (QQuickContext2DTile* tile, m_tiles) {
+ if (tile->dirty()) {
+ if (dirtyRect.isEmpty())
+ dirtyRect = tile->rect();
+ else
+ dirtyRect |= tile->rect();
}
+ }
- if (beginPainting()) {
- QQuickContext2D::State oldState = m_state;
- QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer();
- if (!ccb || ccb->isEmpty()) {
- endPainting();
- delete ccb;
- return;
- }
- foreach (QQuickContext2DTile* tile, m_tiles) {
- bool dirtyTile = false, dirtyCanvas = false, smooth = false;
-
- lock();
- dirtyTile = tile->dirty();
- smooth = m_smooth;
- dirtyCanvas = m_dirtyCanvas;
- unlock();
-
- //canvas size or tile size may change during painting tiles
- if (dirtyCanvas) {
- if (m_threadRendering)
- QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection);
- endPainting();
- return;
- } else if (dirtyTile) {
- ccb->replay(tile->createPainter(smooth), oldState);
- tile->drawFinished();
- lock();
- tile->markDirty(false);
- unlock();
- }
-
- compositeTile(tile);
+ if (beginPainting()) {
+ QQuickContext2D::State oldState = m_state;
+ foreach (QQuickContext2DTile* tile, m_tiles) {
+ if (tile->dirty()) {
+ ccb->replay(tile->createPainter(m_smooth), oldState);
+ tile->drawFinished();
+ tile->markDirty(false);
}
- ccb->clear();
- delete ccb;
- endPainting();
- m_state = oldState;
- markDirtyTexture();
+ compositeTile(tile);
}
+ endPainting();
+ m_state = oldState;
+ markDirtyTexture();
}
}
+ delete ccb;
}
QRect QQuickContext2DTexture::tiledRect(const QRectF& window, const QSize& tileSize)
@@ -438,11 +380,15 @@ QQuickContext2DFBOTexture::QQuickContext2DFBOTexture()
, m_multisampledFbo(0)
, m_paint_device(0)
{
- m_threadRendering = false;
}
QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture()
{
+ if (m_multisampledFbo)
+ m_multisampledFbo->release();
+ else if (m_fbo)
+ m_fbo->release();
+
delete m_fbo;
delete m_multisampledFbo;
delete m_paint_device;
@@ -477,14 +423,7 @@ int QQuickContext2DFBOTexture::textureId() const
bool QQuickContext2DFBOTexture::updateTexture()
{
bool textureUpdated = m_dirtyTexture;
-
m_dirtyTexture = false;
-
- if (m_doGrabImage) {
- grabImage();
- m_condition.wakeOne();
- m_doGrabImage = false;
- }
return textureUpdated;
}
@@ -493,13 +432,6 @@ QQuickContext2DTile* QQuickContext2DFBOTexture::createTile() const
return new QQuickContext2DFBOTile();
}
-void QQuickContext2DFBOTexture::grabImage()
-{
- if (m_fbo) {
- m_grabedImage = m_fbo->toImage();
- }
-}
-
bool QQuickContext2DFBOTexture::doMultisampling() const
{
static bool extensionsChecked = false;
@@ -515,27 +447,22 @@ bool QQuickContext2DFBOTexture::doMultisampling() const
return multisamplingSupported && m_smooth;
}
-QImage QQuickContext2DFBOTexture::toImage(const QRectF& region)
+void QQuickContext2DFBOTexture::grabImage(const QRectF& rf)
{
- const unsigned long context2d_wait_max = 5000;
+ Q_ASSERT(rf.isValid());
- m_doGrabImage = true;
- if (m_item) // forces a call to updatePaintNode (repaints)
- m_item->update();
+ if (!m_fbo) {
+ m_context->setGrabbedImage(QImage());
+ return;
+ }
QImage grabbed;
- m_mutex.lock();
- bool ok = m_condition.wait(&m_mutex, context2d_wait_max);
-
- if (!ok)
- grabbed = QImage();
+ {
+ GLAcquireContext ctx(m_context->glContext(), m_context->surface());
+ grabbed = m_fbo->toImage().mirrored().copy(rf.toRect());
+ }
- if (region.isValid())
- grabbed = m_grabedImage.copy(region.toRect());
- else
- grabbed = m_grabedImage;
- m_grabedImage = QImage();
- return grabbed;
+ m_context->setGrabbedImage(grabbed);
}
void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile)
@@ -551,15 +478,17 @@ void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile)
QOpenGLFramebufferObject::blitFramebuffer(m_fbo, target, t->fbo(), source);
}
}
+
QQuickCanvasItem::RenderTarget QQuickContext2DFBOTexture::renderTarget() const
{
return QQuickCanvasItem::FramebufferObject;
}
+
QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
{
QQuickContext2DTexture::beginPainting();
- if (m_canvasWindow.size().isEmpty() && !m_threadRendering) {
+ if (m_canvasWindow.size().isEmpty()) {
delete m_fbo;
delete m_multisampledFbo;
delete m_paint_device;
@@ -615,78 +544,27 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
void QQuickContext2DFBOTexture::endPainting()
{
QQuickContext2DTexture::endPainting();
- if (m_multisampledFbo) {
+ if (m_multisampledFbo)
QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo);
- m_multisampledFbo->release();
- } else if (m_fbo)
- m_fbo->release();
-}
-void qt_quit_context2d_render_thread()
-{
- QThread* thread = globalCanvasThreadRenderInstance();
-
- if (thread->isRunning()) {
- thread->exit(0);
- thread->wait(1000);
- }
}
-QQuickContext2DImageTexture::QQuickContext2DImageTexture(bool threadRendering)
+QQuickContext2DImageTexture::QQuickContext2DImageTexture()
: QQuickContext2DTexture()
- , m_texture(new QSGPlainTexture())
+ , m_texture(0)
{
- m_texture->setOwnsTexture(true);
- m_texture->setHasMipmaps(false);
-
- m_threadRendering = threadRendering;
-
- if (m_threadRendering) {
- QThread* thread = globalCanvasThreadRenderInstance();
- moveToThread(thread);
-
- if (!thread->isRunning()) {
- qAddPostRoutine(qt_quit_context2d_render_thread); // XXX: change this method
- thread->start();
- }
- }
}
QQuickContext2DImageTexture::~QQuickContext2DImageTexture()
{
- delete m_texture;
+ if (m_texture && m_texture->thread() != QThread::currentThread())
+ m_texture->deleteLater();
+ else
+ delete m_texture;
}
int QQuickContext2DImageTexture::textureId() const
{
- return m_texture->textureId();
-}
-
-void QQuickContext2DImageTexture::lock()
-{
- if (m_threadRendering)
- m_mutex.lock();
-}
-void QQuickContext2DImageTexture::unlock()
-{
- if (m_threadRendering)
- m_mutex.unlock();
-}
-
-void QQuickContext2DImageTexture::wait()
-{
- if (m_threadRendering)
- m_waitCondition.wait(&m_mutex);
-}
-
-void QQuickContext2DImageTexture::wake()
-{
- if (m_threadRendering)
- m_waitCondition.wakeOne();
-}
-
-bool QQuickContext2DImageTexture::supportDirectRendering() const
-{
- return !m_threadRendering;
+ return imageTexture()->textureId();
}
QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const
@@ -696,14 +574,14 @@ QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const
void QQuickContext2DImageTexture::bind()
{
- m_texture->bind();
+ imageTexture()->bind();
}
bool QQuickContext2DImageTexture::updateTexture()
{
bool textureUpdated = m_dirtyTexture;
if (m_dirtyTexture) {
- m_texture->setImage(m_image);
+ imageTexture()->setImage(m_image);
m_dirtyTexture = false;
}
return textureUpdated;
@@ -714,26 +592,23 @@ QQuickContext2DTile* QQuickContext2DImageTexture::createTile() const
return new QQuickContext2DImageTile();
}
-void QQuickContext2DImageTexture::grabImage(const QRect& r)
+void QQuickContext2DImageTexture::grabImage(const QRectF& rf)
{
- m_doGrabImage = true;
- paint();
- m_doGrabImage = false;
- m_grabedImage = m_image.copy(r);
+ Q_ASSERT(rf.isValid());
+ Q_ASSERT(m_context);
+ QImage grabbed = m_image.copy(rf.toRect());
+ m_context->setGrabbedImage(grabbed);
}
-QImage QQuickContext2DImageTexture::toImage(const QRectF& rect)
+QSGPlainTexture *QQuickContext2DImageTexture::imageTexture() const
{
- QRect r = rect.isValid() ? rect.toRect() : QRect(QPoint(0, 0), m_canvasWindow.size());
- if (threadRendering()) {
- wake();
- QMetaObject::invokeMethod(this, "grabImage", Qt::BlockingQueuedConnection, Q_ARG(QRect, r));
- } else {
- QMetaObject::invokeMethod(this, "grabImage", Qt::DirectConnection, Q_ARG(QRect, r));
+ if (!m_texture) {
+ QQuickContext2DImageTexture *that = const_cast<QQuickContext2DImageTexture *>(this);
+ that->m_texture = new QSGPlainTexture;
+ that->m_texture->setOwnsTexture(true);
+ that->m_texture->setHasMipmaps(false);
}
- QImage image = m_grabedImage;
- m_grabedImage = QImage();
- return image;
+ return m_texture;
}
QPaintDevice* QQuickContext2DImageTexture::beginPainting()
@@ -762,14 +637,11 @@ void QQuickContext2DImageTexture::compositeTile(QQuickContext2DTile* tile)
source.moveTo(source.topLeft() - t->rect().topLeft());
target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
- lock();
m_painter.begin(&m_image);
m_painter.setCompositionMode(QPainter::CompositionMode_Source);
m_painter.drawImage(target, t->image(), source);
m_painter.end();
- unlock();
}
}
QT_END_NAMESPACE
-
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index 81b239dc16..684185572c 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -70,15 +70,7 @@ public:
virtual bool hasAlphaChannel() const {return true;}
virtual bool hasMipmaps() const {return false;}
virtual QSize textureSize() const;
- virtual void lock() {}
- virtual void unlock() {}
- virtual void wait() {}
- virtual void wake() {}
- bool threadRendering() const {return m_threadRendering;}
- virtual bool supportThreadRendering() const = 0;
- virtual bool supportDirectRendering() const = 0;
virtual QQuickCanvasItem::RenderTarget renderTarget() const = 0;
- virtual QImage toImage(const QRectF& region = QRectF()) = 0;
static QRect tiledRect(const QRectF& window, const QSize& tileSize);
bool setCanvasSize(const QSize &size);
@@ -86,18 +78,20 @@ public:
bool setCanvasWindow(const QRect& canvasWindow);
void setSmooth(bool smooth);
bool setDirtyRect(const QRect &dirtyRect);
- virtual void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
bool canvasDestroyed();
+
Q_SIGNALS:
void textureChanged();
public Q_SLOTS:
void markDirtyTexture();
void setItem(QQuickCanvasItem* item);
- void paint();
+ void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
+ void paint(QQuickContext2DCommandBuffer *ccb);
+ virtual void grabImage(const QRectF& region = QRectF()) = 0;
protected:
- void paintWithoutTiles();
+ void paintWithoutTiles(QQuickContext2DCommandBuffer *ccb);
virtual QPaintDevice* beginPainting() {m_painting = true; return 0; }
virtual void endPainting() {m_painting = false;}
virtual QQuickContext2DTile* createTile() const = 0;
@@ -120,10 +114,8 @@ protected:
uint m_dirtyCanvas : 1;
uint m_canvasWindowChanged : 1;
uint m_dirtyTexture : 1;
- uint m_threadRendering : 1;
uint m_smooth : 1;
uint m_tiledCanvas : 1;
- uint m_doGrabImage : 1;
uint m_painting : 1;
};
@@ -137,23 +129,19 @@ public:
virtual int textureId() const;
virtual bool updateTexture();
virtual QQuickContext2DTile* createTile() const;
- virtual QImage toImage(const QRectF& region = QRectF());
virtual QPaintDevice* beginPainting();
virtual void endPainting();
QRectF normalizedTextureSubRect() const;
- virtual bool supportThreadRendering() const {return false;}
- virtual bool supportDirectRendering() const {return false;}
virtual QQuickCanvasItem::RenderTarget renderTarget() const;
virtual void compositeTile(QQuickContext2DTile* tile);
virtual void bind();
QSize adjustedTileSize(const QSize &ts);
-private Q_SLOTS:
- void grabImage();
+public Q_SLOTS:
+ virtual void grabImage(const QRectF& region = QRectF());
private:
bool doMultisampling() const;
- QImage m_grabedImage;
QOpenGLFramebufferObject *m_fbo;
QOpenGLFramebufferObject *m_multisampledFbo;
QMutex m_mutex;
@@ -168,31 +156,24 @@ class QQuickContext2DImageTexture : public QQuickContext2DTexture
Q_OBJECT
public:
- QQuickContext2DImageTexture(bool threadRendering = true);
+ QQuickContext2DImageTexture();
~QQuickContext2DImageTexture();
virtual int textureId() const;
virtual void bind();
- virtual bool supportThreadRendering() const {return true;}
- virtual bool supportDirectRendering() const;
+
virtual QQuickCanvasItem::RenderTarget renderTarget() const;
- virtual void lock();
- virtual void unlock();
- virtual void wait();
- virtual void wake();
virtual bool updateTexture();
virtual QQuickContext2DTile* createTile() const;
- virtual QImage toImage(const QRectF& region = QRectF());
virtual QPaintDevice* beginPainting();
virtual void compositeTile(QQuickContext2DTile* tile);
-private Q_SLOTS:
- void grabImage(const QRect& r);
+public Q_SLOTS:
+ virtual void grabImage(const QRectF& region = QRectF());
+
private:
+ QSGPlainTexture *imageTexture() const;
QImage m_image;
- QImage m_grabedImage;
- QMutex m_mutex;
- QWaitCondition m_waitCondition;
QPainter m_painter;
QSGPlainTexture* m_texture;
};
diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
index 4aae317a7a..bc11d349fa 100644
--- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
@@ -13,13 +13,12 @@ TestCase {
function testData(type) {
if (type === "2d")
return [
- { tag:"image threaded", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Threaded}}
- //TODO: Enable the followings later
- //{ tag:"image cooperative", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Cooperative}},
- //{ tag:"image immediate", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Immediate}},
- //{ tag:"fbo cooperative", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Cooperative}},
- //{ tag:"fbo immediate", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Immediate}},
- //{ tag:"fbo threaded", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Threaded}}
+ { tag:"image threaded", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Threaded}},
+// { tag:"image cooperative", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Cooperative}},
+ { tag:"image immediate", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Immediate}},
+// { tag:"fbo cooperative", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Cooperative}},
+// { tag:"fbo immediate", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Immediate}},
+// { tag:"fbo threaded", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Threaded}}
];
return [];
}
@@ -43,4 +42,4 @@ TestCase {
qtest_fail('Pixel compare fail:\nactual :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d, 1);
}
-} \ No newline at end of file
+}
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
index 71931acae8..72b6dcdb00 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
@@ -653,7 +653,7 @@ CanvasTestCase {
var ctx = canvas.getContext('2d');
loadImages(canvas);
- var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas);
+ var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image; renderStrategy:Canvas.Immediate}", canvas);
canvas2.width = 100;
canvas2.height = 50;
var ctx2 = canvas2.getContext('2d');
@@ -704,4 +704,4 @@ CanvasTestCase {
comparePixel(ctx, 25,25, 255,0,0,255, 2);
comparePixel(ctx, 75,25, 255,0,0,255, 2);
}
-} \ No newline at end of file
+}
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
index 2966811021..2b39357bed 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml
@@ -23,16 +23,16 @@ CanvasTestCase {
];
var blues = [
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0,-1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 1, 0,
- 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
+ 1, 1, 1, 0,-1, 1, 1, 1, 0, 0,
1, 1, 0, 1, 1, 1, 1, 1, 0, 0,
1, 0, 0, 1, 1, 1, 1, 1, 0, 0,
1, 0, 0, 1, 1, 1, 1, 1, 0, 0,
- 1, 0, 0, 0, 1, 1, 1, 0, 0, 0
+ -1, 0, 0, 0, 1, 1, 1, 0, 0, 0
];
ctx.fillRule = Qt.OddEvenFill;
@@ -45,6 +45,7 @@ CanvasTestCase {
var x, y;
for (x=0; x < 10; x++) {
for (y=0; y < 10; y++) {
+ if (blues[y*10 +x] == -1) continue; //edge point, different render target may have different value
if (blues[y * 10 + x]) {
comparePixel(ctx, x * 5, y * 5, 0, 0, 255, 255);
} else {