Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Unified Diff: src/effects/gradients/SkGradientShader.cpp

Issue 2256843004: Implement gradient simplification for 0,0,1 and 0,1,1 gradients (Closed) Base URL: https://skia.googlesource.com/skia.git@remove-expand-one-color-macro
Patch Set: Remove unnecessary include Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/gradients/SkGradientShader.cpp
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 3b761a51cadabba2175375df9b5292f66470c344..460b10111f84699efee298be7766a74ec9666b8a 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -755,12 +755,57 @@ static void desc_init(SkGradientShaderBase::Descriptor* desc,
desc->fLocalMatrix = localMatrix;
}
+static int simplify(SkScalar* pos, SkColor* colors, int colorCount, SkShader::TileMode mode) {
+ if (pos) {
+ if (3 == colorCount) {
+ // Left-edged hard stop gradients (0, 0, 1) can be simplified
+ // to a 2-color gradient if first two colors are the same
+ if (SkScalarNearlyEqual(pos[0], 0.0f) &&
+ SkScalarNearlyEqual(pos[1], 0.0f) &&
+ SkScalarNearlyEqual(pos[2], 1.0f)) {
+
+ // If the tile mode is repeat or mirror, first color
+ // doesn't matter
+ if (SkShader::kRepeat_TileMode == mode ||
+ SkShader::kMirror_TileMode == mode ||
+ colors[0] == colors[1]) {
+
+ pos[0] = 0.0f;
+ pos[1] = 1.0f;
+
+ colors[0] = colors[1];
+ colors[1] = colors[2];
+
+ colorCount = 2;
f(malita) 2016/08/18 22:54:17 If we fall through here, I think we'll also take t
+ }
+ }
+
+ // Right-edged hard stop gradients (0, 1, 1) can be simplified
+ // to a 2-color gradient if last two colors are the same
+ if (SkScalarNearlyEqual(pos[0], 0.0f) &&
+ SkScalarNearlyEqual(pos[1], 1.0f) &&
+ SkScalarNearlyEqual(pos[2], 1.0f)) {
+
+ // If the tile mode is repeat or mirror, last color
+ // doesn't matter
+ if (SkShader::kRepeat_TileMode == mode ||
+ SkShader::kMirror_TileMode == mode ||
+ colors[1] == colors[2]) {
+
+ colorCount = 2;
+ }
+ }
+ }
+ }
+ return colorCount;
+}
+
sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2],
- const SkColor colors[],
- const SkScalar pos[], int colorCount,
- SkShader::TileMode mode,
- uint32_t flags,
- const SkMatrix* localMatrix) {
+ const SkColor colors[],
+ const SkScalar pos[], int colorCount,
+ SkShader::TileMode mode,
+ uint32_t flags,
+ const SkMatrix* localMatrix) {
if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) {
return nullptr;
}
@@ -771,8 +816,22 @@ sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2],
return SkShader::MakeColorShader(colors[0]);
}
+ SkAutoTArray<SkScalar> simplifiedPos(colorCount);
+ SkAutoTArray<SkColor> simplifiedCol(colorCount);
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedCol[i] = colors[i];
+ }
+ if (pos) {
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedPos[i] = pos[i];
+ }
+ colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCount, mode);
+ } else {
+ simplifiedPos.reset(0);
+ }
f(malita) 2016/08/18 22:54:17 It would be nice to a) avoid these allocations an
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix);
return sk_make_sp<SkLinearGradient>(pts, desc);
}
@@ -792,8 +851,22 @@ sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad
return SkShader::MakeColorShader(colors[0]);
}
+ SkAutoTArray<SkScalar> simplifiedPos(colorCount);
+ SkAutoTArray<SkColor> simplifiedCol(colorCount);
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedCol[i] = colors[i];
+ }
+ if (pos) {
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedPos[i] = pos[i];
+ }
+ colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCount, mode);
+ } else {
+ simplifiedPos.reset(0);
+ }
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix);
return sk_make_sp<SkRadialGradient>(center, radius, desc);
}
@@ -822,24 +895,38 @@ sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start,
return SkShader::MakeColorShader(colors[0]);
}
+ SkAutoTArray<SkScalar> simplifiedPos(colorCount);
+ SkAutoTArray<SkColor> simplifiedCol(colorCount);
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedCol[i] = colors[i];
+ }
+ if (pos) {
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedPos[i] = pos[i];
+ }
+ colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCount, mode);
+ } else {
+ simplifiedPos.reset(0);
+ }
+
bool flipGradient = startRadius > endRadius;
SkGradientShaderBase::Descriptor desc;
if (!flipGradient) {
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix);
return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, endRadius,
flipGradient, desc);
} else {
SkAutoSTArray<8, SkColor> colorsNew(colorCount);
SkAutoSTArray<8, SkScalar> posNew(colorCount);
for (int i = 0; i < colorCount; ++i) {
- colorsNew[i] = colors[colorCount - i - 1];
+ colorsNew[i] = simplifiedCol[colorCount - i - 1];
}
if (pos) {
for (int i = 0; i < colorCount; ++i) {
- posNew[i] = 1 - pos[colorCount - i - 1];
+ posNew[i] = 1 - simplifiedPos[colorCount - i - 1];
}
desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, flags, localMatrix);
} else {
@@ -864,8 +951,23 @@ sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy,
return SkShader::MakeColorShader(colors[0]);
}
+ SkAutoTArray<SkScalar> simplifiedPos(colorCount);
+ SkAutoTArray<SkColor> simplifiedCol(colorCount);
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedCol[i] = colors[i];
+ }
+ auto mode = SkShader::kClamp_TileMode; // Bogus tilemode
+ if (pos) {
+ for (int i = 0; i < colorCount; i++) {
+ simplifiedPos[i] = pos[i];
+ }
+ colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCount, mode);
+ } else {
+ simplifiedPos.reset(0);
+ }
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix);
+ desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix);
return sk_make_sp<SkSweepGradient>(cx, cy, desc);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698