Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_masks.cc
blob97765bda71ae8d7797979698da341f516322a802
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "build/build_config.h"
6 #include "cc/layers/content_layer_client.h"
7 #include "cc/layers/picture_image_layer.h"
8 #include "cc/layers/picture_layer.h"
9 #include "cc/layers/solid_color_layer.h"
10 #include "cc/test/layer_tree_pixel_resource_test.h"
11 #include "cc/test/pixel_comparator.h"
13 #if !defined(OS_ANDROID)
15 namespace cc {
16 namespace {
18 typedef ParameterizedPixelResourceTest LayerTreeHostMasksPixelTest;
20 INSTANTIATE_PIXEL_RESOURCE_TEST_CASE_P(LayerTreeHostMasksPixelTest);
22 class MaskContentLayerClient : public ContentLayerClient {
23 public:
24 explicit MaskContentLayerClient(const gfx::Size& bounds) : bounds_(bounds) {}
25 ~MaskContentLayerClient() override {}
27 bool FillsBoundsCompletely() const override { return false; }
29 void PaintContents(SkCanvas* canvas,
30 const gfx::Rect& rect,
31 PaintingControlSetting picture_control) override {
32 SkPaint paint;
33 paint.setStyle(SkPaint::kStroke_Style);
34 paint.setStrokeWidth(SkIntToScalar(2));
35 paint.setColor(SK_ColorWHITE);
37 canvas->clear(SK_ColorTRANSPARENT);
38 gfx::Rect inset_rect(bounds_);
39 while (!inset_rect.IsEmpty()) {
40 inset_rect.Inset(3, 3, 2, 2);
41 canvas->drawRect(
42 SkRect::MakeXYWH(inset_rect.x(), inset_rect.y(),
43 inset_rect.width(), inset_rect.height()),
44 paint);
45 inset_rect.Inset(3, 3, 2, 2);
49 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
50 const gfx::Rect& clip,
51 PaintingControlSetting picture_control) override {
52 NOTIMPLEMENTED();
53 return DisplayItemList::Create();
56 private:
57 gfx::Size bounds_;
60 TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) {
61 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
62 gfx::Rect(100, 100), SK_ColorWHITE);
64 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
65 gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
66 background->AddChild(green);
68 gfx::Size mask_bounds(50, 50);
69 MaskContentLayerClient client(mask_bounds);
70 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
71 mask->SetBounds(mask_bounds);
72 mask->SetIsDrawable(true);
73 mask->SetIsMask(true);
74 green->SetMaskLayer(mask.get());
76 RunPixelResourceTest(background,
77 base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png")));
80 TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
81 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
82 gfx::Rect(100, 100), SK_ColorWHITE);
84 gfx::Size mask_bounds(50, 50);
86 scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
87 mask->SetIsDrawable(true);
88 mask->SetIsMask(true);
89 mask->SetBounds(mask_bounds);
91 SkBitmap bitmap;
92 bitmap.allocN32Pixels(200, 200);
93 SkCanvas canvas(bitmap);
94 canvas.scale(SkIntToScalar(4), SkIntToScalar(4));
95 MaskContentLayerClient client(mask_bounds);
96 client.PaintContents(&canvas, gfx::Rect(mask_bounds),
97 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
98 mask->SetBitmap(bitmap);
100 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
101 gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
102 green->SetMaskLayer(mask.get());
103 background->AddChild(green);
105 RunPixelResourceTest(
106 background, base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")));
109 TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) {
110 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
111 gfx::Rect(100, 100), SK_ColorWHITE);
113 // Clip to the top half of the green layer.
114 scoped_refptr<Layer> clip = Layer::Create();
115 clip->SetPosition(gfx::Point(0, 0));
116 clip->SetBounds(gfx::Size(100, 50));
117 clip->SetMasksToBounds(true);
118 background->AddChild(clip);
120 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
121 gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
122 clip->AddChild(green);
124 gfx::Size mask_bounds(50, 50);
125 MaskContentLayerClient client(mask_bounds);
126 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
127 mask->SetBounds(mask_bounds);
128 mask->SetIsDrawable(true);
129 mask->SetIsMask(true);
130 green->SetMaskLayer(mask.get());
132 RunPixelResourceTest(
133 background,
134 base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png")));
137 TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplica) {
138 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
139 gfx::Rect(100, 100), SK_ColorWHITE);
141 gfx::Size mask_bounds(50, 50);
142 MaskContentLayerClient client(mask_bounds);
143 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
144 mask->SetBounds(mask_bounds);
145 mask->SetIsDrawable(true);
146 mask->SetIsMask(true);
148 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
149 gfx::Rect(0, 0, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
150 background->AddChild(green);
151 green->SetMaskLayer(mask.get());
153 gfx::Transform replica_transform;
154 replica_transform.Rotate(-90.0);
156 scoped_refptr<Layer> replica = Layer::Create();
157 replica->SetTransformOrigin(gfx::Point3F(25.f, 25.f, 0.f));
158 replica->SetPosition(gfx::Point(50, 50));
159 replica->SetTransform(replica_transform);
160 green->SetReplicaLayer(replica.get());
162 RunPixelResourceTest(
163 background, base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png")));
166 TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) {
167 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
168 gfx::Rect(100, 100), SK_ColorWHITE);
170 gfx::Size mask_bounds(50, 50);
171 MaskContentLayerClient client(mask_bounds);
172 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
173 mask->SetBounds(mask_bounds);
174 mask->SetIsDrawable(true);
175 mask->SetIsMask(true);
177 // Clip to the bottom half of the green layer, and the left half of the
178 // replica.
179 scoped_refptr<Layer> clip = Layer::Create();
180 clip->SetPosition(gfx::Point(0, 25));
181 clip->SetBounds(gfx::Size(75, 75));
182 clip->SetMasksToBounds(true);
183 background->AddChild(clip);
185 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
186 gfx::Rect(0, -25, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
187 clip->AddChild(green);
188 green->SetMaskLayer(mask.get());
190 gfx::Transform replica_transform;
191 replica_transform.Rotate(-90.0);
193 scoped_refptr<Layer> replica = Layer::Create();
194 replica->SetTransformOrigin(gfx::Point3F(25.f, 25.f, 0.f));
195 replica->SetPosition(gfx::Point(50, 50));
196 replica->SetTransform(replica_transform);
197 green->SetReplicaLayer(replica.get());
199 RunPixelResourceTest(background,
200 base::FilePath(FILE_PATH_LITERAL(
201 "mask_with_replica_of_clipped_layer.png")));
204 TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplica) {
205 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
206 gfx::Rect(100, 100), SK_ColorWHITE);
208 gfx::Size mask_bounds(50, 50);
209 MaskContentLayerClient client(mask_bounds);
210 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
211 mask->SetBounds(mask_bounds);
212 mask->SetIsDrawable(true);
213 mask->SetIsMask(true);
215 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
216 gfx::Rect(25, 0, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
217 background->AddChild(green);
219 scoped_refptr<SolidColorLayer> orange = CreateSolidColorLayer(
220 gfx::Rect(-25, 25, 25, 25), kCSSOrange);
221 green->AddChild(orange);
223 gfx::Transform replica_transform;
224 replica_transform.Rotate(180.0);
225 replica_transform.Translate(50.0, 0.0);
227 scoped_refptr<Layer> replica = Layer::Create();
228 replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
229 replica->SetPosition(gfx::Point());
230 replica->SetTransform(replica_transform);
231 replica->SetMaskLayer(mask.get());
232 green->SetReplicaLayer(replica.get());
234 RunPixelResourceTest(
235 background, base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png")));
238 TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) {
239 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
240 gfx::Rect(100, 100), SK_ColorWHITE);
242 gfx::Size mask_bounds(50, 50);
243 MaskContentLayerClient client(mask_bounds);
244 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
245 mask->SetBounds(mask_bounds);
246 mask->SetIsDrawable(true);
247 mask->SetIsMask(true);
249 // Clip to the bottom 3/4 of the green layer, and the top 3/4 of the replica.
250 scoped_refptr<Layer> clip = Layer::Create();
251 clip->SetPosition(gfx::Point(0, 12));
252 clip->SetBounds(gfx::Size(100, 75));
253 clip->SetMasksToBounds(true);
254 background->AddChild(clip);
256 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
257 gfx::Rect(25, -12, 50, 50), kCSSGreen, 1, SK_ColorBLACK);
258 clip->AddChild(green);
260 scoped_refptr<SolidColorLayer> orange = CreateSolidColorLayer(
261 gfx::Rect(-25, 25, 25, 25), kCSSOrange);
262 green->AddChild(orange);
264 gfx::Transform replica_transform;
265 replica_transform.Rotate(180.0);
266 replica_transform.Translate(50.0, 0.0);
268 scoped_refptr<Layer> replica = Layer::Create();
269 replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
270 replica->SetPosition(gfx::Point());
271 replica->SetTransform(replica_transform);
272 replica->SetMaskLayer(mask.get());
273 green->SetReplicaLayer(replica.get());
275 RunPixelResourceTest(background,
276 base::FilePath(FILE_PATH_LITERAL(
277 "mask_of_replica_of_clipped_layer.png")));
280 class CheckerContentLayerClient : public ContentLayerClient {
281 public:
282 CheckerContentLayerClient(const gfx::Size& bounds,
283 SkColor color,
284 bool vertical)
285 : bounds_(bounds), color_(color), vertical_(vertical) {}
286 ~CheckerContentLayerClient() override {}
287 bool FillsBoundsCompletely() const override { return false; }
288 void PaintContents(SkCanvas* canvas,
289 const gfx::Rect& rect,
290 PaintingControlSetting picture_control) override {
291 SkPaint paint;
292 paint.setStyle(SkPaint::kStroke_Style);
293 paint.setStrokeWidth(SkIntToScalar(4));
294 paint.setColor(color_);
295 canvas->clear(SK_ColorTRANSPARENT);
296 if (vertical_) {
297 for (int i = 4; i < bounds_.width(); i += 16) {
298 canvas->drawLine(i, 0, i, bounds_.height(), paint);
300 } else {
301 for (int i = 4; i < bounds_.height(); i += 16) {
302 canvas->drawLine(0, i, bounds_.width(), i, paint);
306 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
307 const gfx::Rect& clip,
308 PaintingControlSetting picture_control) override {
309 NOTIMPLEMENTED();
310 return DisplayItemList::Create();
313 private:
314 gfx::Size bounds_;
315 SkColor color_;
316 bool vertical_;
319 class CircleContentLayerClient : public ContentLayerClient {
320 public:
321 explicit CircleContentLayerClient(const gfx::Size& bounds)
322 : bounds_(bounds) {}
323 ~CircleContentLayerClient() override {}
324 bool FillsBoundsCompletely() const override { return false; }
325 void PaintContents(SkCanvas* canvas,
326 const gfx::Rect& rect,
327 PaintingControlSetting picture_control) override {
328 SkPaint paint;
329 paint.setStyle(SkPaint::kFill_Style);
330 paint.setColor(SK_ColorWHITE);
331 canvas->clear(SK_ColorTRANSPARENT);
332 canvas->drawCircle(bounds_.width() / 2,
333 bounds_.height() / 2,
334 bounds_.width() / 4,
335 paint);
337 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
338 const gfx::Rect& clip,
339 PaintingControlSetting picture_control) override {
340 NOTIMPLEMENTED();
341 return DisplayItemList::Create();
344 private:
345 gfx::Size bounds_;
348 using LayerTreeHostMasksForBackgroundFiltersPixelTest =
349 ParameterizedPixelResourceTest;
351 INSTANTIATE_TEST_CASE_P(
352 PixelResourceTest,
353 LayerTreeHostMasksForBackgroundFiltersPixelTest,
354 ::testing::Values(
355 // SOFTWARE, Background filters aren't implemented in software
356 GL_GPU_RASTER_2D_DRAW,
357 GL_ONE_COPY_2D_STAGING_2D_DRAW,
358 GL_ONE_COPY_RECT_STAGING_2D_DRAW,
359 GL_ONE_COPY_EXTERNAL_STAGING_2D_DRAW,
360 GL_ZERO_COPY_2D_DRAW,
361 GL_ZERO_COPY_RECT_DRAW,
362 GL_ZERO_COPY_EXTERNAL_DRAW,
363 GL_ASYNC_UPLOAD_2D_DRAW));
365 TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
366 MaskOfLayerWithBackgroundFilter) {
367 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
368 gfx::Rect(100, 100), SK_ColorWHITE);
370 gfx::Size picture_bounds(100, 100);
371 CheckerContentLayerClient picture_client(picture_bounds, SK_ColorGREEN, true);
372 scoped_refptr<PictureLayer> picture = PictureLayer::Create(&picture_client);
373 picture->SetBounds(picture_bounds);
374 picture->SetIsDrawable(true);
376 scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
377 gfx::Rect(100, 100), SK_ColorTRANSPARENT);
378 background->AddChild(picture);
379 background->AddChild(blur);
381 FilterOperations filters;
382 filters.Append(FilterOperation::CreateBlurFilter(1.5f));
383 blur->SetBackgroundFilters(filters);
385 gfx::Size mask_bounds(100, 100);
386 CircleContentLayerClient mask_client(mask_bounds);
387 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
388 mask->SetBounds(mask_bounds);
389 mask->SetIsDrawable(true);
390 mask->SetIsMask(true);
391 blur->SetMaskLayer(mask.get());
393 float percentage_pixels_large_error = 2.5f; // 2.5%, ~250px / (100*100)
394 float percentage_pixels_small_error = 0.0f;
395 float average_error_allowed_in_bad_pixels = 100.0f;
396 int large_error_allowed = 256;
397 int small_error_allowed = 0;
398 pixel_comparator_.reset(new FuzzyPixelComparator(
399 true, // discard_alpha
400 percentage_pixels_large_error,
401 percentage_pixels_small_error,
402 average_error_allowed_in_bad_pixels,
403 large_error_allowed,
404 small_error_allowed));
406 RunPixelResourceTest(background,
407 base::FilePath(
408 FILE_PATH_LITERAL("mask_of_background_filter.png")));
411 TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
412 MaskOfLayerWithBlend) {
413 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
414 gfx::Rect(128, 128), SK_ColorWHITE);
416 gfx::Size picture_bounds(128, 128);
417 CheckerContentLayerClient picture_client_vertical(
418 picture_bounds, SK_ColorGREEN, true);
419 scoped_refptr<PictureLayer> picture_vertical =
420 PictureLayer::Create(&picture_client_vertical);
421 picture_vertical->SetBounds(picture_bounds);
422 picture_vertical->SetIsDrawable(true);
424 CheckerContentLayerClient picture_client_horizontal(
425 picture_bounds, SK_ColorMAGENTA, false);
426 scoped_refptr<PictureLayer> picture_horizontal =
427 PictureLayer::Create(&picture_client_horizontal);
428 picture_horizontal->SetBounds(picture_bounds);
429 picture_horizontal->SetIsDrawable(true);
430 picture_horizontal->SetContentsOpaque(false);
431 picture_horizontal->SetBlendMode(SkXfermode::kMultiply_Mode);
433 background->AddChild(picture_vertical);
434 background->AddChild(picture_horizontal);
436 gfx::Size mask_bounds(128, 128);
437 CircleContentLayerClient mask_client(mask_bounds);
438 scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
439 mask->SetBounds(mask_bounds);
440 mask->SetIsDrawable(true);
441 mask->SetIsMask(true);
442 picture_horizontal->SetMaskLayer(mask.get());
444 float percentage_pixels_large_error = 0.04f; // 0.04%, ~6px / (128*128)
445 float percentage_pixels_small_error = 0.0f;
446 float average_error_allowed_in_bad_pixels = 256.0f;
447 int large_error_allowed = 256;
448 int small_error_allowed = 0;
449 pixel_comparator_.reset(new FuzzyPixelComparator(
450 true, // discard_alpha
451 percentage_pixels_large_error,
452 percentage_pixels_small_error,
453 average_error_allowed_in_bad_pixels,
454 large_error_allowed,
455 small_error_allowed));
457 RunPixelResourceTest(background,
458 base::FilePath(
459 FILE_PATH_LITERAL("mask_of_layer_with_blend.png")));
462 } // namespace
463 } // namespace cc
465 #endif // !defined(OS_ANDROID)