diff options
author | 2017-06-28 10:02:40 -0400 | |
---|---|---|
committer | 2017-06-28 16:49:31 +0000 | |
commit | a66ef2d1063c9005611890613a7c27bede6ec5cb (patch) | |
tree | 2b7618b84b105e12d732319593adb5a4df481f7f /src/shaders/gradients/SkTwoPointConicalGradient.cpp | |
parent | 2de8cfadc34cd92a6f99659fa565c137b386fa5f (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.cpp | 46 |
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; } |