aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qsgcanvasitem.cpp
diff options
context:
space:
mode:
authorCharles Yin <charles.yin@nokia.com>2011-07-12 09:21:27 +1000
committerQt by Nokia <qt-info@nokia.com>2011-07-12 04:25:33 +0200
commitb119220da60453ecf31898f7a57eda9d3c4e9225 (patch)
tree0b316ed1ef9a5e0e154c0a87628a6a5ff205c9dc /src/declarative/items/qsgcanvasitem.cpp
parentbd4d69c9a88f476b4de4ba80945d39725bb29efa (diff)
Rewrite the canvas item's paint logic.
1. Only allow the context API calls inside onPaint() slot function, makes the context2d handle invalid when out of scope. 2. requestPaint() method supports region parameter 3. Emit paint() signal in updatePolish() function to allow threaded scene graph rendering work properly with context2d api 4. Allow request painting mutiple dirty regions between 2 frames. 5. Add svgpath for context2d Change-Id: I5ec48f7c0eb6820d5c9c16a8d0dcc0aae8d0fd2f Reviewed-on: http://codereview.qt.nokia.com/1465 Reviewed-by: Charles Yin <charles.yin@nokia.com>
Diffstat (limited to 'src/declarative/items/qsgcanvasitem.cpp')
-rw-r--r--src/declarative/items/qsgcanvasitem.cpp119
1 files changed, 102 insertions, 17 deletions
diff --git a/src/declarative/items/qsgcanvasitem.cpp b/src/declarative/items/qsgcanvasitem.cpp
index f346db4c66..0bd9a47d8d 100644
--- a/src/declarative/items/qsgcanvasitem.cpp
+++ b/src/declarative/items/qsgcanvasitem.cpp
@@ -58,6 +58,10 @@ public:
QSGCanvasItemPrivate();
~QSGCanvasItemPrivate();
QSGContext2D* context;
+ QList<QRect> dirtyRegions;
+ QRect unitedDirtyRegion;
+ qreal canvasX;
+ qreal canvasY;
};
@@ -67,6 +71,9 @@ public:
QSGCanvasItemPrivate::QSGCanvasItemPrivate()
: QSGPaintedItemPrivate()
, context(0)
+ , unitedDirtyRegion()
+ , canvasX(0.)
+ , canvasY(0.)
{
}
@@ -74,6 +81,40 @@ QSGCanvasItemPrivate::~QSGCanvasItemPrivate()
{
}
+
+void QSGCanvasItem::setCanvasX(qreal x)
+{
+ Q_D(QSGCanvasItem);
+ if (d->canvasX != x) {
+ d->canvasX = x;
+ emit canvasXChanged();
+ }
+}
+void QSGCanvasItem::setCanvasY(qreal y)
+{
+ Q_D(QSGCanvasItem);
+ if (d->canvasY != y) {
+ d->canvasY = y;
+ emit canvasYChanged();
+ }
+}
+
+qreal QSGCanvasItem::canvasX() const
+{
+ Q_D(const QSGCanvasItem);
+ return d->canvasX;
+}
+qreal QSGCanvasItem::canvasY() const
+{
+ Q_D(const QSGCanvasItem);
+ return d->canvasY;
+}
+QPointF QSGCanvasItem::canvasPos() const
+{
+ Q_D(const QSGCanvasItem);
+ return QPointF(d->canvasX, d->canvasY);
+}
+
/*!
Constructs a QSGCanvasItem with the given \a parent item.
*/
@@ -92,11 +133,13 @@ QSGCanvasItem::~QSGCanvasItem()
void QSGCanvasItem::paint(QPainter *painter)
{
Q_D(QSGCanvasItem);
+ if (d->context && d->context->isDirty()) {
+ painter->setWindow(-d->canvasX, -d->canvasY, d->width, d->height);
+ painter->setViewport(0, 0, d->width, d->height);
+ painter->scale(d->contentsScale, d->contentsScale);
- if (d->context) {
- emit drawRegion(getContext(), QRect(0, 0, width(), height()));
d->context->paint(painter);
- emit canvasUpdated();
+ emit painted();
}
}
@@ -104,36 +147,59 @@ void QSGCanvasItem::componentComplete()
{
const QMetaObject *metaObject = this->metaObject();
int propertyCount = metaObject->propertyCount();
- int requestPaintMethod = metaObject->indexOfMethod("requestPaint()");
+ int requestPaintMethod = metaObject->indexOfMethod("requestPaint(const QRect&)");
for (int ii = QSGCanvasItem::staticMetaObject.propertyCount(); ii < propertyCount; ++ii) {
QMetaProperty p = metaObject->property(ii);
if (p.hasNotifySignal())
QMetaObject::connect(this, p.notifySignalIndex(), this, requestPaintMethod, 0, 0);
}
+
+ createContext();
+
QSGPaintedItem::componentComplete();
}
+void QSGCanvasItem::createContext()
+{
+ Q_D(QSGCanvasItem);
+
+ delete d->context;
+
+ d->context = new QSGContext2D(this);
+
+ QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
+ d->context->setV8Engine(e);
+}
QDeclarativeV8Handle QSGCanvasItem::getContext(const QString &contextId)
{
Q_D(QSGCanvasItem);
+ Q_UNUSED(contextId);
- if (contextId == QLatin1String("2d")) {
- if (!d->context) {
- QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
- d->context = new QSGContext2D(this);
- d->context->setV8Engine(e);
- connect(d->context, SIGNAL(changed()), this, SLOT(requestPaint()));
- }
- return QDeclarativeV8Handle::fromHandle(d->context->v8value());
- }
+ if (d->context)
+ return QDeclarativeV8Handle::fromHandle(d->context->v8value());
return QDeclarativeV8Handle::fromHandle(v8::Undefined());
}
-void QSGCanvasItem::requestPaint()
+void QSGCanvasItem::requestPaint(const QRect& r)
{
- //TODO:update(d->context->dirtyRect());
- update();
+ Q_D(QSGCanvasItem);
+
+ QRect region;
+ if (!r.isValid())
+ region = QRect(d->canvasX, d->canvasY, d->width, d->height);
+ else
+ region = r;
+
+ foreach (const QRect& rect, d->dirtyRegions) {
+ if (rect.contains(region))
+ return;
+ }
+
+ d->unitedDirtyRegion = d->unitedDirtyRegion.unite(region);
+ d->dirtyRegions.append(region);
+ polish();
+ update(d->unitedDirtyRegion);
}
bool QSGCanvasItem::save(const QString &filename) const
@@ -147,6 +213,26 @@ bool QSGCanvasItem::save(const QString &filename) const
return false;
}
+void QSGCanvasItem::updatePolish()
+{
+ Q_D(QSGCanvasItem);
+ QDeclarativeV8Handle context = QDeclarativeV8Handle::fromHandle(d->context->v8value());
+
+ d->context->setValid(true);
+
+ // d->context->setTileRect(QRectF(d->canvasX, d->canvasY, d->width, d->height).intersected(QRectF(0, 0, d->width, d->height)));
+ // d->context->setTileRect(QRectF(d->canvasX, d->canvasY, d->width, d->height));
+
+ foreach (const QRect& region, d->dirtyRegions) {
+ emit paint(context, region);
+ }
+ d->dirtyRegions.clear();
+
+ d->context->setValid(false);
+
+ QSGPaintedItem::updatePolish();
+}
+
QString QSGCanvasItem::toDataURL(const QString& mimeType) const
{
Q_D(const QSGCanvasItem);
@@ -182,5 +268,4 @@ QString QSGCanvasItem::toDataURL(const QString& mimeType) const
}
return QLatin1String("data:,");
}
-
QT_END_NAMESPACE