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

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: Add null pos check 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 78cdb80d559c34f127ce48bdb95191557d50e0bf..58c0d3bd5dcc2aaa8a266a7ef23141255e895b40 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -767,12 +767,61 @@ static void desc_init(SkGradientShaderBase::Descriptor* desc,
} \
} while (0)
+struct ColorStopOptimizer {
+ ColorStopOptimizer(const SkColor* colors, const SkScalar* pos,
+ int count, SkShader::TileMode mode)
+ : fColors(colors)
+ , fPos(pos)
+ , fCount(count) {
+
+ if (!pos || count != 3) {
+ return;
+ }
+
+ if (SkScalarNearlyEqual(pos[0], 0.0f) &&
+ SkScalarNearlyEqual(pos[1], 0.0f) &&
+ SkScalarNearlyEqual(pos[2], 1.0f)) {
+
+ if (SkShader::kRepeat_TileMode == mode ||
+ SkShader::kMirror_TileMode == mode ||
+ colors[0] == colors[1]) {
+
+ fColorStorage[0] = colors[1];
+ fColorStorage[1] = colors[2];
+ fPosStorage[0] = 0.0f;
+ fPosStorage[1] = 1.0f;
+
+ fColors = fColorStorage;
+ fPos = fPosStorage;
+ fCount = 2;
+ }
+ } else if (SkScalarNearlyEqual(pos[0], 0.0f) &&
+ SkScalarNearlyEqual(pos[1], 1.0f) &&
+ SkScalarNearlyEqual(pos[2], 1.0f)) {
+
+ if (SkShader::kRepeat_TileMode == mode ||
+ SkShader::kMirror_TileMode == mode ||
+ colors[1] == colors[2]) {
+
+ fCount = 2;
+ }
+ }
+ }
+
+ const SkColor* fColors;
+ const SkScalar* fPos;
+ int fCount;
+
+ SkColor fColorStorage[2];
+ SkScalar fPosStorage[2];
+};
+
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;
}
@@ -783,8 +832,10 @@ sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2],
return SkShader::MakeColorShader(colors[0]);
}
+ ColorStopOptimizer opt(colors, pos, colorCount, mode);
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix);
return sk_make_sp<SkLinearGradient>(pts, desc);
}
@@ -804,8 +855,10 @@ sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad
return SkShader::MakeColorShader(colors[0]);
}
+ ColorStopOptimizer opt(colors, pos, colorCount, mode);
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix);
return sk_make_sp<SkRadialGradient>(center, radius, desc);
}
@@ -832,24 +885,26 @@ sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start,
}
EXPAND_1_COLOR(colorCount);
+ ColorStopOptimizer opt(colors, pos, colorCount, mode);
+
bool flipGradient = startRadius > endRadius;
SkGradientShaderBase::Descriptor desc;
if (!flipGradient) {
- desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, 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] = opt.fColors[colorCount - i - 1];
}
if (pos) {
for (int i = 0; i < colorCount; ++i) {
- posNew[i] = 1 - pos[colorCount - i - 1];
+ posNew[i] = 1 - opt.fPos[colorCount - i - 1];
}
desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, flags, localMatrix);
} else {
@@ -874,8 +929,12 @@ sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy,
return SkShader::MakeColorShader(colors[0]);
}
+ auto mode = SkShader::kClamp_TileMode;
+
+ ColorStopOptimizer opt(colors, pos, colorCount, mode);
+
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix);
+ desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, 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