Add Apps.AppListSearchQueryLength UMA histogram.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_blending.cc
blobb31d3e8539525ccb1203ffb7377b28aac8e3c33f
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 = PictureImageLayer::Create();
141 layer->SetIsDrawable(true);
142 layer->SetBounds(gfx::Size(width, height));
143 layer->SetBitmap(backing_store);
144 return layer;
147 void SetupMaskLayer(scoped_refptr<Layer> layer) {
148 const int kMaskOffset = 2;
149 gfx::Size bounds = layer->bounds();
150 scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
151 mask->SetIsDrawable(true);
152 mask->SetIsMask(true);
153 mask->SetBounds(bounds);
155 SkBitmap bitmap;
156 bitmap.allocN32Pixels(bounds.width(), bounds.height());
157 SkCanvas canvas(bitmap);
158 SkPaint paint;
159 paint.setColor(SK_ColorWHITE);
160 canvas.clear(SK_ColorTRANSPARENT);
161 canvas.drawRect(SkRect::MakeXYWH(kMaskOffset,
162 kMaskOffset,
163 bounds.width() - kMaskOffset * 2,
164 bounds.height() - kMaskOffset * 2),
165 paint);
166 mask->SetBitmap(bitmap);
167 layer->SetMaskLayer(mask.get());
170 void SetupColorMatrix(scoped_refptr<Layer> layer) {
171 FilterOperations filter_operations;
172 filter_operations.Append(FilterOperation::CreateSepiaFilter(.001f));
173 layer->SetFilters(filter_operations);
176 void CreateBlendingColorLayers(int lane_width,
177 int lane_height,
178 scoped_refptr<Layer> background,
179 RenderPassOptions flags) {
180 const int kLanesCount = kBlendModesCount + 4;
181 const SkColor kMiscOpaqueColor = 0xffc86464;
182 const SkColor kMiscTransparentColor = 0x80c86464;
183 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
184 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
185 // add vertical lanes with each of the blend modes
186 for (int i = 0; i < kLanesCount; ++i) {
187 gfx::Rect child_rect(i * lane_width, 0, lane_width, lane_height);
188 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
189 float opacity = 1.f;
190 SkColor color = kMiscOpaqueColor;
192 if (i < kBlendModesCount) {
193 blend_mode = kBlendModes[i];
194 } else if (i == kBlendModesCount) {
195 blend_mode = kCoeffBlendMode;
196 opacity = 0.5f;
197 } else if (i == kBlendModesCount + 1) {
198 blend_mode = kCoeffBlendMode;
199 color = kMiscTransparentColor;
200 } else if (i == kBlendModesCount + 2) {
201 blend_mode = kShaderBlendMode;
202 opacity = 0.5f;
203 } else if (i == kBlendModesCount + 3) {
204 blend_mode = kShaderBlendMode;
205 color = kMiscTransparentColor;
208 scoped_refptr<SolidColorLayer> lane =
209 CreateSolidColorLayer(child_rect, color);
210 lane->SetBlendMode(blend_mode);
211 lane->SetOpacity(opacity);
212 lane->SetForceRenderSurface(true);
213 if (flags & kUseMasks)
214 SetupMaskLayer(lane);
215 if (flags & kUseColorMatrix) {
216 SetupColorMatrix(lane);
218 background->AddChild(lane);
222 void RunBlendingWithRenderPass(PixelResourceTestCase type,
223 const base::FilePath::CharType* expected_path,
224 RenderPassOptions flags) {
225 const int kLaneWidth = 8;
226 const int kLaneHeight = kLaneWidth * kCSSTestColorsCount;
227 const int kRootSize = kLaneHeight;
228 InitializeFromTestCase(type);
230 scoped_refptr<SolidColorLayer> root =
231 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
232 scoped_refptr<Layer> background =
233 CreateColorfulBackdropLayer(kRootSize, kRootSize);
235 background->SetIsRootForIsolatedGroup(true);
236 root->AddChild(background);
238 CreateBlendingColorLayers(kLaneWidth, kLaneHeight, background.get(), flags);
240 this->force_antialiasing_ = (flags & kUseAntialiasing);
241 this->force_blending_with_shaders_ = (flags & kForceShaders);
243 if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
244 // Anti aliasing causes differences up to 8 pixels at the edges.
245 int large_error_allowed = 8;
246 // Blending results might differ with one pixel.
247 int small_error_allowed = 1;
248 // Most of the errors are one pixel errors.
249 float percentage_pixels_small_error = 13.1f;
250 // Because of anti-aliasing, around 10% of pixels (at the edges) have
251 // bigger errors (from small_error_allowed + 1 to large_error_allowed).
252 float percentage_pixels_error = 22.5f;
253 // The average error is still close to 1.
254 float average_error_allowed_in_bad_pixels = 1.4f;
256 pixel_comparator_.reset(
257 new FuzzyPixelComparator(false, // discard_alpha
258 percentage_pixels_error,
259 percentage_pixels_small_error,
260 average_error_allowed_in_bad_pixels,
261 large_error_allowed,
262 small_error_allowed));
265 RunPixelResourceTest(root, base::FilePath(expected_path));
268 bool force_antialiasing_;
269 bool force_blending_with_shaders_;
272 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
273 RunBlendingWithRootPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
276 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
277 RunBlendingWithRootPixelTestType(SOFTWARE);
280 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
281 const int kLaneWidth = 2;
282 const int kLaneHeight = kLaneWidth;
283 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
284 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
285 InitializeFromTestCase(GL_ASYNC_UPLOAD_2D_DRAW);
287 scoped_refptr<SolidColorLayer> background =
288 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
290 // Orange child layers have a background filter set and they will blend with
291 // the green background
292 for (int i = 0; i < kBlendModesCount; ++i) {
293 gfx::Rect child_rect(
294 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
295 scoped_refptr<SolidColorLayer> green_lane =
296 CreateSolidColorLayer(child_rect, kCSSGreen);
297 background->AddChild(green_lane);
299 FilterOperations filters;
300 filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
301 green_lane->SetBackgroundFilters(filters);
302 green_lane->SetBlendMode(kBlendModes[i]);
305 RunPixelResourceTest(
306 background, base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
309 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
310 RunBlendingWithTransparentPixelTestType(GL_ASYNC_UPLOAD_2D_DRAW);
313 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
314 RunBlendingWithTransparentPixelTestType(SOFTWARE);
317 // Tests for render passes
318 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
319 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
320 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
323 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
324 RunBlendingWithRenderPass(SOFTWARE,
325 FILE_PATH_LITERAL("blending_render_pass.png"), 0);
328 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
329 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
330 FILE_PATH_LITERAL("blending_render_pass.png"),
331 kUseAntialiasing);
334 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
335 RunBlendingWithRenderPass(SOFTWARE,
336 FILE_PATH_LITERAL("blending_render_pass.png"),
337 kUseAntialiasing);
340 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
341 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
342 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
343 kUseMasks);
346 TEST_F(LayerTreeHostBlendingPixelTest,
347 BlendingWithRenderPassWithMask_Software) {
348 RunBlendingWithRenderPass(
349 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass_mask.png"), kUseMasks);
352 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
353 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
354 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
355 kUseMasks | kUseAntialiasing);
358 TEST_F(LayerTreeHostBlendingPixelTest,
359 BlendingWithRenderPassWithMaskAA_Software) {
360 RunBlendingWithRenderPass(SOFTWARE,
361 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
362 kUseMasks | kUseAntialiasing);
365 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
366 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
367 FILE_PATH_LITERAL("blending_render_pass.png"),
368 kUseColorMatrix);
371 TEST_F(LayerTreeHostBlendingPixelTest,
372 BlendingWithRenderPassColorMatrix_Software) {
373 RunBlendingWithRenderPass(
374 SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), kUseColorMatrix);
377 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
378 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
379 FILE_PATH_LITERAL("blending_render_pass.png"),
380 kUseAntialiasing | kUseColorMatrix);
383 TEST_F(LayerTreeHostBlendingPixelTest,
384 BlendingWithRenderPassColorMatrixAA_Software) {
385 RunBlendingWithRenderPass(SOFTWARE,
386 FILE_PATH_LITERAL("blending_render_pass.png"),
387 kUseAntialiasing | kUseColorMatrix);
390 TEST_F(LayerTreeHostBlendingPixelTest,
391 BlendingWithRenderPassWithMaskColorMatrix_GL) {
392 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
393 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
394 kUseMasks | kUseColorMatrix);
397 TEST_F(LayerTreeHostBlendingPixelTest,
398 BlendingWithRenderPassWithMaskColorMatrix_Software) {
399 RunBlendingWithRenderPass(SOFTWARE,
400 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
401 kUseMasks | kUseColorMatrix);
404 TEST_F(LayerTreeHostBlendingPixelTest,
405 BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
406 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
407 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
408 kUseMasks | kUseAntialiasing | kUseColorMatrix);
411 TEST_F(LayerTreeHostBlendingPixelTest,
412 BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
413 RunBlendingWithRenderPass(SOFTWARE,
414 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
415 kUseMasks | kUseAntialiasing | kUseColorMatrix);
418 // Tests for render passes forcing shaders for all the blend modes.
419 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
420 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
421 FILE_PATH_LITERAL("blending_render_pass.png"),
422 kForceShaders);
425 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
426 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
427 FILE_PATH_LITERAL("blending_render_pass.png"),
428 kUseAntialiasing | kForceShaders);
431 TEST_F(LayerTreeHostBlendingPixelTest,
432 BlendingWithRenderPassShadersWithMask_GL) {
433 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
434 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
435 kUseMasks | kForceShaders);
438 TEST_F(LayerTreeHostBlendingPixelTest,
439 BlendingWithRenderPassShadersWithMask_GL_TextureRect) {
440 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
441 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
442 kUseMasks | kForceShaders);
445 TEST_F(LayerTreeHostBlendingPixelTest,
446 BlendingWithRenderPassShadersWithMaskAA_GL) {
447 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
448 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
449 kUseMasks | kUseAntialiasing | kForceShaders);
452 TEST_F(LayerTreeHostBlendingPixelTest,
453 BlendingWithRenderPassShadersWithMaskAA_GL_TextureRect) {
454 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
455 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
456 kUseMasks | kUseAntialiasing | kForceShaders);
459 TEST_F(LayerTreeHostBlendingPixelTest,
460 BlendingWithRenderPassShadersColorMatrix_GL) {
461 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
462 FILE_PATH_LITERAL("blending_render_pass.png"),
463 kUseColorMatrix | kForceShaders);
466 TEST_F(LayerTreeHostBlendingPixelTest,
467 BlendingWithRenderPassShadersColorMatrixAA_GL) {
468 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
469 FILE_PATH_LITERAL("blending_render_pass.png"),
470 kUseAntialiasing | kUseColorMatrix | kForceShaders);
473 TEST_F(LayerTreeHostBlendingPixelTest,
474 BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
475 RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
476 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
477 kUseMasks | kUseColorMatrix | kForceShaders);
480 TEST_F(LayerTreeHostBlendingPixelTest,
481 BlendingWithRenderPassShadersWithMaskColorMatrix_GL_TextureRect) {
482 RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
483 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
484 kUseMasks | kUseColorMatrix | kForceShaders);
487 TEST_F(LayerTreeHostBlendingPixelTest,
488 BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
489 RunBlendingWithRenderPass(
490 GL_ASYNC_UPLOAD_2D_DRAW,
491 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
492 kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
495 } // namespace
496 } // namespace cc
498 #endif // OS_ANDROID