Continue refactor of Canvas rendering.
- Remove sync() - not necessary - Queue buffer before flush Change-Id: If7dea8e56a612d241c67a82eae265febc45059a8 Reviewed-by: Yunqiao Yin <charles.yin@nokia.com>
This commit is contained in:
parent
eab48686b2
commit
fd57a4059a
|
@ -66,10 +66,6 @@ void QQuickCanvasContext::flush()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QQuickCanvasContext::sync()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,13 +68,8 @@ public:
|
||||||
virtual void init(QQuickCanvasItem *canvasItem, const QVariantMap &args) = 0;
|
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);
|
||||||
|
|
||||||
// Indicate this is a good time to begin composition
|
|
||||||
virtual void flush();
|
virtual void flush();
|
||||||
|
|
||||||
// Cause render (if necessary) to surface via execution unit
|
|
||||||
virtual void sync();
|
|
||||||
|
|
||||||
virtual void setV8Engine(QV8Engine *engine) = 0;
|
virtual void setV8Engine(QV8Engine *engine) = 0;
|
||||||
virtual v8::Handle<v8::Object> v8value() const = 0;
|
virtual v8::Handle<v8::Object> v8value() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -549,8 +549,12 @@ void QQuickCanvasItem::updatePolish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->contextInitialized)
|
if (d->contextInitialized) {
|
||||||
d->context->flush();
|
if (d->renderStrategy == QQuickCanvasItem::Cooperative)
|
||||||
|
update();
|
||||||
|
else
|
||||||
|
d->context->flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
|
QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
|
||||||
|
@ -566,7 +570,7 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->renderStrategy == QQuickCanvasItem::Cooperative)
|
if (d->renderStrategy == QQuickCanvasItem::Cooperative)
|
||||||
d->context->sync();
|
d->context->flush();
|
||||||
|
|
||||||
node->setTexture(d->context->texture());
|
node->setTexture(d->context->texture());
|
||||||
node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
|
node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
|
||||||
|
|
|
@ -100,21 +100,6 @@ QT_BEGIN_NAMESPACE
|
||||||
\image qml-item-canvas-context.gif
|
\image qml-item-canvas-context.gif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QLockedCommandBuffer::QLockedCommandBuffer(QQuickContext2DCommandBuffer *b)
|
|
||||||
: m_buffer(b)
|
|
||||||
{
|
|
||||||
m_buffer->lockQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
QLockedCommandBuffer::~QLockedCommandBuffer()
|
|
||||||
{
|
|
||||||
m_buffer->unlockQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
QQuickContext2DCommandBuffer* QLockedCommandBuffer::operator->() const
|
|
||||||
{
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
|
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
|
||||||
|
@ -3196,7 +3181,7 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
|
||||||
|
|
||||||
switch (m_renderTarget) {
|
switch (m_renderTarget) {
|
||||||
case QQuickCanvasItem::Image:
|
case QQuickCanvasItem::Image:
|
||||||
m_texture = new QQuickContext2DImageTexture(m_renderStrategy == QQuickCanvasItem::Threaded); // ?? || Coop
|
m_texture = new QQuickContext2DImageTexture(m_renderStrategy == QQuickCanvasItem::Threaded);
|
||||||
break;
|
break;
|
||||||
case QQuickCanvasItem::FramebufferObject:
|
case QQuickCanvasItem::FramebufferObject:
|
||||||
m_texture = new QQuickContext2DFBOTexture;
|
m_texture = new QQuickContext2DFBOTexture;
|
||||||
|
@ -3221,6 +3206,13 @@ void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, co
|
||||||
|
|
||||||
void QQuickContext2D::flush()
|
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) {
|
switch (m_renderStrategy) {
|
||||||
case QQuickCanvasItem::Immediate:
|
case QQuickCanvasItem::Immediate:
|
||||||
// Cause the texture to consume paint commands immediately
|
// Cause the texture to consume paint commands immediately
|
||||||
|
@ -3231,19 +3223,12 @@ void QQuickContext2D::flush()
|
||||||
m_texture->paint();
|
m_texture->paint();
|
||||||
break;
|
break;
|
||||||
case QQuickCanvasItem::Cooperative:
|
case QQuickCanvasItem::Cooperative:
|
||||||
// Add to the update list in SG
|
// NOTE: On SG Thread
|
||||||
m_canvas->update(); // FIXME
|
m_texture->paint();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On SG render thread
|
|
||||||
void QQuickContext2D::sync()
|
|
||||||
{
|
|
||||||
if (m_renderStrategy == QQuickCanvasItem::Cooperative)
|
|
||||||
m_texture->paint();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSGDynamicTexture *QQuickContext2D::texture() const
|
QSGDynamicTexture *QQuickContext2D::texture() const
|
||||||
{
|
{
|
||||||
return m_texture;
|
return m_texture;
|
||||||
|
@ -3251,6 +3236,15 @@ QSGDynamicTexture *QQuickContext2D::texture() const
|
||||||
|
|
||||||
QImage QQuickContext2D::toImage(const QRectF& bounds)
|
QImage QQuickContext2D::toImage(const QRectF& bounds)
|
||||||
{
|
{
|
||||||
|
switch (m_renderStrategy) {
|
||||||
|
case QQuickCanvasItem::Immediate:
|
||||||
|
case QQuickCanvasItem::Threaded:
|
||||||
|
flush();
|
||||||
|
break;
|
||||||
|
case QQuickCanvasItem::Cooperative:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return m_texture->toImage(bounds);
|
return m_texture->toImage(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3475,4 +3469,10 @@ void QQuickContext2D::setV8Engine(QV8Engine *engine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQuickContext2DCommandBuffer* QQuickContext2D::nextBuffer()
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_bufferMutex);
|
||||||
|
return m_bufferQueue.isEmpty() ? 0 : m_bufferQueue.dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include <QtGui/qpainterpath.h>
|
#include <QtGui/qpainterpath.h>
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
#include <QtCore/qstack.h>
|
#include <QtCore/qstack.h>
|
||||||
|
#include <QtCore/qqueue.h>
|
||||||
#include <private/qv8engine_p.h>
|
#include <private/qv8engine_p.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,14 +71,6 @@ class QQuickContext2DTexture;
|
||||||
class QQuickPixmap;
|
class QQuickPixmap;
|
||||||
class QSGTexture;
|
class QSGTexture;
|
||||||
|
|
||||||
class QLockedCommandBuffer {
|
|
||||||
public:
|
|
||||||
QLockedCommandBuffer(QQuickContext2DCommandBuffer *b);
|
|
||||||
~QLockedCommandBuffer();
|
|
||||||
QQuickContext2DCommandBuffer* operator->() const;
|
|
||||||
private:
|
|
||||||
QQuickContext2DCommandBuffer *m_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Q_QUICK_EXPORT QQuickContext2D : public QQuickCanvasContext
|
class Q_QUICK_EXPORT QQuickContext2D : public QQuickCanvasContext
|
||||||
{
|
{
|
||||||
|
@ -179,7 +172,9 @@ public:
|
||||||
void setV8Engine(QV8Engine *eng);
|
void setV8Engine(QV8Engine *eng);
|
||||||
|
|
||||||
QQuickCanvasItem* canvas() const { return m_canvas; }
|
QQuickCanvasItem* canvas() const { return m_canvas; }
|
||||||
QLockedCommandBuffer buffer() const { return m_buffer; }
|
QQuickContext2DCommandBuffer* buffer() const { return m_buffer; }
|
||||||
|
QQuickContext2DCommandBuffer* nextBuffer();
|
||||||
|
|
||||||
bool bufferValid() const { return m_buffer != 0; }
|
bool bufferValid() const { return m_buffer != 0; }
|
||||||
void popState();
|
void popState();
|
||||||
void pushState();
|
void pushState();
|
||||||
|
@ -221,6 +216,8 @@ public:
|
||||||
QQuickContext2DTexture *m_texture;
|
QQuickContext2DTexture *m_texture;
|
||||||
QQuickCanvasItem::RenderTarget m_renderTarget;
|
QQuickCanvasItem::RenderTarget m_renderTarget;
|
||||||
QQuickCanvasItem::RenderStrategy m_renderStrategy;
|
QQuickCanvasItem::RenderStrategy m_renderStrategy;
|
||||||
|
QQueue<QQuickContext2DCommandBuffer*> m_bufferQueue;
|
||||||
|
QMutex m_bufferMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -195,13 +195,14 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize&
|
||||||
|
|
||||||
void QQuickContext2DTexture::paintWithoutTiles()
|
void QQuickContext2DTexture::paintWithoutTiles()
|
||||||
{
|
{
|
||||||
QLockedCommandBuffer ccb = m_context->buffer();
|
QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer();
|
||||||
|
|
||||||
if (ccb->isEmpty())
|
if (!ccb || ccb->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QPaintDevice* device = beginPainting();
|
QPaintDevice* device = beginPainting();
|
||||||
if (!device) {
|
if (!device) {
|
||||||
|
delete ccb;
|
||||||
endPainting();
|
endPainting();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -218,6 +219,7 @@ void QQuickContext2DTexture::paintWithoutTiles()
|
||||||
|
|
||||||
ccb->replay(&p, m_state);
|
ccb->replay(&p, m_state);
|
||||||
ccb->clear();
|
ccb->clear();
|
||||||
|
delete ccb;
|
||||||
|
|
||||||
endPainting();
|
endPainting();
|
||||||
|
|
||||||
|
@ -269,7 +271,12 @@ void QQuickContext2DTexture::paint()
|
||||||
|
|
||||||
if (beginPainting()) {
|
if (beginPainting()) {
|
||||||
QQuickContext2D::State oldState = m_state;
|
QQuickContext2D::State oldState = m_state;
|
||||||
QLockedCommandBuffer ccb = m_context->buffer();
|
QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer();
|
||||||
|
if (!ccb || ccb->isEmpty()) {
|
||||||
|
endPainting();
|
||||||
|
delete ccb;
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach (QQuickContext2DTile* tile, m_tiles) {
|
foreach (QQuickContext2DTile* tile, m_tiles) {
|
||||||
bool dirtyTile = false, dirtyCanvas = false, smooth = false;
|
bool dirtyTile = false, dirtyCanvas = false, smooth = false;
|
||||||
|
|
||||||
|
@ -296,6 +303,7 @@ void QQuickContext2DTexture::paint()
|
||||||
compositeTile(tile);
|
compositeTile(tile);
|
||||||
}
|
}
|
||||||
ccb->clear();
|
ccb->clear();
|
||||||
|
delete ccb;
|
||||||
endPainting();
|
endPainting();
|
||||||
m_state = oldState;
|
m_state = oldState;
|
||||||
markDirtyTexture();
|
markDirtyTexture();
|
||||||
|
|
|
@ -228,7 +228,7 @@ Rectangle {
|
||||||
c.toDataURL();
|
c.toDataURL();
|
||||||
wait(100);
|
wait(100);
|
||||||
|
|
||||||
compare(c.paintedCount, 1);
|
compare(c.paintedCount, 2);
|
||||||
compare(c.paintCount, 1);
|
compare(c.paintCount, 1);
|
||||||
c.destroy();
|
c.destroy();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue