Reland of Add channel-specific product logo to chrome://help (patchset #1 id:1 of...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_blending.cc
blob3a7feefaf1591ce226305da519ca9dc22273b607
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"
9 #include "third_party/skia/include/core/SkImage.h"
10 #include "third_party/skia/include/core/SkSurface.h"
12 #if !defined(OS_ANDROID)
14 namespace cc {
15 namespace {
17 SkXfermode::Mode const kBlendModes[] = {
18 SkXfermode::kSrcOver_Mode, SkXfermode::kScreen_Mode,
19 SkXfermode::kOverlay_Mode, SkXfermode::kDarken_Mode,
20 SkXfermode::kLighten_Mode, SkXfermode::kColorDodge_Mode,
21 SkXfermode::kColorBurn_Mode, SkXfermode::kHardLight_Mode,
22 SkXfermode::kSoftLight_Mode, SkXfermode::kDifference_Mode,
23 SkXfermode::kExclusion_Mode, SkXfermode::kMultiply_Mode,
24 SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode,
25 SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode};
27 SkColor kCSSTestColors[] = {
28 0xffff0000, // red
29 0xff00ff00, // lime
30 0xff0000ff, // blue
31 0xff00ffff, // aqua
32 0xffff00ff, // fuchsia
33 0xffffff00, // yellow
34 0xff008000, // green
35 0xff800000, // maroon
36 0xff000080, // navy
37 0xff800080, // purple
38 0xff808000, // olive
39 0xff008080, // teal
40 0xfffa8072, // salmon
41 0xffc0c0c0, // silver
42 0xff000000, // black
43 0xff808080, // gray
44 0x80000000, // black with transparency
45 0xffffffff, // white
46 0x80ffffff, // white with transparency
47 0x00000000 // transparent
50 const int kBlendModesCount = arraysize(kBlendModes);
51 const int kCSSTestColorsCount = arraysize(kCSSTestColors);
53 using RenderPassOptions = uint32;
54 const uint32 kUseMasks = 1 << 0;
55 const uint32 kUseAntialiasing = 1 << 1;
56 const uint32 kUseColorMatrix = 1 << 2;
57 const uint32 kForceShaders = 1 << 3;
59 class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest {
60 public:
61 LayerTreeHostBlendingPixelTest()
62 : force_antialiasing_(false), force_blending_with_shaders_(false) {
63 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
66 void InitializeSettings(LayerTreeSettings* settings) override {
67 settings->renderer_settings.force_antialiasing = force_antialiasing_;
68 settings->renderer_settings.force_blending_with_shaders =
69 force_blending_with_shaders_;
72 protected:
73 void RunBlendingWithRootPixelTestType(PixelResourceTestCase type) {
74 const int kLaneWidth = 2;
75 const int kLaneHeight = kLaneWidth;
76 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
77 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
78 InitializeFromTestCase(type);
80 scoped_refptr<SolidColorLayer> background =
81 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
83 // Orange child layers will blend with the green background
84 for (int i = 0; i < kBlendModesCount; ++i) {
85 gfx::Rect child_rect(
86 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
87 scoped_refptr<SolidColorLayer> green_lane =
88 CreateSolidColorLayer(child_rect, kCSSGreen);
89 background->AddChild(green_lane);
90 green_lane->SetBlendMode(kBlendModes[i]);
93 RunPixelResourceTest(
94 background,
95 base::FilePath(FILE_PATH_LITERAL("blending_with_root.png")));
98 void RunBlendingWithTransparentPixelTestType(PixelResourceTestCase type) {
99 const int kLaneWidth = 2;
100 const int kLaneHeight = 3 * kLaneWidth;
101 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
102 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
103 InitializeFromTestCase(type);
105 scoped_refptr<SolidColorLayer> root =
106 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSBrown);
108 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
109 gfx::Rect(0, kLaneWidth * 2, kRootWidth, kLaneWidth), kCSSOrange);
111 root->AddChild(background);
112 background->SetIsRootForIsolatedGroup(true);
114 // Orange child layers will blend with the green background
115 for (int i = 0; i < kBlendModesCount; ++i) {
116 gfx::Rect child_rect(
117 (i + 1) * kLaneWidth, -kLaneWidth, kLaneWidth, kLaneHeight);
118 scoped_refptr<SolidColorLayer> green_lane =
119 CreateSolidColorLayer(child_rect, kCSSGreen);
120 background->AddChild(green_lane);
121 green_lane->SetBlendMode(kBlendModes[i]);
124 RunPixelResourceTest(
125 root, base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
128 scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
129 // Draw the backdrop with horizontal lanes.
130 const int kLaneWidth = width;
131 const int kLaneHeight = height / kCSSTestColorsCount;
132 skia::RefPtr<SkSurface> backing_store =
133 skia::AdoptRef(SkSurface::NewRasterN32Premul(width, height));
134 SkCanvas* canvas = backing_store->getCanvas();
135 canvas->clear(SK_ColorTRANSPARENT);
136 for (int i = 0; i < kCSSTestColorsCount; ++i) {
137 SkPaint paint;
138 paint.setColor(kCSSTestColors[i]);
139 canvas->drawRect(
140 SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
142 scoped_refptr<PictureImageLayer> layer =
143 PictureImageLayer::Create(layer_settings());
144 layer->SetIsDrawable(true);
145 layer->SetBounds(gfx::Size(width, height));
146 skia::RefPtr<const SkImage> image =
147 skia::AdoptRef(backing_store->newImageSnapshot());
148 layer->SetImage(image.Pass());
149 return layer;
152 void SetupMaskLayer(scoped_refptr<Layer> layer) {
153 const int kMaskOffset = 2;
154 gfx::Size bounds = layer->bounds();
155 scoped_refptr<PictureImageLayer> mask =
156 PictureImageLayer::Create(layer_settings());
157 mask->SetIsDrawable(true);
158 mask->SetIsMask(true);
159 mask->SetBounds(bounds);
161 skia::RefPtr<SkSurface> surface = skia::AdoptRef(
162 SkSurface::NewRasterN32Premul(bounds.width(), bounds.height()));
163 SkCanvas* canvas = surface->getCanvas();
164 SkPaint paint;
165 paint.setColor(SK_ColorWHITE);
166 canvas->clear(SK_ColorTRANSPARENT);
167 canvas->drawRect(SkRect::MakeXYWH(kMaskOffset, kMaskOffset,
168 bounds.width() - kMaskOffset * 2,
169 bounds.height() - kMaskOffset * 2),
170 paint);
171 skia::RefPtr<const SkImage> image =
172 skia::AdoptRef(surface->newImageSnapshot());
173 mask->SetImage(image.Pass());
174 layer->SetMaskLayer(mask.get());
177 void SetupColorMatrix(scoped_refptr<Layer> layer) {
178 FilterOperations filter_operations;
179 filter_operations.Append(FilterOperation::CreateSepiaFilter(.001f));
180 layer->SetFilters(filter_operations);
183 void CreateBlendingColorLayers(int lane_width,
184 int lane_height,
185 scoped_refptr<Layer> background,
186 RenderPassOptions flags) {
187 const int kLanesCount = kBlendModesCount + 4;
188 const SkColor kMiscOpaqueColor = 0xffc86464;
189 const SkColor kMiscTransparentColor = 0x80c86464;
190 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
191 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
192 // add vertical lanes with each of the blend modes
193 for (int i = 0; i < kLanesCount; ++i) {
194 gfx::Rect child_rect(i * lane_width, 0, lane_width, lane_height);
195 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
196 float opacity = 1.f;
197 SkColor color = kMiscOpaqueColor;
199 if (i < kBlendModesCount) {
200 blend_mode = kBlendModes[i];
201 } else if (i == kBlendModesCount) {
202 blend_mode = kCoeffBlendMode;
203 opacity = 0.5f;
204 } else if (i == kBlendModesCount + 1) {
205 blend_mode = kCoeffBlendMode;
206 color = kMiscTransparentColor;
207 } else if (i == kBlendModesCount + 2) {
208 blend_mode = kShaderBlendMode;
209 opacity = 0.5f;
210 } else if (i == kBlendModesCount + 3) {
211 blend_mode = kShaderBlendMode;
212 color = kMiscTransparentColor;
215 scoped_refptr<SolidColorLayer> lane =
216 CreateSolidColorLayer(child_rect, color);
217 lane->SetBlendMode(blend_mode);
218 lane->SetOpacity(opacity);
219 lane->SetForceRenderSurface(true);
220 if (flags & kUseMasks)
221 SetupMaskLayer(lane);
222 if (flags & kUseColorMatrix) {
223 SetupColorMatrix(lane);
225 background->AddChild(lane);
229 void RunBlendingWithRenderPass(PixelResourceTestCase type,
230 const base::FilePath::CharType* expected_path,
231 RenderPassOptions flags) {
232 const int kLaneWidth = 8;
233 const int kLaneHeight = kLaneWidth * kCSSTestColorsCount;
234 const int kRootSize = kLaneHeight;
235 InitializeFromTestCase(type);
237 scoped_refptr<SolidColorLayer> root =
238 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
239 scoped_refptr<Layer> background =
240 CreateColorfulBackdropLayer(kRootSize, kRootSize);
242 background->SetIsRootForIsolatedGroup(true);
243 root->AddChild(background);
245 CreateBlendingColorLayers(kLaneWidth, kLaneHeight, background.get(), flags);
247 this->force_antialiasing_ = (flags & kUseAntialiasing);
248 this->force_blending_with_shaders_ = (flags & kForceShaders);
250 if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
251 // Anti aliasing causes differences up to 8 pixels at the edges.
252 int large_error_allowed = 8;
253 // Blending results might differ with one pixel.
254 int small_error_allowed = 1;
255 // Most of the errors are one pixel errors.
256 float percentage_pixels_small_error = 13.1f;
257 // Because of anti-aliasing, around 10% of pixels (at the edges) have
258 // bigger errors (from small_error_allowed + 1 to large_error_allowed).
259 float percentage_pixels_error = 22.5f;
260 // The average error is still close to 1.
261 float average_error_allowed_in_bad_pixels = 1.4f;
263 pixel_comparator_.reset(
264 new FuzzyPixelComparator(false, // discard_alpha
265 percentage_pixels_error,
266 percentage_pixels_small_error,
267 average_error_allowed_in_bad_pixels,
268 large_error_allowed,
269 small_error_allowed));
272 RunPixelResourceTest(root, base::FilePath(expected_path));
275 bool force_antialiasing_;
276 bool force_blending_with_shaders_;
279 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
280 RunBlendingWithRootPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
283 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
284 RunBlendingWithRootPixelTestType(SOFTWARE);
287 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
288 const int kLaneWidth = 2;
289 const int kLaneHeight = kLaneWidth;
290 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
291 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
292 InitializeFromTestCase(GL_ASYNC_UPLOAD_2D_DRAW);
294 scoped_refptr<SolidColorLayer> background =
295 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
297 // Orange child layers have a background filter set and they will blend with
298 // the green background
299 for (int i = 0; i < kBlendModesCount; ++i) {
300 gfx::Rect child_rect(
301 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
302 scoped_refptr<SolidColorLayer> green_lane =
303 CreateSolidColorLayer(child_rect, kCSSGreen);
304 background->AddChild(green_lane);
306 FilterOperations filters;
307 filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
308 green_lane->SetBackgroundFilters(filters);
309 green_lane->SetBlendMode(kBlendModes[i]);
312 RunPixelResourceTest(
313 background, base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
316 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
317 RunBlendingWithTransparentPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
320 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
321 RunBlendingWithTransparentPixelTestType(SOFTWARE);
324 // Tests for render passes
325 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
326 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
327 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
330 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
331 RunBlendingWithRenderPass(SOFTWARE,
332 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
335 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
336 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
337 FILE_PATH_LITERAL("blending_render_pass.png"),
338 kUseAntialiasing);
341 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
342 RunBlendingWithRenderPass(SOFTWARE,
343 FILE_PATH_LITERAL("blending_render_pass.png"),
344 kUseAntialiasing);
347 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
348 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
349 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
350 kUseMasks);
353 TEST_F(LayerTreeHostBlendingPixelTest,
354 BlendingWithRenderPassWithMask_Software) {
355 RunBlendingWithRenderPass(
356 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass_mask.png"), kUseMasks);
359 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
360 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
361 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
362 kUseMasks | kUseAntialiasing);
365 TEST_F(LayerTreeHostBlendingPixelTest,
366 BlendingWithRenderPassWithMaskAA_Software) {
367 RunBlendingWithRenderPass(SOFTWARE,
368 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
369 kUseMasks | kUseAntialiasing);
372 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
373 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
374 FILE_PATH_LITERAL("blending_render_pass.png"),
375 kUseColorMatrix);
378 TEST_F(LayerTreeHostBlendingPixelTest,
379 BlendingWithRenderPassColorMatrix_Software) {
380 RunBlendingWithRenderPass(
381 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), kUseColorMatrix);
384 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
385 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
386 FILE_PATH_LITERAL("blending_render_pass.png"),
387 kUseAntialiasing | kUseColorMatrix);
390 TEST_F(LayerTreeHostBlendingPixelTest,
391 BlendingWithRenderPassColorMatrixAA_Software) {
392 RunBlendingWithRenderPass(SOFTWARE,
393 FILE_PATH_LITERAL("blending_render_pass.png"),
394 kUseAntialiasing | kUseColorMatrix);
397 TEST_F(LayerTreeHostBlendingPixelTest,
398 BlendingWithRenderPassWithMaskColorMatrix_GL) {
399 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
400 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
401 kUseMasks | kUseColorMatrix);
404 TEST_F(LayerTreeHostBlendingPixelTest,
405 BlendingWithRenderPassWithMaskColorMatrix_Software) {
406 RunBlendingWithRenderPass(SOFTWARE,
407 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
408 kUseMasks | kUseColorMatrix);
411 TEST_F(LayerTreeHostBlendingPixelTest,
412 BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
413 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
414 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
415 kUseMasks | kUseAntialiasing | kUseColorMatrix);
418 TEST_F(LayerTreeHostBlendingPixelTest,
419 BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
420 RunBlendingWithRenderPass(SOFTWARE,
421 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
422 kUseMasks | kUseAntialiasing | kUseColorMatrix);
425 // Tests for render passes forcing shaders for all the blend modes.
426 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
427 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
428 FILE_PATH_LITERAL("blending_render_pass.png"),
429 kForceShaders);
432 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
433 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
434 FILE_PATH_LITERAL("blending_render_pass.png"),
435 kUseAntialiasing | kForceShaders);
438 TEST_F(LayerTreeHostBlendingPixelTest,
439 BlendingWithRenderPassShadersWithMask_GL) {
440 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
441 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
442 kUseMasks | kForceShaders);
445 TEST_F(LayerTreeHostBlendingPixelTest,
446 BlendingWithRenderPassShadersWithMask_GL_TextureRect) {
447 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
448 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
449 kUseMasks | kForceShaders);
452 TEST_F(LayerTreeHostBlendingPixelTest,
453 BlendingWithRenderPassShadersWithMaskAA_GL) {
454 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
455 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
456 kUseMasks | kUseAntialiasing | kForceShaders);
459 TEST_F(LayerTreeHostBlendingPixelTest,
460 BlendingWithRenderPassShadersWithMaskAA_GL_TextureRect) {
461 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
462 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
463 kUseMasks | kUseAntialiasing | kForceShaders);
466 TEST_F(LayerTreeHostBlendingPixelTest,
467 BlendingWithRenderPassShadersColorMatrix_GL) {
468 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
469 FILE_PATH_LITERAL("blending_render_pass.png"),
470 kUseColorMatrix | kForceShaders);
473 TEST_F(LayerTreeHostBlendingPixelTest,
474 BlendingWithRenderPassShadersColorMatrixAA_GL) {
475 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
476 FILE_PATH_LITERAL("blending_render_pass.png"),
477 kUseAntialiasing | kUseColorMatrix | kForceShaders);
480 TEST_F(LayerTreeHostBlendingPixelTest,
481 BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
482 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
483 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
484 kUseMasks | kUseColorMatrix | kForceShaders);
487 TEST_F(LayerTreeHostBlendingPixelTest,
488 BlendingWithRenderPassShadersWithMaskColorMatrix_GL_TextureRect) {
489 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
490 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
491 kUseMasks | kUseColorMatrix | kForceShaders);
494 TEST_F(LayerTreeHostBlendingPixelTest,
495 BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
496 RunBlendingWithRenderPass(
497 GL_ASYNC_UPLOAD_2D_DRAW,
498 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
499 kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
502 } // namespace
503 } // namespace cc
505 #endif // OS_ANDROID