Index: tests/GradientTest.cpp |
diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp |
index 3ed2f518cc78fe61212f8befbf131ec6f040d967..1e8f3936b3faeabe0bc13a4b841f8d4e47dfbe0e 100644 |
--- a/tests/GradientTest.cpp |
+++ b/tests/GradientTest.cpp |
@@ -67,12 +67,12 @@ struct GradRec { |
}; |
-static void none_gradproc(skiatest::Reporter* reporter, const GradRec&) { |
+static void none_gradproc(skiatest::Reporter* reporter, const GradRec&, const GradRec&) { |
sk_sp<SkShader> s(SkShader::MakeEmptyShader()); |
REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(nullptr)); |
} |
-static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
+static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec, const GradRec&) { |
SkAutoTUnref<SkShader> s(new SkColorShader(rec.fColors[0])); |
REPORTER_ASSERT(reporter, SkShader::kColor_GradientType == s->asAGradient(nullptr)); |
@@ -83,48 +83,54 @@ static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
REPORTER_ASSERT(reporter, 1 == info.fColorCount); |
} |
-static void linear_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
- sk_sp<SkShader> s(SkGradientShader::MakeLinear(rec.fPoint, rec.fColors, rec.fPos, |
- rec.fColorCount, rec.fTileMode)); |
+static void linear_gradproc(skiatest::Reporter* reporter, const GradRec& buildRec, |
+ const GradRec& checkRec) { |
+ sk_sp<SkShader> s(SkGradientShader::MakeLinear(buildRec.fPoint, buildRec.fColors, buildRec.fPos, |
+ buildRec.fColorCount, buildRec.fTileMode)); |
SkShader::GradientInfo info; |
- rec.gradCheck(reporter, s, &info, SkShader::kLinear_GradientType); |
- REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint))); |
+ checkRec.gradCheck(reporter, s, &info, SkShader::kLinear_GradientType); |
+ REPORTER_ASSERT(reporter, !memcmp(info.fPoint, checkRec.fPoint, 2 * sizeof(SkPoint))); |
} |
-static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
- sk_sp<SkShader> s(SkGradientShader::MakeRadial(rec.fPoint[0], rec.fRadius[0], rec.fColors, |
- rec.fPos, rec.fColorCount, rec.fTileMode)); |
+static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& buildRec, |
+ const GradRec& checkRec) { |
+ sk_sp<SkShader> s(SkGradientShader::MakeRadial(buildRec.fPoint[0], buildRec.fRadius[0], |
+ buildRec.fColors, buildRec.fPos, |
+ buildRec.fColorCount, buildRec.fTileMode)); |
SkShader::GradientInfo info; |
- rec.gradCheck(reporter, s, &info, SkShader::kRadial_GradientType); |
- REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]); |
- REPORTER_ASSERT(reporter, info.fRadius[0] == rec.fRadius[0]); |
+ checkRec.gradCheck(reporter, s, &info, SkShader::kRadial_GradientType); |
+ REPORTER_ASSERT(reporter, info.fPoint[0] == checkRec.fPoint[0]); |
+ REPORTER_ASSERT(reporter, info.fRadius[0] == checkRec.fRadius[0]); |
} |
-static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
- sk_sp<SkShader> s(SkGradientShader::MakeSweep(rec.fPoint[0].fX, rec.fPoint[0].fY, rec.fColors, |
- rec.fPos, rec.fColorCount)); |
+static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& buildRec, |
+ const GradRec& checkRec) { |
+ sk_sp<SkShader> s(SkGradientShader::MakeSweep(buildRec.fPoint[0].fX, buildRec.fPoint[0].fY, |
+ buildRec.fColors, buildRec.fPos, |
+ buildRec.fColorCount)); |
SkShader::GradientInfo info; |
- rec.gradCheck(reporter, s, &info, SkShader::kSweep_GradientType); |
- REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]); |
+ checkRec.gradCheck(reporter, s, &info, SkShader::kSweep_GradientType); |
+ REPORTER_ASSERT(reporter, info.fPoint[0] == checkRec.fPoint[0]); |
} |
-static void conical_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { |
- sk_sp<SkShader> s(SkGradientShader::MakeTwoPointConical(rec.fPoint[0], |
- rec.fRadius[0], |
- rec.fPoint[1], |
- rec.fRadius[1], |
- rec.fColors, |
- rec.fPos, |
- rec.fColorCount, |
- rec.fTileMode)); |
+static void conical_gradproc(skiatest::Reporter* reporter, const GradRec& buildRec, |
+ const GradRec& checkRec) { |
+ sk_sp<SkShader> s(SkGradientShader::MakeTwoPointConical(buildRec.fPoint[0], |
+ buildRec.fRadius[0], |
+ buildRec.fPoint[1], |
+ buildRec.fRadius[1], |
+ buildRec.fColors, |
+ buildRec.fPos, |
+ buildRec.fColorCount, |
+ buildRec.fTileMode)); |
SkShader::GradientInfo info; |
- rec.gradCheck(reporter, s, &info, SkShader::kConical_GradientType); |
- REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint))); |
- REPORTER_ASSERT(reporter, !memcmp(info.fRadius, rec.fRadius, 2 * sizeof(SkScalar))); |
+ checkRec.gradCheck(reporter, s, &info, SkShader::kConical_GradientType); |
+ REPORTER_ASSERT(reporter, !memcmp(info.fPoint, checkRec.fPoint, 2 * sizeof(SkPoint))); |
+ REPORTER_ASSERT(reporter, !memcmp(info.fRadius, checkRec.fRadius, 2 * sizeof(SkScalar))); |
} |
// Ensure that repeated color gradients behave like drawing a single color |
@@ -150,7 +156,7 @@ static void TestConstantGradient(skiatest::Reporter*) { |
} |
} |
-typedef void (*GradProc)(skiatest::Reporter* reporter, const GradRec&); |
+typedef void (*GradProc)(skiatest::Reporter* reporter, const GradRec&, const GradRec&); |
static void TestGradientShaders(skiatest::Reporter* reporter) { |
static const SkColor gColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; |
@@ -179,7 +185,85 @@ static void TestGradientShaders(skiatest::Reporter* reporter) { |
}; |
for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) { |
- gProcs[i](reporter, rec); |
+ gProcs[i](reporter, rec, rec); |
+ } |
+} |
+ |
+static void TestGradientOptimization(skiatest::Reporter* reporter) { |
+ static const struct { |
+ GradProc fProc; |
+ bool fIsClampRestricted; |
+ } gProcInfo[] = { |
+ { linear_gradproc , false }, |
+ { radial_gradproc , false }, |
+ { sweep_gradproc , true }, // sweep is funky in that it always pretends to be kClamp. |
+ { conical_gradproc, false }, |
+ }; |
+ |
+ static const SkColor gC_00[] = { 0xff000000, 0xff000000 }; |
+ static const SkColor gC_01[] = { 0xff000000, 0xffffffff }; |
+ static const SkColor gC_11[] = { 0xffffffff, 0xffffffff }; |
+ static const SkColor gC_001[] = { 0xff000000, 0xff000000, 0xffffffff }; |
+ static const SkColor gC_011[] = { 0xff000000, 0xffffffff, 0xffffffff }; |
+ static const SkColor gC_0011[] = { 0xff000000, 0xff000000, 0xffffffff, 0xffffffff }; |
+ |
+ static const SkScalar gP_01[] = { 0, 1 }; |
+ static const SkScalar gP_001[] = { 0, 0, 1 }; |
+ static const SkScalar gP_011[] = { 0, 1, 1 }; |
+ static const SkScalar gP_0x1[] = { 0, .5f, 1 }; |
+ static const SkScalar gP_0011[] = { 0, 0, 1, 1 }; |
+ |
+ static const SkPoint gPts[] = { {0, 0}, {1, 1} }; |
+ static const SkScalar gRadii[] = { 1, 2 }; |
+ |
+ static const struct { |
+ const SkColor* fCol; |
+ const SkScalar* fPos; |
+ int fCount; |
+ |
+ const SkColor* fExpectedCol; |
+ const SkScalar* fExpectedPos; |
+ int fExpectedCount; |
+ bool fRequiresNonClamp; |
+ } gTests[] = { |
+ { gC_001, gP_001, 3, gC_01, gP_01, 2, false }, |
+ { gC_001, gP_011, 3, gC_00, gP_01, 2, true }, |
+ { gC_001, gP_0x1, 3, gC_001, gP_0x1, 3, false }, |
+ { gC_001, nullptr, 3, gC_001, gP_0x1, 3, false }, |
+ |
+ { gC_011, gP_001, 3, gC_11, gP_01, 2, true }, |
+ { gC_011, gP_011, 3, gC_01, gP_01, 2, false }, |
+ { gC_011, gP_0x1, 3, gC_011, gP_0x1, 3, false }, |
+ { gC_011, nullptr, 3, gC_011, gP_0x1, 3, false }, |
+ |
+ { gC_0011, gP_0011, 4, gC_0011, gP_0011, 4, false }, |
+ }; |
+ |
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gProcInfo); ++i) { |
+ for (int mode = 0; mode < SkShader::kTileModeCount; ++mode) { |
+ if (gProcInfo[i].fIsClampRestricted && mode != SkShader::kClamp_TileMode) { |
+ continue; |
+ } |
+ |
+ for (size_t t = 0; t < SK_ARRAY_COUNT(gTests); ++t) { |
+ GradRec rec; |
+ rec.fColorCount = gTests[t].fCount; |
+ rec.fColors = gTests[t].fCol; |
+ rec.fPos = gTests[t].fPos; |
+ rec.fTileMode = static_cast<SkShader::TileMode>(mode); |
+ rec.fPoint = gPts; |
+ rec.fRadius = gRadii; |
+ |
+ GradRec expected = rec; |
+ if (!gTests[t].fRequiresNonClamp || mode != SkShader::kClamp_TileMode) { |
+ expected.fColorCount = gTests[t].fExpectedCount; |
+ expected.fColors = gTests[t].fExpectedCol; |
+ expected.fPos = gTests[t].fExpectedPos; |
+ } |
+ |
+ gProcInfo[i].fProc(reporter, rec, expected); |
+ } |
+ } |
} |
} |
@@ -271,6 +355,7 @@ static void text_degenerate_linear(skiatest::Reporter*) { |
DEF_TEST(Gradient, reporter) { |
TestGradientShaders(reporter); |
+ TestGradientOptimization(reporter); |
TestConstantGradient(reporter); |
test_big_grad(reporter); |
test_nearly_vertical(reporter); |