diff options
author | Louai Al-Khanji <louai.al-khanji@digia.com> | 2014-05-21 13:25:26 +0300 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-22 06:06:51 +0200 |
commit | 8d7e23ea0b6d0e198e445e3cd4285a34d4e7dc96 (patch) | |
tree | ccd552eeaf5e6b698c7371dba250d6271a1fb0ef /src | |
parent | 5d2939344eb8fbd3c2115f52a7a8d47365bdf820 (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.cpp | 49 |
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; |