From 3e5c94c368c261190992b9c0f8b4223c35ede407 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 18 May 2009 11:44:26 +1000 Subject: More aggressively skip calculations --- src/declarative/canvas/qsimplecanvas.cpp | 5 +- src/declarative/canvas/qsimplecanvas_p.h | 2 + src/declarative/canvas/qsimplecanvas_software.cpp | 119 ++++++++++++++-------- src/declarative/canvas/qsimplecanvasitem.cpp | 7 +- src/declarative/canvas/qsimplecanvasitem_p.h | 2 +- 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; -- cgit v0.12