aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {