From 58caefa13e7bcfac1baccee4d1e7a73bd6b48f19 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Fri, 9 May 2014 11:17:41 +0300 Subject: Direct2D QPA: Stroke using direct2d primitives Use native direct2d stroking instead of falling back to QPaintEngineEx::stroke which in turn calls the pure virtual QPaintEngineEx::fill which is reimplemented in QWindowsDirect2DPaintEngine. In some cases like arc stroking this is significantly faster (up to 3x in my measurements) and results in better visual quality. Change-Id: I1c86ff772ba591432ff6550c7c59704ace4f0e0f Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 78 +++++++++++++++++++++- .../direct2d/qwindowsdirect2dpaintengine.h | 7 ++ 2 files changed, 84 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 5a4157565e..a838950c9e 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -934,6 +934,33 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s) transformChanged(); } +void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) +{ + Q_D(QWindowsDirect2DPaintEngine); + + ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + if (!geometry) { + qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); + return; + } + + const QBrush &brush = state()->brush; + if (qbrush_style(brush) != Qt::NoBrush) { + if (emulationRequired(BrushEmulation)) + rasterFill(path, brush); + else + fill(geometry.Get(), brush); + } + + const QPen &pen = state()->pen; + if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) { + if (emulationRequired(PenEmulation)) + QPaintEngineEx::stroke(path, pen); + else + stroke(geometry.Get(), pen); + } +} + void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QWindowsDirect2DPaintEngine); @@ -943,7 +970,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br return; ensureBrush(brush); - if (emulationRequired(BrushEmulation)) { rasterFill(path, brush); return; @@ -961,6 +987,56 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get()); } +void QWindowsDirect2DPaintEngine::fill(ID2D1Geometry *geometry, const QBrush &brush) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + ensureBrush(brush); + if (!d->brush.brush) + return; + + d->dc()->FillGeometry(geometry, d->brush.brush.Get()); +} + +void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pen) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + if (path.isEmpty()) + return; + + ensurePen(pen); + if (emulationRequired(PenEmulation)) { + QPaintEngineEx::stroke(path, pen); + return; + } + + if (!d->pen.brush) + return; + + ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + if (!geometry) { + qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); + return; + } + + d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); +} + +void QWindowsDirect2DPaintEngine::stroke(ID2D1Geometry *geometry, const QPen &pen) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + ensurePen(pen); + if (!d->pen.brush) + return; + + d->dc()->DrawGeometry(geometry, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); +} + void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QWindowsDirect2DPaintEngine); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index fb9b7acec3..c91a951ebe 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -68,7 +68,14 @@ public: void setState(QPainterState *s) Q_DECL_OVERRIDE; + void draw(const QVectorPath &path) Q_DECL_OVERRIDE; + void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE; + void fill(ID2D1Geometry *geometry, const QBrush &brush); + + void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE; + void stroke(ID2D1Geometry *geometry, const QPen &pen); + void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; void clipEnabledChanged() Q_DECL_OVERRIDE; -- cgit v1.2.3