summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/canvas/qsimplecanvas.cpp5
-rw-r--r--src/declarative/canvas/qsimplecanvas_p.h2
-rw-r--r--src/declarative/canvas/qsimplecanvas_software.cpp119
-rw-r--r--src/declarative/canvas/qsimplecanvasitem.cpp7
-rw-r--r--src/declarative/canvas/qsimplecanvasitem_p.h2
5 files changed, 84 insertions, 51 deletions
diff --git a/src/declarative/canvas/qsimplecanvas.cpp b/src/declarative/canvas/qsimplecanvas.cpp
index e1dd0e8..cd50945 100644
--- a/src/declarative/canvas/qsimplecanvas.cpp
+++ b/src/declarative/canvas/qsimplecanvas.cpp
@@ -621,8 +621,10 @@ QSimpleCanvas::~QSimpleCanvas()
void QSimpleCanvasPrivate::paint(QPainter &p)
{
#if defined(QFX_RENDER_QPAINTER)
- if (!isSetup)
+ if (!isSetup) {
+ ++paintVersion;
root->d_func()->setupPainting(0, q->rect());
+ }
lrpTimer.start();
@@ -920,6 +922,7 @@ bool QSimpleCanvas::event(QEvent *e)
unsigned int zero = 0;
d->root->d_func()->setupPainting(0, rect(), &zero);
#else
+ ++d->paintVersion;
d->root->d_func()->setupPainting(0, rect());
#endif
diff --git a/src/declarative/canvas/qsimplecanvas_p.h b/src/declarative/canvas/qsimplecanvas_p.h
index 7bc7330..9c3408e 100644
--- a/src/declarative/canvas/qsimplecanvas_p.h
+++ b/src/declarative/canvas/qsimplecanvas_p.h
@@ -112,6 +112,7 @@ public:
#if defined(QFX_RENDER_OPENGL)
,egl(q, this), basicShadersInstance(0)
#endif
+ , paintVersion(1)
{
}
@@ -190,6 +191,7 @@ public:
void release(QGLFramebufferObject *);
void paintGL();
#endif
+ int paintVersion;
};
#endif
diff --git a/src/declarative/canvas/qsimplecanvas_software.cpp b/src/declarative/canvas/qsimplecanvas_software.cpp
index f822677..dd5e201 100644
--- a/src/declarative/canvas/qsimplecanvas_software.cpp
+++ b/src/declarative/canvas/qsimplecanvas_software.cpp
@@ -41,6 +41,7 @@
#include "qsimplecanvas.h"
#include "qsimplecanvasitem_p.h"
+#include "qsimplecanvas_p.h"
QT_BEGIN_NAMESPACE
@@ -48,9 +49,15 @@ QRect QSimpleCanvasItemPrivate::setupPainting(int version, const QRect &bounding
{
Q_Q(QSimpleCanvasItem);
- QRectF boundingRectActive = q->boundingRect();
- QRect rv =
- data()->transformActive.mapRect(boundingRectActive).toAlignedRect() & bounding;
+ bool hasContents = options & QSimpleCanvasItem::HasContents;
+
+ QRect rv;
+
+ if (hasContents || q->clip()) {
+ QRectF boundingRectActive = q->boundingRect();
+ rv = data()->transformActive.mapRect(boundingRectActive).toAlignedRect() & bounding;
+ }
+
data()->doNotPaint = rv.isEmpty();
data()->doNotPaintChildren = data()->doNotPaint && q->clip();
QRect myBounding = bounding;
@@ -61,48 +68,68 @@ QRect QSimpleCanvasItemPrivate::setupPainting(int version, const QRect &bounding
for (int ii = 0; ii < children.count(); ++ii) {
QSimpleCanvasItem *child = children.at(ii);
- qreal visible = child->visible();
- child->d_func()->data()->activeOpacity = data()->activeOpacity;
- if (visible != 1)
- child->d_func()->data()->activeOpacity *= visible;
-
+ int childVersion = version;
+ if (!child->d_func()->data()->transformValid)
+ childVersion = canvas->d->paintVersion;
+
+ bool recalcNeeded =
+ (childVersion > child->d_func()->data()->transformVersion);
+
+ if (recalcNeeded) {
+ qreal visible = child->visible();
+ child->d_func()->data()->activeOpacity = data()->activeOpacity;
+ if (visible != 1)
+ child->d_func()->data()->activeOpacity *= visible;
+ }
+
if (child->d_func()->data()->activeOpacity != 0) {
- // Calculate child's transform
- qreal x = child->x();
- qreal y = child->y();
- qreal scale = child->scale();
- QSimpleCanvasItem::Flip flip = child->flip();
-
- QSimpleCanvas::Matrix &am = child->d_func()->data()->transformActive;
- am = data()->transformActive;
- if (x != 0 || y != 0)
- am.translate(x, y);
- if (scale != 1) {
- QPointF to = child->d_func()->transformOrigin();
- if (to.x() != 0. || to.y() != 0.)
- am.translate(to.x(), to.y());
- am.scale(scale, scale);
- if (to.x() != 0. || to.y() != 0.)
- am.translate(-to.x(), -to.y());
- }
-
- if (child->d_func()->data()->transformUser)
- am = *child->d_func()->data()->transformUser * am;
-
- if (flip) {
- QRectF br = child->boundingRect();
- am.translate(br.width() / 2., br.height() / 2);
- am.scale((flip & QSimpleCanvasItem::HorizontalFlip)?-1:1,
- (flip & QSimpleCanvasItem::VerticalFlip)?-1:1);
- am.translate(-br.width() / 2., -br.height() / 2);
- }
- child->d_func()->data()->transformValid = true;
- rv |= child->d_func()->setupPainting(version, myBounding);
+ if (recalcNeeded) {
+ // Calculate child's transform
+ qreal x = child->x();
+ qreal y = child->y();
+ qreal scale = child->scale();
+ QSimpleCanvasItem::Flip flip = child->flip();
+
+ QSimpleCanvas::Matrix &am =
+ child->d_func()->data()->transformActive;
+ am = data()->transformActive;
+ if (x != 0 || y != 0)
+ am.translate(x, y);
+ if (scale != 1) {
+ QPointF to = child->d_func()->transformOrigin();
+ if (to.x() != 0. || to.y() != 0.)
+ am.translate(to.x(), to.y());
+ am.scale(scale, scale);
+ if (to.x() != 0. || to.y() != 0.)
+ am.translate(-to.x(), -to.y());
+ }
+
+ if (child->d_func()->data()->transformUser)
+ am = *child->d_func()->data()->transformUser * am;
+
+ if (flip) {
+ QRectF br = child->boundingRect();
+ am.translate(br.width() / 2., br.height() / 2);
+ am.scale((flip & QSimpleCanvasItem::HorizontalFlip)?-1:1,
+ (flip & QSimpleCanvasItem::VerticalFlip)?-1:1);
+ am.translate(-br.width() / 2., -br.height() / 2);
+ }
+ child->d_func()->data()->transformValid = true;
+ child->d_func()->data()->transformVersion = childVersion;
+ }
+ rv |= child->d_func()->setupPainting(child->d_func()->data()->transformVersion, myBounding);
}
}
}
data()->lastPaintRect = rv;
+ if (!data()->doNotPaintChildren) {
+ if (!bounding.intersects(rv)) {
+ data()->doNotPaintChildren = true;
+ data()->doNotPaint = true;
+ }
+ }
+
return rv;
}
@@ -157,12 +184,14 @@ void QSimpleCanvasItemPrivate::paint(QPainter &p)
zOrderChildren();
int upto = 0;
- for (upto = 0; upto < children.count(); ++upto) {
- QSimpleCanvasItem *c = children.at(upto);
- if (c->z() < 0) {
- paintChild(p, c);
- } else {
- break;
+ if (!data()->doNotPaintChildren) {
+ for (upto = 0; upto < children.count(); ++upto) {
+ QSimpleCanvasItem *c = children.at(upto);
+ if (c->z() < 0) {
+ paintChild(p, c);
+ } else {
+ break;
+ }
}
}
diff --git a/src/declarative/canvas/qsimplecanvasitem.cpp b/src/declarative/canvas/qsimplecanvasitem.cpp
index 9c110d7..a62dbc9 100644
--- a/src/declarative/canvas/qsimplecanvasitem.cpp
+++ b/src/declarative/canvas/qsimplecanvasitem.cpp
@@ -50,8 +50,9 @@
QT_BEGIN_NAMESPACE
QSimpleCanvasItemData::QSimpleCanvasItemData()
: buttons(Qt::NoButton), flip(QSimpleCanvasItem::NoFlip),
- dirty(false), transformValid(true), doNotPaint(false), doNotPaintChildren(false), x(0), y(0), z(0), visible(1),
- transformUser(0), activeOpacity(1)
+ dirty(false), transformValid(true), doNotPaint(false),
+ doNotPaintChildren(false), x(0), y(0), z(0), visible(1),
+ transformUser(0), transformVersion(0), activeOpacity(1)
{
}
@@ -934,8 +935,6 @@ QRectF QSimpleCanvasItem::mapToScene(const QRectF &r) const
}
}
-int QSimpleCanvasItemPrivate::nextTransformVersion = 1;
-
void QSimpleCanvasItemPrivate::freshenTransforms() const
{
if (freshenNeeded())
diff --git a/src/declarative/canvas/qsimplecanvasitem_p.h b/src/declarative/canvas/qsimplecanvasitem_p.h
index a20b8f4..34880f0 100644
--- a/src/declarative/canvas/qsimplecanvasitem_p.h
+++ b/src/declarative/canvas/qsimplecanvasitem_p.h
@@ -102,6 +102,7 @@ public:
QSimpleCanvas::Matrix *transformUser;
QSimpleCanvas::Matrix transformActive;
+ int transformVersion;
float activeOpacity;
@@ -238,7 +239,6 @@ public:
#endif
void zOrderChildren();
- static int nextTransformVersion;
bool freshenNeeded() const;
void doFreshenTransforms() const;