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

Side by Side Diff: tests/GradientTest.cpp

Issue 2267593002: Add a gradient edge optimization test (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: rename test 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkColorShader.h" 10 #include "SkColorShader.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 REPORTER_ASSERT(reporter, info->fColorCount == fColorCount); 60 REPORTER_ASSERT(reporter, info->fColorCount == fColorCount);
61 REPORTER_ASSERT(reporter, 61 REPORTER_ASSERT(reporter,
62 !memcmp(info->fColors, fColors, fColorCount * sizeof(SkC olor))); 62 !memcmp(info->fColors, fColors, fColorCount * sizeof(SkC olor)));
63 REPORTER_ASSERT(reporter, 63 REPORTER_ASSERT(reporter,
64 !memcmp(info->fColorOffsets, fPos, fColorCount * sizeof( SkScalar))); 64 !memcmp(info->fColorOffsets, fPos, fColorCount * sizeof( SkScalar)));
65 REPORTER_ASSERT(reporter, fTileMode == info->fTileMode); 65 REPORTER_ASSERT(reporter, fTileMode == info->fTileMode);
66 } 66 }
67 }; 67 };
68 68
69 69
70 static void none_gradproc(skiatest::Reporter* reporter, const GradRec&) { 70 static void none_gradproc(skiatest::Reporter* reporter, const GradRec&, const Gr adRec&) {
71 sk_sp<SkShader> s(SkShader::MakeEmptyShader()); 71 sk_sp<SkShader> s(SkShader::MakeEmptyShader());
72 REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(nul lptr)); 72 REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(nul lptr));
73 } 73 }
74 74
75 static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { 75 static void color_gradproc(skiatest::Reporter* reporter, const GradRec& rec, con st GradRec&) {
76 SkAutoTUnref<SkShader> s(new SkColorShader(rec.fColors[0])); 76 SkAutoTUnref<SkShader> s(new SkColorShader(rec.fColors[0]));
77 REPORTER_ASSERT(reporter, SkShader::kColor_GradientType == s->asAGradient(nu llptr)); 77 REPORTER_ASSERT(reporter, SkShader::kColor_GradientType == s->asAGradient(nu llptr));
78 78
79 SkShader::GradientInfo info; 79 SkShader::GradientInfo info;
80 info.fColors = nullptr; 80 info.fColors = nullptr;
81 info.fColorCount = 0; 81 info.fColorCount = 0;
82 s->asAGradient(&info); 82 s->asAGradient(&info);
83 REPORTER_ASSERT(reporter, 1 == info.fColorCount); 83 REPORTER_ASSERT(reporter, 1 == info.fColorCount);
84 } 84 }
85 85
86 static void linear_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { 86 static void linear_gradproc(skiatest::Reporter* reporter, const GradRec& buildRe c,
87 sk_sp<SkShader> s(SkGradientShader::MakeLinear(rec.fPoint, rec.fColors, rec. fPos, 87 const GradRec& checkRec) {
88 rec.fColorCount, rec.fTileMod e)); 88 sk_sp<SkShader> s(SkGradientShader::MakeLinear(buildRec.fPoint, buildRec.fCo lors, buildRec.fPos,
89 buildRec.fColorCount, buildRe c.fTileMode));
89 90
90 SkShader::GradientInfo info; 91 SkShader::GradientInfo info;
91 rec.gradCheck(reporter, s, &info, SkShader::kLinear_GradientType); 92 checkRec.gradCheck(reporter, s, &info, SkShader::kLinear_GradientType);
92 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoin t))); 93 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, checkRec.fPoint, 2 * sizeof(S kPoint)));
93 } 94 }
94 95
95 static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { 96 static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& buildRe c,
96 sk_sp<SkShader> s(SkGradientShader::MakeRadial(rec.fPoint[0], rec.fRadius[0] , rec.fColors, 97 const GradRec& checkRec) {
97 rec.fPos, rec.fColorCount, re c.fTileMode)); 98 sk_sp<SkShader> s(SkGradientShader::MakeRadial(buildRec.fPoint[0], buildRec. fRadius[0],
99 buildRec.fColors, buildRec.fP os,
100 buildRec.fColorCount, buildRe c.fTileMode));
98 101
99 SkShader::GradientInfo info; 102 SkShader::GradientInfo info;
100 rec.gradCheck(reporter, s, &info, SkShader::kRadial_GradientType); 103 checkRec.gradCheck(reporter, s, &info, SkShader::kRadial_GradientType);
101 REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]); 104 REPORTER_ASSERT(reporter, info.fPoint[0] == checkRec.fPoint[0]);
102 REPORTER_ASSERT(reporter, info.fRadius[0] == rec.fRadius[0]); 105 REPORTER_ASSERT(reporter, info.fRadius[0] == checkRec.fRadius[0]);
103 } 106 }
104 107
105 static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { 108 static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& buildRec ,
106 sk_sp<SkShader> s(SkGradientShader::MakeSweep(rec.fPoint[0].fX, rec.fPoint[0 ].fY, rec.fColors, 109 const GradRec& checkRec) {
107 rec.fPos, rec.fColorCount)); 110 sk_sp<SkShader> s(SkGradientShader::MakeSweep(buildRec.fPoint[0].fX, buildRe c.fPoint[0].fY,
111 buildRec.fColors, buildRec.fPo s,
112 buildRec.fColorCount));
108 113
109 SkShader::GradientInfo info; 114 SkShader::GradientInfo info;
110 rec.gradCheck(reporter, s, &info, SkShader::kSweep_GradientType); 115 checkRec.gradCheck(reporter, s, &info, SkShader::kSweep_GradientType);
111 REPORTER_ASSERT(reporter, info.fPoint[0] == rec.fPoint[0]); 116 REPORTER_ASSERT(reporter, info.fPoint[0] == checkRec.fPoint[0]);
112 } 117 }
113 118
114 static void conical_gradproc(skiatest::Reporter* reporter, const GradRec& rec) { 119 static void conical_gradproc(skiatest::Reporter* reporter, const GradRec& buildR ec,
115 sk_sp<SkShader> s(SkGradientShader::MakeTwoPointConical(rec.fPoint[0], 120 const GradRec& checkRec) {
116 rec.fRadius[0], 121 sk_sp<SkShader> s(SkGradientShader::MakeTwoPointConical(buildRec.fPoint[0],
117 rec.fPoint[1], 122 buildRec.fRadius[0],
118 rec.fRadius[1], 123 buildRec.fPoint[1],
119 rec.fColors, 124 buildRec.fRadius[1],
120 rec.fPos, 125 buildRec.fColors,
121 rec.fColorCount, 126 buildRec.fPos,
122 rec.fTileMode)); 127 buildRec.fColorCount ,
128 buildRec.fTileMode)) ;
123 129
124 SkShader::GradientInfo info; 130 SkShader::GradientInfo info;
125 rec.gradCheck(reporter, s, &info, SkShader::kConical_GradientType); 131 checkRec.gradCheck(reporter, s, &info, SkShader::kConical_GradientType);
126 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoin t))); 132 REPORTER_ASSERT(reporter, !memcmp(info.fPoint, checkRec.fPoint, 2 * sizeof(S kPoint)));
127 REPORTER_ASSERT(reporter, !memcmp(info.fRadius, rec.fRadius, 2 * sizeof(SkSc alar))); 133 REPORTER_ASSERT(reporter, !memcmp(info.fRadius, checkRec.fRadius, 2 * sizeof (SkScalar)));
128 } 134 }
129 135
130 // Ensure that repeated color gradients behave like drawing a single color 136 // Ensure that repeated color gradients behave like drawing a single color
131 static void TestConstantGradient(skiatest::Reporter*) { 137 static void TestConstantGradient(skiatest::Reporter*) {
132 const SkPoint pts[] = { 138 const SkPoint pts[] = {
133 { 0, 0 }, 139 { 0, 0 },
134 { SkIntToScalar(10), 0 } 140 { SkIntToScalar(10), 0 }
135 }; 141 };
136 SkColor colors[] = { SK_ColorBLUE, SK_ColorBLUE }; 142 SkColor colors[] = { SK_ColorBLUE, SK_ColorBLUE };
137 const SkScalar pos[] = { 0, SK_Scalar1 }; 143 const SkScalar pos[] = { 0, SK_Scalar1 };
138 SkPaint paint; 144 SkPaint paint;
139 paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2, SkShader:: kClamp_TileMode)); 145 paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2, SkShader:: kClamp_TileMode));
140 SkBitmap outBitmap; 146 SkBitmap outBitmap;
141 outBitmap.allocN32Pixels(10, 1); 147 outBitmap.allocN32Pixels(10, 1);
142 SkCanvas canvas(outBitmap); 148 SkCanvas canvas(outBitmap);
143 canvas.drawPaint(paint); 149 canvas.drawPaint(paint);
144 SkAutoLockPixels alp(outBitmap); 150 SkAutoLockPixels alp(outBitmap);
145 for (int i = 0; i < 10; i++) { 151 for (int i = 0; i < 10; i++) {
146 // The following is commented out because it currently fails 152 // The following is commented out because it currently fails
147 // Related bug: https://code.google.com/p/skia/issues/detail?id=1098 153 // Related bug: https://code.google.com/p/skia/issues/detail?id=1098
148 154
149 // REPORTER_ASSERT(reporter, SK_ColorBLUE == outBitmap.getColor(i, 0)); 155 // REPORTER_ASSERT(reporter, SK_ColorBLUE == outBitmap.getColor(i, 0));
150 } 156 }
151 } 157 }
152 158
153 typedef void (*GradProc)(skiatest::Reporter* reporter, const GradRec&); 159 typedef void (*GradProc)(skiatest::Reporter* reporter, const GradRec&, const Gra dRec&);
154 160
155 static void TestGradientShaders(skiatest::Reporter* reporter) { 161 static void TestGradientShaders(skiatest::Reporter* reporter) {
156 static const SkColor gColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 162 static const SkColor gColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
157 static const SkScalar gPos[] = { 0, SK_ScalarHalf, SK_Scalar1 }; 163 static const SkScalar gPos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
158 static const SkPoint gPts[] = { 164 static const SkPoint gPts[] = {
159 { 0, 0 }, 165 { 0, 0 },
160 { SkIntToScalar(10), SkIntToScalar(20) } 166 { SkIntToScalar(10), SkIntToScalar(20) }
161 }; 167 };
162 static const SkScalar gRad[] = { SkIntToScalar(1), SkIntToScalar(2) }; 168 static const SkScalar gRad[] = { SkIntToScalar(1), SkIntToScalar(2) };
163 169
164 GradRec rec; 170 GradRec rec;
165 rec.fColorCount = SK_ARRAY_COUNT(gColors); 171 rec.fColorCount = SK_ARRAY_COUNT(gColors);
166 rec.fColors = gColors; 172 rec.fColors = gColors;
167 rec.fPos = gPos; 173 rec.fPos = gPos;
168 rec.fPoint = gPts; 174 rec.fPoint = gPts;
169 rec.fRadius = gRad; 175 rec.fRadius = gRad;
170 rec.fTileMode = SkShader::kClamp_TileMode; 176 rec.fTileMode = SkShader::kClamp_TileMode;
171 177
172 static const GradProc gProcs[] = { 178 static const GradProc gProcs[] = {
173 none_gradproc, 179 none_gradproc,
174 color_gradproc, 180 color_gradproc,
175 linear_gradproc, 181 linear_gradproc,
176 radial_gradproc, 182 radial_gradproc,
177 sweep_gradproc, 183 sweep_gradproc,
178 conical_gradproc, 184 conical_gradproc,
179 }; 185 };
180 186
181 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) { 187 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
182 gProcs[i](reporter, rec); 188 gProcs[i](reporter, rec, rec);
183 } 189 }
184 } 190 }
185 191
192 static void TestGradientOptimization(skiatest::Reporter* reporter) {
193 static const struct {
194 GradProc fProc;
195 bool fIsClampRestricted;
196 } gProcInfo[] = {
197 { linear_gradproc , false },
198 { radial_gradproc , false },
199 { sweep_gradproc , true }, // sweep is funky in that it always pretend s to be kClamp.
200 { conical_gradproc, false },
201 };
202
203 static const SkColor gC_00[] = { 0xff000000, 0xff000000 };
204 static const SkColor gC_01[] = { 0xff000000, 0xffffffff };
205 static const SkColor gC_11[] = { 0xffffffff, 0xffffffff };
206 static const SkColor gC_001[] = { 0xff000000, 0xff000000, 0xffffffff };
207 static const SkColor gC_011[] = { 0xff000000, 0xffffffff, 0xffffffff };
208 static const SkColor gC_0011[] = { 0xff000000, 0xff000000, 0xffffffff, 0xfff fffff };
209
210 static const SkScalar gP_01[] = { 0, 1 };
211 static const SkScalar gP_001[] = { 0, 0, 1 };
212 static const SkScalar gP_011[] = { 0, 1, 1 };
213 static const SkScalar gP_0x1[] = { 0, .5f, 1 };
214 static const SkScalar gP_0011[] = { 0, 0, 1, 1 };
215
216 static const SkPoint gPts[] = { {0, 0}, {1, 1} };
217 static const SkScalar gRadii[] = { 1, 2 };
218
219 static const struct {
220 const SkColor* fCol;
221 const SkScalar* fPos;
222 int fCount;
223
224 const SkColor* fExpectedCol;
225 const SkScalar* fExpectedPos;
226 int fExpectedCount;
227 bool fRequiresNonClamp;
228 } gTests[] = {
229 { gC_001, gP_001, 3, gC_01, gP_01, 2, false },
230 { gC_001, gP_011, 3, gC_00, gP_01, 2, true },
231 { gC_001, gP_0x1, 3, gC_001, gP_0x1, 3, false },
232 { gC_001, nullptr, 3, gC_001, gP_0x1, 3, false },
233
234 { gC_011, gP_001, 3, gC_11, gP_01, 2, true },
235 { gC_011, gP_011, 3, gC_01, gP_01, 2, false },
236 { gC_011, gP_0x1, 3, gC_011, gP_0x1, 3, false },
237 { gC_011, nullptr, 3, gC_011, gP_0x1, 3, false },
238
239 { gC_0011, gP_0011, 4, gC_0011, gP_0011, 4, false },
240 };
241
242 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcInfo); ++i) {
243 for (int mode = 0; mode < SkShader::kTileModeCount; ++mode) {
244 if (gProcInfo[i].fIsClampRestricted && mode != SkShader::kClamp_Tile Mode) {
245 continue;
246 }
247
248 for (size_t t = 0; t < SK_ARRAY_COUNT(gTests); ++t) {
249 GradRec rec;
250 rec.fColorCount = gTests[t].fCount;
251 rec.fColors = gTests[t].fCol;
252 rec.fPos = gTests[t].fPos;
253 rec.fTileMode = static_cast<SkShader::TileMode>(mode);
254 rec.fPoint = gPts;
255 rec.fRadius = gRadii;
256
257 GradRec expected = rec;
258 if (!gTests[t].fRequiresNonClamp || mode != SkShader::kClamp_Til eMode) {
259 expected.fColorCount = gTests[t].fExpectedCount;
260 expected.fColors = gTests[t].fExpectedCol;
261 expected.fPos = gTests[t].fExpectedPos;
262 }
263
264 gProcInfo[i].fProc(reporter, rec, expected);
265 }
266 }
267 }
268 }
269
186 static void test_nearly_vertical(skiatest::Reporter* reporter) { 270 static void test_nearly_vertical(skiatest::Reporter* reporter) {
187 auto surface(SkSurface::MakeRasterN32Premul(200, 200)); 271 auto surface(SkSurface::MakeRasterN32Premul(200, 200));
188 272
189 const SkPoint pts[] = {{ 100, 50 }, { 100.0001f, 50000 }}; 273 const SkPoint pts[] = {{ 100, 50 }, { 100.0001f, 50000 }};
190 const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE }; 274 const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
191 const SkScalar pos[] = { 0, 1 }; 275 const SkScalar pos[] = { 0, 1 };
192 SkPaint paint; 276 SkPaint paint;
193 paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2, SkShader:: kClamp_TileMode)); 277 paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2, SkShader:: kClamp_TileMode));
194 278
195 surface->getCanvas()->drawPaint(paint); 279 surface->getCanvas()->drawPaint(paint);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 348
265 p.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader:: kClamp_TileMode)); 349 p.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader:: kClamp_TileMode));
266 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); 350 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50));
267 surface->getCanvas()->drawPaint(p); 351 surface->getCanvas()->drawPaint(p);
268 352
269 // Passes if we don't trigger asserts. 353 // Passes if we don't trigger asserts.
270 } 354 }
271 355
272 DEF_TEST(Gradient, reporter) { 356 DEF_TEST(Gradient, reporter) {
273 TestGradientShaders(reporter); 357 TestGradientShaders(reporter);
358 TestGradientOptimization(reporter);
274 TestConstantGradient(reporter); 359 TestConstantGradient(reporter);
275 test_big_grad(reporter); 360 test_big_grad(reporter);
276 test_nearly_vertical(reporter); 361 test_nearly_vertical(reporter);
277 test_linear_fuzz(reporter); 362 test_linear_fuzz(reporter);
278 test_two_point_conical_zero_radius(reporter); 363 test_two_point_conical_zero_radius(reporter);
279 test_clamping_overflow(reporter); 364 test_clamping_overflow(reporter);
280 text_degenerate_linear(reporter); 365 text_degenerate_linear(reporter);
281 } 366 }
OLDNEW
« 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