Find cubic KLM functionals directly
- Updates GrPathUtils to computes the KLM functionals directly instead
of deriving them from their explicit values at the control points.
- Updates the utility to return these functionals as a matrix
rather than an array of scalar values.
- Adds a benchmark for chopCubicAtLoopIntersection.
BUG=skia:
Change-Id: I97a9b5cf610d33e15c9af96b9d9a8eb4a94b1ca7
Reviewed-on: https://skia-review.googlesource.com/9951
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 9167410..523ccd3 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -22,10 +22,6 @@
#include "effects/GrBezierEffect.h"
-static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) {
- return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]);
-}
-
namespace skiagm {
class BezierCubicOrConicTestOp : public GrTestMeshDrawOp {
@@ -35,20 +31,21 @@
const char* name() const override { return "BezierCubicOrConicTestOp"; }
static std::unique_ptr<GrMeshDrawOp> Make(sk_sp<GrGeometryProcessor> gp, const SkRect& rect,
- GrColor color, const SkScalar klmEqs[9],
- SkScalar sign) {
+ GrColor color, const SkMatrix& klm, SkScalar sign) {
return std::unique_ptr<GrMeshDrawOp>(
- new BezierCubicOrConicTestOp(gp, rect, color, klmEqs, sign));
+ new BezierCubicOrConicTestOp(gp, rect, color, klm, sign));
}
private:
BezierCubicOrConicTestOp(sk_sp<GrGeometryProcessor> gp, const SkRect& rect, GrColor color,
- const SkScalar klmEqs[9], SkScalar sign)
- : INHERITED(ClassID(), rect, color), fRect(rect), fGeometryProcessor(std::move(gp)) {
- for (int i = 0; i < 9; i++) {
- fKlmEqs[i] = klmEqs[i];
+ const SkMatrix& klm, SkScalar sign)
+ : INHERITED(ClassID(), rect, color)
+ , fKLM(klm)
+ , fRect(rect)
+ , fGeometryProcessor(std::move(gp)) {
+ if (1 != sign) {
+ fKLM.postScale(sign, sign);
}
- fSign = sign;
}
struct Vertex {
SkPoint fPosition;
@@ -66,15 +63,13 @@
verts[0].fPosition.setRectFan(fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom,
sizeof(Vertex));
for (int v = 0; v < 4; ++v) {
- verts[v].fKLM[0] = eval_line(verts[v].fPosition, fKlmEqs + 0, fSign);
- verts[v].fKLM[1] = eval_line(verts[v].fPosition, fKlmEqs + 3, fSign);
- verts[v].fKLM[2] = eval_line(verts[v].fPosition, fKlmEqs + 6, 1.f);
+ SkScalar pt3[3] = {verts[v].fPosition.x(), verts[v].fPosition.y(), 1.f};
+ fKLM.mapHomogeneousPoints(verts[v].fKLM, pt3, 1);
}
helper.recordDraw(target, fGeometryProcessor.get());
}
- SkScalar fKlmEqs[9];
- SkScalar fSign;
+ SkMatrix fKLM;
SkRect fRect;
sk_sp<GrGeometryProcessor> fGeometryProcessor;
@@ -155,11 +150,11 @@
{x + baseControlPts[3].fX, y + baseControlPts[3].fY}
};
SkPoint chopped[10];
- SkScalar klmEqs[9];
+ SkMatrix klm;
int loopIndex;
int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
chopped,
- klmEqs,
+ &klm,
&loopIndex);
SkPaint ctrlPtPaint;
@@ -203,7 +198,7 @@
}
std::unique_ptr<GrMeshDrawOp> op =
- BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, sign);
+ BezierCubicOrConicTestOp::Make(gp, bounds, color, klm, sign);
renderTargetContext->priv().testingOnly_addMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
@@ -296,9 +291,9 @@
{x + baseControlPts[2].fX, y + baseControlPts[2].fY}
};
SkConic dst[4];
- SkScalar klmEqs[9];
+ SkMatrix klm;
int cnt = chop_conic(controlPts, dst, weight);
- GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
+ GrPathUtils::getConicKLM(controlPts, weight, &klm);
SkPaint ctrlPtPaint;
ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
@@ -336,7 +331,7 @@
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
std::unique_ptr<GrMeshDrawOp> op =
- BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, 1.f);
+ BezierCubicOrConicTestOp::Make(gp, bounds, color, klm, 1.f);
renderTargetContext->priv().testingOnly_addMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));