roll libyuv to r1437 to resolve msan overread on odd width ARGBToYUY2.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_blending.cc
blobe2715e3907c6e494d933afdc1e8ffc6c2f74b4bb
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 "cc/layers/picture_image_layer.h"
6 #include "cc/layers/solid_color_layer.h"
7 #include "cc/test/layer_tree_pixel_resource_test.h"
8 #include "cc/test/pixel_comparator.h"
10 #if !defined(OS_ANDROID)
12 namespace cc {
13 namespace {
15 SkXfermode::Mode const kBlendModes[] = {
16 SkXfermode::kSrcOver_Mode, SkXfermode::kScreen_Mode,
17 SkXfermode::kOverlay_Mode, SkXfermode::kDarken_Mode,
18 SkXfermode::kLighten_Mode, SkXfermode::kColorDodge_Mode,
19 SkXfermode::kColorBurn_Mode, SkXfermode::kHardLight_Mode,
20 SkXfermode::kSoftLight_Mode, SkXfermode::kDifference_Mode,
21 SkXfermode::kExclusion_Mode, SkXfermode::kMultiply_Mode,
22 SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode,
23 SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode};
25 SkColor kCSSTestColors[] = {
26 0xffff0000, // red
27 0xff00ff00, // lime
28 0xff0000ff, // blue
29 0xff00ffff, // aqua
30 0xffff00ff, // fuchsia
31 0xffffff00, // yellow
32 0xff008000, // green
33 0xff800000, // maroon
34 0xff000080, // navy
35 0xff800080, // purple
36 0xff808000, // olive
37 0xff008080, // teal
38 0xfffa8072, // salmon
39 0xffc0c0c0, // silver
40 0xff000000, // black
41 0xff808080, // gray
42 0x80000000, // black with transparency
43 0xffffffff, // white
44 0x80ffffff, // white with transparency
45 0x00000000 // transparent
48 const int kBlendModesCount = arraysize(kBlendModes);
49 const int kCSSTestColorsCount = arraysize(kCSSTestColors);
51 using RenderPassOptions = uint32;
52 const uint32 kUseMasks = 1 << 0;
53 const uint32 kUseAntialiasing = 1 << 1;
54 const uint32 kUseColorMatrix = 1 << 2;
55 const uint32 kForceShaders = 1 << 3;
57 class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest {
58 public:
59 LayerTreeHostBlendingPixelTest()
60 : force_antialiasing_(false), force_blending_with_shaders_(false) {
61 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
64 void InitializeSettings(LayerTreeSettings* settings) override {
65 settings->renderer_settings.force_antialiasing = force_antialiasing_;
66 settings->renderer_settings.force_blending_with_shaders =
67 force_blending_with_shaders_;
70 protected:
71 void RunBlendingWithRootPixelTestType(PixelResourceTestCase type) {
72 const int kLaneWidth = 2;
73 const int kLaneHeight = kLaneWidth;
74 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
75 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
76 InitializeFromTestCase(type);
78 scoped_refptr<SolidColorLayer> background =
79 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
81 // Orange child layers will blend with the green background
82 for (int i = 0; i < kBlendModesCount; ++i) {
83 gfx::Rect child_rect(
84 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
85 scoped_refptr<SolidColorLayer> green_lane =
86 CreateSolidColorLayer(child_rect, kCSSGreen);
87 background->AddChild(green_lane);
88 green_lane->SetBlendMode(kBlendModes[i]);
91 RunPixelResourceTest(
92 background,
93 base::FilePath(FILE_PATH_LITERAL("blending_with_root.png")));
96 void RunBlendingWithTransparentPixelTestType(PixelResourceTestCase type) {
97 const int kLaneWidth = 2;
98 const int kLaneHeight = 3 * kLaneWidth;
99 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
100 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
101 InitializeFromTestCase(type);
103 scoped_refptr<SolidColorLayer> root =
104 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSBrown);
106 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
107 gfx::Rect(0, kLaneWidth * 2, kRootWidth, kLaneWidth), kCSSOrange);
109 root->AddChild(background);
110 background->SetIsRootForIsolatedGroup(true);
112 // Orange child layers will blend with the green background
113 for (int i = 0; i < kBlendModesCount; ++i) {
114 gfx::Rect child_rect(
115 (i + 1) * kLaneWidth, -kLaneWidth, kLaneWidth, kLaneHeight);
116 scoped_refptr<SolidColorLayer> green_lane =
117 CreateSolidColorLayer(child_rect, kCSSGreen);
118 background->AddChild(green_lane);
119 green_lane->SetBlendMode(kBlendModes[i]);
122 RunPixelResourceTest(
123 root, base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
126 scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
127 // Draw the backdrop with horizontal lanes.
128 const int kLaneWidth = width;
129 const int kLaneHeight = height / kCSSTestColorsCount;
130 SkBitmap backing_store;
131 backing_store.allocN32Pixels(width, height);
132 SkCanvas canvas(backing_store);
133 canvas.clear(SK_ColorTRANSPARENT);
134 for (int i = 0; i < kCSSTestColorsCount; ++i) {
135 SkPaint paint;
136 paint.setColor(kCSSTestColors[i]);
137 canvas.drawRect(
138 SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
140 scoped_refptr<PictureImageLayer> layer =
141 PictureImageLayer::Create(layer_settings());
142 layer->SetIsDrawable(true);
143 layer->SetBounds(gfx::Size(width, height));
144 layer->SetBitmap(backing_store);
145 return layer;
148 void SetupMaskLayer(scoped_refptr<Layer> layer) {
149 const int kMaskOffset = 2;
150 gfx::Size bounds = layer->bounds();
151 scoped_refptr<PictureImageLayer> mask =
152 PictureImageLayer::Create(layer_settings());
153 mask->SetIsDrawable(true);
154 mask->SetIsMask(true);
155 mask->SetBounds(bounds);
157 SkBitmap bitmap;
158 bitmap.allocN32Pixels(bounds.width(), bounds.height());
159 SkCanvas canvas(bitmap);
160 SkPaint paint;
161 paint.setColor(SK_ColorWHITE);
162 canvas.clear(SK_ColorTRANSPARENT);
163 canvas.drawRect(SkRect::MakeXYWH(kMaskOffset,
164 kMaskOffset,
165 bounds.width() - kMaskOffset * 2,
166 bounds.height() - kMaskOffset * 2),
167 paint);
168 mask->SetBitmap(bitmap);
169 layer->SetMaskLayer(mask.get());
172 void SetupColorMatrix(scoped_refptr<Layer> layer) {
173 FilterOperations filter_operations;
174 filter_operations.Append(FilterOperation::CreateSepiaFilter(.001f));
175 layer->SetFilters(filter_operations);
178 void CreateBlendingColorLayers(int lane_width,
179 int lane_height,
180 scoped_refptr<Layer> background,
181 RenderPassOptions flags) {
182 const int kLanesCount = kBlendModesCount + 4;
183 const SkColor kMiscOpaqueColor = 0xffc86464;
184 const SkColor kMiscTransparentColor = 0x80c86464;
185 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
186 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
187 // add vertical lanes with each of the blend modes
188 for (int i = 0; i < kLanesCount; ++i) {
189 gfx::Rect child_rect(i * lane_width, 0, lane_width, lane_height);
190 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
191 float opacity = 1.f;
192 SkColor color = kMiscOpaqueColor;
194 if (i < kBlendModesCount) {
195 blend_mode = kBlendModes[i];
196 } else if (i == kBlendModesCount) {
197 blend_mode = kCoeffBlendMode;
198 opacity = 0.5f;
199 } else if (i == kBlendModesCount + 1) {
200 blend_mode = kCoeffBlendMode;
201 color = kMiscTransparentColor;
202 } else if (i == kBlendModesCount + 2) {
203 blend_mode = kShaderBlendMode;
204 opacity = 0.5f;
205 } else if (i == kBlendModesCount + 3) {
206 blend_mode = kShaderBlendMode;
207 color = kMiscTransparentColor;
210 scoped_refptr<SolidColorLayer> lane =
211 CreateSolidColorLayer(child_rect, color);
212 lane->SetBlendMode(blend_mode);
213 lane->SetOpacity(opacity);
214 lane->SetForceRenderSurface(true);
215 if (flags & kUseMasks)
216 SetupMaskLayer(lane);
217 if (flags & kUseColorMatrix) {
218 SetupColorMatrix(lane);
220 background->AddChild(lane);
224 void RunBlendingWithRenderPass(PixelResourceTestCase type,
225 const base::FilePath::CharType* expected_path,
226 RenderPassOptions flags) {
227 const int kLaneWidth = 8;
228 const int kLaneHeight = kLaneWidth * kCSSTestColorsCount;
229 const int kRootSize = kLaneHeight;
230 InitializeFromTestCase(type);
232 scoped_refptr<SolidColorLayer> root =
233 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
234 scoped_refptr<Layer> background =
235 CreateColorfulBackdropLayer(kRootSize, kRootSize);
237 background->SetIsRootForIsolatedGroup(true);
238 root->AddChild(background);
240 CreateBlendingColorLayers(kLaneWidth, kLaneHeight, background.get(), flags);
242 this->force_antialiasing_ = (flags & kUseAntialiasing);
243 this->force_blending_with_shaders_ = (flags & kForceShaders);
245 if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
246 // Anti aliasing causes differences up to 8 pixels at the edges.
247 int large_error_allowed = 8;
248 // Blending results might differ with one pixel.
249 int small_error_allowed = 1;
250 // Most of the errors are one pixel errors.
251 float percentage_pixels_small_error = 13.1f;
252 // Because of anti-aliasing, around 10% of pixels (at the edges) have
253 // bigger errors (from small_error_allowed + 1 to large_error_allowed).
254 float percentage_pixels_error = 22.5f;
255 // The average error is still close to 1.
256 float average_error_allowed_in_bad_pixels = 1.4f;
258 pixel_comparator_.reset(
259 new FuzzyPixelComparator(false, // discard_alpha
260 percentage_pixels_error,
261 percentage_pixels_small_error,
262 average_error_allowed_in_bad_pixels,
263 large_error_allowed,
264 small_error_allowed));
267 RunPixelResourceTest(root, base::FilePath(expected_path));
270 bool force_antialiasing_;
271 bool force_blending_with_shaders_;
274 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
275 RunBlendingWithRootPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
278 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
279 RunBlendingWithRootPixelTestType(SOFTWARE);
282 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
283 const int kLaneWidth = 2;
284 const int kLaneHeight = kLaneWidth;
285 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
286 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
287 InitializeFromTestCase(GL_ASYNC_UPLOAD_2D_DRAW);
289 scoped_refptr<SolidColorLayer> background =
290 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
292 // Orange child layers have a background filter set and they will blend with
293 // the green background
294 for (int i = 0; i < kBlendModesCount; ++i) {
295 gfx::Rect child_rect(
296 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
297 scoped_refptr<SolidColorLayer> green_lane =
298 CreateSolidColorLayer(child_rect, kCSSGreen);
299 background->AddChild(green_lane);
301 FilterOperations filters;
302 filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
303 green_lane->SetBackgroundFilters(filters);
304 green_lane->SetBlendMode(kBlendModes[i]);
307 RunPixelResourceTest(
308 background, base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
311 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
312 RunBlendingWithTransparentPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
315 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
316 RunBlendingWithTransparentPixelTestType(SOFTWARE);
319 // Tests for render passes
320 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
321 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
322 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
325 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
326 RunBlendingWithRenderPass(SOFTWARE,
327 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
330 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
331 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
332 FILE_PATH_LITERAL("blending_render_pass.png"),
333 kUseAntialiasing);
336 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
337 RunBlendingWithRenderPass(SOFTWARE,
338 FILE_PATH_LITERAL("blending_render_pass.png"),
339 kUseAntialiasing);
342 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
343 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
344 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
345 kUseMasks);
348 TEST_F(LayerTreeHostBlendingPixelTest,
349 BlendingWithRenderPassWithMask_Software) {
350 RunBlendingWithRenderPass(
351 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass_mask.png"), kUseMasks);
354 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
355 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
356 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
357 kUseMasks | kUseAntialiasing);
360 TEST_F(LayerTreeHostBlendingPixelTest,
361 BlendingWithRenderPassWithMaskAA_Software) {
362 RunBlendingWithRenderPass(SOFTWARE,
363 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
364 kUseMasks | kUseAntialiasing);
367 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
368 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
369 FILE_PATH_LITERAL("blending_render_pass.png"),
370 kUseColorMatrix);
373 TEST_F(LayerTreeHostBlendingPixelTest,
374 BlendingWithRenderPassColorMatrix_Software) {
375 RunBlendingWithRenderPass(
376 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), kUseColorMatrix);
379 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
380 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
381 FILE_PATH_LITERAL("blending_render_pass.png"),
382 kUseAntialiasing | kUseColorMatrix);
385 TEST_F(LayerTreeHostBlendingPixelTest,
386 BlendingWithRenderPassColorMatrixAA_Software) {
387 RunBlendingWithRenderPass(SOFTWARE,
388 FILE_PATH_LITERAL("blending_render_pass.png"),
389 kUseAntialiasing | kUseColorMatrix);
392 TEST_F(LayerTreeHostBlendingPixelTest,
393 BlendingWithRenderPassWithMaskColorMatrix_GL) {
394 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
395 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
396 kUseMasks | kUseColorMatrix);
399 TEST_F(LayerTreeHostBlendingPixelTest,
400 BlendingWithRenderPassWithMaskColorMatrix_Software) {
401 RunBlendingWithRenderPass(SOFTWARE,
402 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
403 kUseMasks | kUseColorMatrix);
406 TEST_F(LayerTreeHostBlendingPixelTest,
407 BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
408 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
409 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
410 kUseMasks | kUseAntialiasing | kUseColorMatrix);
413 TEST_F(LayerTreeHostBlendingPixelTest,
414 BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
415 RunBlendingWithRenderPass(SOFTWARE,
416 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
417 kUseMasks | kUseAntialiasing | kUseColorMatrix);
420 // Tests for render passes forcing shaders for all the blend modes.
421 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
422 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
423 FILE_PATH_LITERAL("blending_render_pass.png"),
424 kForceShaders);
427 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
428 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
429 FILE_PATH_LITERAL("blending_render_pass.png"),
430 kUseAntialiasing | kForceShaders);
433 TEST_F(LayerTreeHostBlendingPixelTest,
434 BlendingWithRenderPassShadersWithMask_GL) {
435 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
436 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
437 kUseMasks | kForceShaders);
440 TEST_F(LayerTreeHostBlendingPixelTest,
441 BlendingWithRenderPassShadersWithMask_GL_TextureRect) {
442 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
443 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
444 kUseMasks | kForceShaders);
447 TEST_F(LayerTreeHostBlendingPixelTest,
448 BlendingWithRenderPassShadersWithMaskAA_GL) {
449 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
450 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
451 kUseMasks | kUseAntialiasing | kForceShaders);
454 TEST_F(LayerTreeHostBlendingPixelTest,
455 BlendingWithRenderPassShadersWithMaskAA_GL_TextureRect) {
456 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
457 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
458 kUseMasks | kUseAntialiasing | kForceShaders);
461 TEST_F(LayerTreeHostBlendingPixelTest,
462 BlendingWithRenderPassShadersColorMatrix_GL) {
463 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
464 FILE_PATH_LITERAL("blending_render_pass.png"),
465 kUseColorMatrix | kForceShaders);
468 TEST_F(LayerTreeHostBlendingPixelTest,
469 BlendingWithRenderPassShadersColorMatrixAA_GL) {
470 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
471 FILE_PATH_LITERAL("blending_render_pass.png"),
472 kUseAntialiasing | kUseColorMatrix | kForceShaders);
475 TEST_F(LayerTreeHostBlendingPixelTest,
476 BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
477 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
478 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
479 kUseMasks | kUseColorMatrix | kForceShaders);
482 TEST_F(LayerTreeHostBlendingPixelTest,
483 BlendingWithRenderPassShadersWithMaskColorMatrix_GL_TextureRect) {
484 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
485 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
486 kUseMasks | kUseColorMatrix | kForceShaders);
489 TEST_F(LayerTreeHostBlendingPixelTest,
490 BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
491 RunBlendingWithRenderPass(
492 GL_ASYNC_UPLOAD_2D_DRAW,
493 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
494 kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
497 } // namespace
498 } // namespace cc
500 #endif // OS_ANDROID