Simplify web_view.js
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_blending.cc
blob7a9ef2123836ed8549689b9025dbb432a4c8a95c
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/image_layer.h"
6 #include "cc/layers/solid_color_layer.h"
7 #include "cc/test/layer_tree_pixel_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;
56 class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
57 public:
58 LayerTreeHostBlendingPixelTest() {
59 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
62 virtual void InitializeSettings(LayerTreeSettings* settings) override {
63 settings->force_antialiasing = force_antialiasing_;
66 protected:
67 void RunBlendingWithRootPixelTestType(PixelTestType type) {
68 const int kLaneWidth = 15;
69 const int kLaneHeight = kBlendModesCount * kLaneWidth;
70 const int kRootSize = (kBlendModesCount + 2) * kLaneWidth;
72 scoped_refptr<SolidColorLayer> background =
73 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), kCSSOrange);
75 // Orange child layers will blend with the green background
76 for (int i = 0; i < kBlendModesCount; ++i) {
77 gfx::Rect child_rect(
78 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
79 scoped_refptr<SolidColorLayer> green_lane =
80 CreateSolidColorLayer(child_rect, kCSSGreen);
81 background->AddChild(green_lane);
82 green_lane->SetBlendMode(kBlendModes[i]);
85 RunPixelTest(type,
86 background,
87 base::FilePath(FILE_PATH_LITERAL("blending_with_root.png")));
90 void RunBlendingWithTransparentPixelTestType(PixelTestType type) {
91 const int kLaneWidth = 15;
92 const int kLaneHeight = kBlendModesCount * kLaneWidth;
93 const int kRootSize = (kBlendModesCount + 2) * kLaneWidth;
95 scoped_refptr<SolidColorLayer> root =
96 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), kCSSBrown);
98 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
99 gfx::Rect(0, kLaneWidth * 2, kRootSize, kLaneWidth), kCSSOrange);
101 root->AddChild(background);
102 background->SetIsRootForIsolatedGroup(true);
104 // Orange child layers will blend with the green background
105 for (int i = 0; i < kBlendModesCount; ++i) {
106 gfx::Rect child_rect(
107 (i + 1) * kLaneWidth, -kLaneWidth, kLaneWidth, kLaneHeight);
108 scoped_refptr<SolidColorLayer> green_lane =
109 CreateSolidColorLayer(child_rect, kCSSGreen);
110 background->AddChild(green_lane);
111 green_lane->SetBlendMode(kBlendModes[i]);
114 RunPixelTest(type,
115 root,
116 base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
119 scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
120 // Draw the backdrop with horizontal lanes.
121 const int kLaneWidth = width;
122 const int kLaneHeight = height / kCSSTestColorsCount;
123 SkBitmap backing_store;
124 backing_store.allocN32Pixels(width, height);
125 SkCanvas canvas(backing_store);
126 canvas.clear(SK_ColorTRANSPARENT);
127 for (int i = 0; i < kCSSTestColorsCount; ++i) {
128 SkPaint paint;
129 paint.setColor(kCSSTestColors[i]);
130 canvas.drawRect(
131 SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
133 scoped_refptr<ImageLayer> layer = ImageLayer::Create();
134 layer->SetIsDrawable(true);
135 layer->SetBounds(gfx::Size(width, height));
136 layer->SetBitmap(backing_store);
137 return layer;
140 void SetupMaskLayer(scoped_refptr<Layer> layer) {
141 const int kMaskOffset = 5;
142 gfx::Size bounds = layer->bounds();
143 scoped_refptr<ImageLayer> mask = ImageLayer::Create();
144 mask->SetIsDrawable(true);
145 mask->SetIsMask(true);
146 mask->SetBounds(bounds);
148 SkBitmap bitmap;
149 bitmap.allocN32Pixels(bounds.width(), bounds.height());
150 SkCanvas canvas(bitmap);
151 SkPaint paint;
152 paint.setColor(SK_ColorWHITE);
153 canvas.clear(SK_ColorTRANSPARENT);
154 canvas.drawRect(SkRect::MakeXYWH(kMaskOffset,
155 kMaskOffset,
156 bounds.width() - kMaskOffset * 2,
157 bounds.height() - kMaskOffset * 2),
158 paint);
159 mask->SetBitmap(bitmap);
160 layer->SetMaskLayer(mask.get());
163 void SetupColorMatrix(scoped_refptr<Layer> layer) {
164 FilterOperations filter_operations;
165 filter_operations.Append(FilterOperation::CreateSepiaFilter(1.f));
166 layer->SetFilters(filter_operations);
169 void CreateBlendingColorLayers(int width,
170 int height,
171 scoped_refptr<Layer> background,
172 RenderPassOptions flags) {
173 const int kLanesCount = kBlendModesCount + 4;
174 int lane_width = width / kLanesCount;
175 const SkColor kMiscOpaqueColor = 0xffc86464;
176 const SkColor kMiscTransparentColor = 0x80c86464;
177 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
178 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
179 // add vertical lanes with each of the blend modes
180 for (int i = 0; i < kLanesCount; ++i) {
181 gfx::Rect child_rect(i * lane_width, 0, lane_width, height);
182 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
183 float opacity = 1.f;
184 SkColor color = kMiscOpaqueColor;
186 if (i < kBlendModesCount) {
187 blend_mode = kBlendModes[i];
188 } else if (i == kBlendModesCount) {
189 blend_mode = kCoeffBlendMode;
190 opacity = 0.5f;
191 } else if (i == kBlendModesCount + 1) {
192 blend_mode = kCoeffBlendMode;
193 color = kMiscTransparentColor;
194 } else if (i == kBlendModesCount + 2) {
195 blend_mode = kShaderBlendMode;
196 opacity = 0.5f;
197 } else if (i == kBlendModesCount + 3) {
198 blend_mode = kShaderBlendMode;
199 color = kMiscTransparentColor;
202 scoped_refptr<SolidColorLayer> lane =
203 CreateSolidColorLayer(child_rect, color);
204 lane->SetBlendMode(blend_mode);
205 lane->SetOpacity(opacity);
206 lane->SetForceRenderSurface(true);
207 if (flags & kUseMasks)
208 SetupMaskLayer(lane);
209 if (flags & kUseColorMatrix) {
210 SetupColorMatrix(lane);
212 background->AddChild(lane);
216 void RunBlendingWithRenderPass(PixelTestType type,
217 const base::FilePath::CharType* expected_path,
218 RenderPassOptions flags) {
219 const int kRootSize = 400;
221 scoped_refptr<SolidColorLayer> root =
222 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
223 scoped_refptr<Layer> background =
224 CreateColorfulBackdropLayer(kRootSize, kRootSize);
226 background->SetIsRootForIsolatedGroup(true);
227 root->AddChild(background);
229 CreateBlendingColorLayers(kRootSize, kRootSize, background.get(), flags);
231 this->impl_side_painting_ = false;
232 this->force_antialiasing_ = (flags & kUseAntialiasing);
234 if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
235 // Anti aliasing causes differences up to 7 pixels at the edges.
236 // Several pixels have 9 units difference on the alpha channel.
237 int large_error_allowed = (flags & kUseMasks) ? 7 : 9;
238 // Blending results might differ with one pixel.
239 int small_error_allowed = 1;
240 // Most of the errors are one pixel errors.
241 float percentage_pixels_small_error = (flags & kUseMasks) ? 7.7f : 12.1f;
242 // Because of anti-aliasing, around 3% of pixels (at the edges) have
243 // bigger errors (from small_error_allowed + 1 to large_error_allowed).
244 float percentage_pixels_error = (flags & kUseMasks) ? 12.4f : 15.f;
245 // The average error is still close to 1.
246 float average_error_allowed_in_bad_pixels =
247 (flags & kUseMasks) ? 1.3f : 1.f;
249 // The sepia filter generates more small errors, but the number of large
250 // errors remains around 3%.
251 if (flags & kUseColorMatrix) {
252 percentage_pixels_small_error = (flags & kUseMasks) ? 14.0f : 26.f;
253 percentage_pixels_error = (flags & kUseMasks) ? 18.5f : 29.f;
254 average_error_allowed_in_bad_pixels = (flags & kUseMasks) ? 0.9f : 0.7f;
257 pixel_comparator_.reset(
258 new FuzzyPixelComparator(false, // discard_alpha
259 percentage_pixels_error,
260 percentage_pixels_small_error,
261 average_error_allowed_in_bad_pixels,
262 large_error_allowed,
263 small_error_allowed));
264 } else if ((flags & kUseColorMatrix) && (type == PIXEL_TEST_GL)) {
265 float percentage_pixels_error = 100.f;
266 float percentage_pixels_small_error = 0.f;
267 float average_error_allowed_in_bad_pixels = 1.f;
268 int large_error_allowed = 2;
269 int small_error_allowed = 0;
270 pixel_comparator_.reset(
271 new FuzzyPixelComparator(false, // discard_alpha
272 percentage_pixels_error,
273 percentage_pixels_small_error,
274 average_error_allowed_in_bad_pixels,
275 large_error_allowed,
276 small_error_allowed));
279 RunPixelTest(type, root, base::FilePath(expected_path));
282 bool force_antialiasing_ = false;
285 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
286 RunBlendingWithRootPixelTestType(PIXEL_TEST_GL);
289 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
290 RunBlendingWithRootPixelTestType(PIXEL_TEST_SOFTWARE);
293 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
294 const int kLaneWidth = 15;
295 const int kLaneHeight = kBlendModesCount * kLaneWidth;
296 const int kRootSize = (kBlendModesCount + 2) * kLaneWidth;
298 scoped_refptr<SolidColorLayer> background =
299 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), kCSSOrange);
301 // Orange child layers have a background filter set and they will blend with
302 // the green background
303 for (int i = 0; i < kBlendModesCount; ++i) {
304 gfx::Rect child_rect(
305 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
306 scoped_refptr<SolidColorLayer> green_lane =
307 CreateSolidColorLayer(child_rect, kCSSGreen);
308 background->AddChild(green_lane);
310 FilterOperations filters;
311 filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
312 green_lane->SetBackgroundFilters(filters);
313 green_lane->SetBlendMode(kBlendModes[i]);
316 RunPixelTest(PIXEL_TEST_GL,
317 background,
318 base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
321 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
322 RunBlendingWithTransparentPixelTestType(PIXEL_TEST_GL);
325 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
326 RunBlendingWithTransparentPixelTestType(PIXEL_TEST_SOFTWARE);
329 // Tests for render passes
330 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
331 RunBlendingWithRenderPass(
332 PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
335 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
336 RunBlendingWithRenderPass(
337 PIXEL_TEST_SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
340 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
341 RunBlendingWithRenderPass(PIXEL_TEST_GL,
342 FILE_PATH_LITERAL("blending_render_pass.png"),
343 kUseAntialiasing);
346 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
347 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
348 FILE_PATH_LITERAL("blending_render_pass.png"),
349 kUseAntialiasing);
352 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
353 RunBlendingWithRenderPass(PIXEL_TEST_GL,
354 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
355 kUseMasks);
358 TEST_F(LayerTreeHostBlendingPixelTest,
359 BlendingWithRenderPassWithMask_Software) {
360 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
361 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
362 kUseMasks);
365 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
366 RunBlendingWithRenderPass(PIXEL_TEST_GL,
367 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
368 kUseMasks | kUseAntialiasing);
371 TEST_F(LayerTreeHostBlendingPixelTest,
372 BlendingWithRenderPassWithMaskAA_Software) {
373 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
374 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
375 kUseMasks | kUseAntialiasing);
378 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
379 RunBlendingWithRenderPass(PIXEL_TEST_GL,
380 FILE_PATH_LITERAL("blending_render_pass_cm.png"),
381 kUseColorMatrix);
384 TEST_F(LayerTreeHostBlendingPixelTest,
385 BlendingWithRenderPassColorMatrix_Software) {
386 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
387 FILE_PATH_LITERAL("blending_render_pass_cm.png"),
388 kUseColorMatrix);
391 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
392 RunBlendingWithRenderPass(PIXEL_TEST_GL,
393 FILE_PATH_LITERAL("blending_render_pass_cm.png"),
394 kUseAntialiasing | kUseColorMatrix);
397 TEST_F(LayerTreeHostBlendingPixelTest,
398 BlendingWithRenderPassColorMatrixAA_Software) {
399 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
400 FILE_PATH_LITERAL("blending_render_pass_cm.png"),
401 kUseAntialiasing | kUseColorMatrix);
404 TEST_F(LayerTreeHostBlendingPixelTest,
405 BlendingWithRenderPassWithMaskColorMatrix_GL) {
406 RunBlendingWithRenderPass(
407 PIXEL_TEST_GL,
408 FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
409 kUseMasks | kUseColorMatrix);
412 TEST_F(LayerTreeHostBlendingPixelTest,
413 BlendingWithRenderPassWithMaskColorMatrix_Software) {
414 RunBlendingWithRenderPass(
415 PIXEL_TEST_SOFTWARE,
416 FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
417 kUseMasks | kUseColorMatrix);
420 TEST_F(LayerTreeHostBlendingPixelTest,
421 BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
422 RunBlendingWithRenderPass(
423 PIXEL_TEST_GL,
424 FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
425 kUseMasks | kUseAntialiasing | kUseColorMatrix);
428 TEST_F(LayerTreeHostBlendingPixelTest,
429 BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
430 RunBlendingWithRenderPass(
431 PIXEL_TEST_SOFTWARE,
432 FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
433 kUseMasks | kUseAntialiasing | kUseColorMatrix);
436 } // namespace
437 } // namespace cc
439 #endif // OS_ANDROID