aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders/gradients/SkTwoPointConicalGradient.cpp
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-06-28 10:02:40 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-28 16:49:31 +0000
commita66ef2d1063c9005611890613a7c27bede6ec5cb (patch)
tree2b7618b84b105e12d732319593adb5a4df481f7f /src/shaders/gradients/SkTwoPointConicalGradient.cpp
parent2de8cfadc34cd92a6f99659fa565c137b386fa5f (diff)
2ptconical stage
Initial impl, for the well-behaved case (focal point inside). MBP numbers - Before: 3365.87 ! gradient_conical_clamp_shallow srgb 3590.88 ! gradient_conical_clamp_shallow_dither srgb 3376.91 ! gradient_conical_clamp_3color srgb 3351.64 ! gradient_conical_clamp_hicolor srgb 3379.35 ! gradient_conical_clamp srgb After: 648.93 ! gradient_conical_clamp_shallow srgb 665.12 ! gradient_conical_clamp_shallow_dither srgb 773.98 ! gradient_conical_clamp_3color srgb 1175.35 ! gradient_conical_clamp_hicolor srgb 619.17 ! gradient_conical_clamp srgb Change-Id: I07b22a758363e1f340a6041bca53bdef74229eb9 Reviewed-on: https://skia-review.googlesource.com/20906 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/shaders/gradients/SkTwoPointConicalGradient.cpp')
-rw-r--r--src/shaders/gradients/SkTwoPointConicalGradient.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/shaders/gradients/SkTwoPointConicalGradient.cpp b/src/shaders/gradients/SkTwoPointConicalGradient.cpp
index 846b5f41d6..d33fbac868 100644
--- a/src/shaders/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/shaders/gradients/SkTwoPointConicalGradient.cpp
@@ -7,6 +7,9 @@
#include "SkTwoPointConicalGradient.h"
+#include "SkRasterPipeline.h"
+#include "../../jumper/SkJumper.h"
+
struct TwoPtRadialContext {
const TwoPtRadial& fRec;
float fRelX, fRelY;
@@ -426,17 +429,19 @@ void SkTwoPointConicalGradient::toString(SkString* str) const {
bool SkTwoPointConicalGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
SkMatrix* matrix,
SkRasterPipeline* p) const {
+ const auto dCenter = (fCenter1 - fCenter2).length();
+ const auto dRadius = fRadius2 - fRadius1;
+ SkASSERT(dRadius >= 0);
+
// When the two circles are concentric, we can pretend we're radial (with a tiny *twist).
- if (SkScalarNearlyZero((fCenter1 - fCenter2).length())) {
+ if (SkScalarNearlyZero(dCenter)) {
matrix->postTranslate(-fCenter1.fX, -fCenter1.fY);
matrix->postScale(1 / fRadius2, 1 / fRadius2);
p->append(SkRasterPipeline::xy_to_radius);
// Tiny twist: radial computes a t for [0, r2], but we want a t for [r1, r2].
- auto dR = fRadius2 - fRadius1;
- SkASSERT(dR > 0);
- auto scale = fRadius2 / dR;
- auto bias = -fRadius1 / dR;
+ auto scale = fRadius2 / dRadius;
+ auto bias = -fRadius1 / dRadius;
auto mad_matrix = SkMatrix::Concat(SkMatrix::MakeTrans(bias, 0),
SkMatrix::MakeScale(scale, 1));
@@ -447,6 +452,33 @@ bool SkTwoPointConicalGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
return true;
}
- // TODO
- return false;
+ if (dCenter + fRadius1 > fRadius2) {
+ // We only handle well behaved cases for now.
+ return false;
+ }
+
+ // To simplify the stage math, we transform the universe (translate/scale/rotate)
+ // such that fCenter1 -> (0, 0) and fCenter2 -> (1, 0).
+ SkMatrix map_to_unit_vector;
+ const SkPoint centers[2] = { fCenter1, fCenter2 };
+ const SkPoint unitvec[2] = { {0, 0}, {1, 0} };
+ SkAssertResult(map_to_unit_vector.setPolyToPoly(centers, unitvec, 2));
+ matrix->postConcat(map_to_unit_vector);
+
+ // Since we've squashed the centers into a unit vector, we must also scale
+ // all the coefficient variables by (1 / dCenter).
+ const auto coeffA = 1 - dRadius * dRadius / (dCenter * dCenter);
+ if (SkScalarNearlyZero(coeffA)) {
+ // We only handle well behaved quadratic cases for now.
+ return false;
+ }
+
+ auto* ctx = alloc->make<SkJumper_2PtConicalCtx>();
+ ctx->fCoeffA = coeffA;
+ ctx->fInvCoeffA = 1 / coeffA;
+ ctx->fR0 = fRadius1 / dCenter;
+ ctx->fDR = dRadius / dCenter;
+
+ p->append(SkRasterPipeline::xy_to_2pt_conical, ctx);
+ return true;
}