summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLouai Al-Khanji <louai.al-khanji@digia.com>2014-05-21 13:25:26 +0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-22 06:06:51 +0200
commit8d7e23ea0b6d0e198e445e3cd4285a34d4e7dc96 (patch)
treeccd552eeaf5e6b698c7371dba250d6271a1fb0ef /src
parent5d2939344eb8fbd3c2115f52a7a8d47365bdf820 (diff)
Direct2D QPA: Cache QVectorPaths if drawn more than once
Hooking into the caching mechanism gets us a measurable performance boost for paths that are drawn repeatedly, around 10% on my machine when drawing aliased arcs. Change-Id: I32f4ed7daa8a51b5c5a9c6d5414ab5d4ef759f70 Reviewed-by: Risto Avila <risto.avila@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp49
1 files changed, 43 insertions, 6 deletions
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index a838950c9e..f376f7707f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -256,8 +256,30 @@ static ComPtr<ID2D1PathGeometry1> painterPathToID2D1PathGeometry(const QPainterP
return writer.geometry();
}
-static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias)
+struct D2DVectorPathCache {
+ ComPtr<ID2D1PathGeometry1> aliased;
+ ComPtr<ID2D1PathGeometry1> antiAliased;
+
+ static void cleanup_func(QPaintEngineEx *engine, void *data) {
+ Q_UNUSED(engine);
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(data);
+ delete e;
+ }
+};
+
+static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias, QPaintEngineEx* engine)
{
+ QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(engine)
+ : Q_NULLPTR;
+
+ if (cacheEntry) {
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data);
+ if (alias && e->aliased)
+ return e->aliased;
+ else if (!alias && e->antiAliased)
+ return e->antiAliased;
+ }
+
Direct2DPathGeometryWriter writer;
if (!writer.begin())
return NULL;
@@ -321,7 +343,22 @@ static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPat
writer.lineTo(QPointF(points[0], points[1]));
writer.close();
- return writer.geometry();
+ ComPtr<ID2D1PathGeometry1> geometry = writer.geometry();
+
+ if (path.isCacheable()) {
+ if (!cacheEntry)
+ cacheEntry = path.addCacheData(engine, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func);
+
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data);
+ if (alias)
+ e->aliased = geometry;
+ else
+ e->antiAliased = geometry;
+ } else {
+ path.makeCacheable();
+ }
+
+ return geometry;
}
class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
@@ -426,7 +463,7 @@ public:
dc()->PushAxisAlignedClip(rect, antialiasMode());
pushedClips.push(AxisAlignedClip);
} else {
- ComPtr<ID2D1PathGeometry1> geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1PathGeometry1> geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, q);
if (!geometry) {
qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__);
return;
@@ -938,7 +975,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path)
{
Q_D(QWindowsDirect2DPaintEngine);
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
@@ -978,7 +1015,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
if (!d->brush.brush)
return;
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
@@ -1016,7 +1053,7 @@ void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pe
if (!d->pen.brush)
return;
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;