Support HTTP/2 drafts 14 and 15 simultaneously.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_blending.cc
blob148769e56f8caaa0495383870d0d743b07361230
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;
55 const uint32 kForceShaders = 1 << 3;
57 class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
58 public:
59 LayerTreeHostBlendingPixelTest()
60 : force_antialiasing_(false), force_blending_with_shaders_(false) {
61 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
64 virtual void InitializeSettings(LayerTreeSettings* settings) override {
65 settings->force_antialiasing = force_antialiasing_;
66 settings->force_blending_with_shaders = force_blending_with_shaders_;
69 protected:
70 void RunBlendingWithRootPixelTestType(PixelTestType type) {
71 const int kLaneWidth = 2;
72 const int kLaneHeight = kLaneWidth;
73 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
74 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
76 scoped_refptr<SolidColorLayer> background =
77 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
79 // Orange child layers will blend with the green background
80 for (int i = 0; i < kBlendModesCount; ++i) {
81 gfx::Rect child_rect(
82 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
83 scoped_refptr<SolidColorLayer> green_lane =
84 CreateSolidColorLayer(child_rect, kCSSGreen);
85 background->AddChild(green_lane);
86 green_lane->SetBlendMode(kBlendModes[i]);
89 RunPixelTest(type,
90 background,
91 base::FilePath(FILE_PATH_LITERAL("blending_with_root.png")));
94 void RunBlendingWithTransparentPixelTestType(PixelTestType type) {
95 const int kLaneWidth = 2;
96 const int kLaneHeight = 3 * kLaneWidth;
97 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
98 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
100 scoped_refptr<SolidColorLayer> root =
101 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSBrown);
103 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
104 gfx::Rect(0, kLaneWidth * 2, kRootWidth, kLaneWidth), kCSSOrange);
106 root->AddChild(background);
107 background->SetIsRootForIsolatedGroup(true);
109 // Orange child layers will blend with the green background
110 for (int i = 0; i < kBlendModesCount; ++i) {
111 gfx::Rect child_rect(
112 (i + 1) * kLaneWidth, -kLaneWidth, kLaneWidth, kLaneHeight);
113 scoped_refptr<SolidColorLayer> green_lane =
114 CreateSolidColorLayer(child_rect, kCSSGreen);
115 background->AddChild(green_lane);
116 green_lane->SetBlendMode(kBlendModes[i]);
119 RunPixelTest(type,
120 root,
121 base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
124 scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
125 // Draw the backdrop with horizontal lanes.
126 const int kLaneWidth = width;
127 const int kLaneHeight = height / kCSSTestColorsCount;
128 SkBitmap backing_store;
129 backing_store.allocN32Pixels(width, height);
130 SkCanvas canvas(backing_store);
131 canvas.clear(SK_ColorTRANSPARENT);
132 for (int i = 0; i < kCSSTestColorsCount; ++i) {
133 SkPaint paint;
134 paint.setColor(kCSSTestColors[i]);
135 canvas.drawRect(
136 SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
138 scoped_refptr<ImageLayer> layer = ImageLayer::Create();
139 layer->SetIsDrawable(true);
140 layer->SetBounds(gfx::Size(width, height));
141 layer->SetBitmap(backing_store);
142 return layer;
145 void SetupMaskLayer(scoped_refptr<Layer> layer) {
146 const int kMaskOffset = 2;
147 gfx::Size bounds = layer->bounds();
148 scoped_refptr<ImageLayer> mask = ImageLayer::Create();
149 mask->SetIsDrawable(true);
150 mask->SetIsMask(true);
151 mask->SetBounds(bounds);
153 SkBitmap bitmap;
154 bitmap.allocN32Pixels(bounds.width(), bounds.height());
155 SkCanvas canvas(bitmap);
156 SkPaint paint;
157 paint.setColor(SK_ColorWHITE);
158 canvas.clear(SK_ColorTRANSPARENT);
159 canvas.drawRect(SkRect::MakeXYWH(kMaskOffset,
160 kMaskOffset,
161 bounds.width() - kMaskOffset * 2,
162 bounds.height() - kMaskOffset * 2),
163 paint);
164 mask->SetBitmap(bitmap);
165 layer->SetMaskLayer(mask.get());
168 void SetupColorMatrix(scoped_refptr<Layer> layer) {
169 FilterOperations filter_operations;
170 filter_operations.Append(FilterOperation::CreateSepiaFilter(.001f));
171 layer->SetFilters(filter_operations);
174 void CreateBlendingColorLayers(int lane_width,
175 int lane_height,
176 scoped_refptr<Layer> background,
177 RenderPassOptions flags) {
178 const int kLanesCount = kBlendModesCount + 4;
179 const SkColor kMiscOpaqueColor = 0xffc86464;
180 const SkColor kMiscTransparentColor = 0x80c86464;
181 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
182 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
183 // add vertical lanes with each of the blend modes
184 for (int i = 0; i < kLanesCount; ++i) {
185 gfx::Rect child_rect(i * lane_width, 0, lane_width, lane_height);
186 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
187 float opacity = 1.f;
188 SkColor color = kMiscOpaqueColor;
190 if (i < kBlendModesCount) {
191 blend_mode = kBlendModes[i];
192 } else if (i == kBlendModesCount) {
193 blend_mode = kCoeffBlendMode;
194 opacity = 0.5f;
195 } else if (i == kBlendModesCount + 1) {
196 blend_mode = kCoeffBlendMode;
197 color = kMiscTransparentColor;
198 } else if (i == kBlendModesCount + 2) {
199 blend_mode = kShaderBlendMode;
200 opacity = 0.5f;
201 } else if (i == kBlendModesCount + 3) {
202 blend_mode = kShaderBlendMode;
203 color = kMiscTransparentColor;
206 scoped_refptr<SolidColorLayer> lane =
207 CreateSolidColorLayer(child_rect, color);
208 lane->SetBlendMode(blend_mode);
209 lane->SetOpacity(opacity);
210 lane->SetForceRenderSurface(true);
211 if (flags & kUseMasks)
212 SetupMaskLayer(lane);
213 if (flags & kUseColorMatrix) {
214 SetupColorMatrix(lane);
216 background->AddChild(lane);
220 void RunBlendingWithRenderPass(PixelTestType type,
221 const base::FilePath::CharType* expected_path,
222 RenderPassOptions flags) {
223 const int kLaneWidth = 8;
224 const int kLaneHeight = kLaneWidth * kCSSTestColorsCount;
225 const int kRootSize = kLaneHeight;
227 scoped_refptr<SolidColorLayer> root =
228 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
229 scoped_refptr<Layer> background =
230 CreateColorfulBackdropLayer(kRootSize, kRootSize);
232 background->SetIsRootForIsolatedGroup(true);
233 root->AddChild(background);
235 CreateBlendingColorLayers(kLaneWidth, kLaneHeight, background.get(), flags);
237 this->impl_side_painting_ = false;
238 this->force_antialiasing_ = (flags & kUseAntialiasing);
239 this->force_blending_with_shaders_ = (flags & kForceShaders);
241 if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
242 // Anti aliasing causes differences up to 8 pixels at the edges.
243 int large_error_allowed = 8;
244 // Blending results might differ with one pixel.
245 int small_error_allowed = 1;
246 // Most of the errors are one pixel errors.
247 float percentage_pixels_small_error = 13.1f;
248 // Because of anti-aliasing, around 10% of pixels (at the edges) have
249 // bigger errors (from small_error_allowed + 1 to large_error_allowed).
250 float percentage_pixels_error = 22.5f;
251 // The average error is still close to 1.
252 float average_error_allowed_in_bad_pixels = 1.4f;
254 pixel_comparator_.reset(
255 new FuzzyPixelComparator(false, // discard_alpha
256 percentage_pixels_error,
257 percentage_pixels_small_error,
258 average_error_allowed_in_bad_pixels,
259 large_error_allowed,
260 small_error_allowed));
263 RunPixelTest(type, root, base::FilePath(expected_path));
266 bool force_antialiasing_;
267 bool force_blending_with_shaders_;
270 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
271 RunBlendingWithRootPixelTestType(PIXEL_TEST_GL);
274 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
275 RunBlendingWithRootPixelTestType(PIXEL_TEST_SOFTWARE);
278 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
279 const int kLaneWidth = 2;
280 const int kLaneHeight = kLaneWidth;
281 const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
282 const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
284 scoped_refptr<SolidColorLayer> background =
285 CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);
287 // Orange child layers have a background filter set and they will blend with
288 // the green background
289 for (int i = 0; i < kBlendModesCount; ++i) {
290 gfx::Rect child_rect(
291 (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
292 scoped_refptr<SolidColorLayer> green_lane =
293 CreateSolidColorLayer(child_rect, kCSSGreen);
294 background->AddChild(green_lane);
296 FilterOperations filters;
297 filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
298 green_lane->SetBackgroundFilters(filters);
299 green_lane->SetBlendMode(kBlendModes[i]);
302 RunPixelTest(PIXEL_TEST_GL,
303 background,
304 base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
307 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
308 RunBlendingWithTransparentPixelTestType(PIXEL_TEST_GL);
311 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
312 RunBlendingWithTransparentPixelTestType(PIXEL_TEST_SOFTWARE);
315 // Tests for render passes
316 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
317 RunBlendingWithRenderPass(
318 PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
321 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
322 RunBlendingWithRenderPass(
323 PIXEL_TEST_SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
326 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
327 RunBlendingWithRenderPass(PIXEL_TEST_GL,
328 FILE_PATH_LITERAL("blending_render_pass.png"),
329 kUseAntialiasing);
332 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
333 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
334 FILE_PATH_LITERAL("blending_render_pass.png"),
335 kUseAntialiasing);
338 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
339 RunBlendingWithRenderPass(PIXEL_TEST_GL,
340 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
341 kUseMasks);
344 TEST_F(LayerTreeHostBlendingPixelTest,
345 BlendingWithRenderPassWithMask_Software) {
346 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
347 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
348 kUseMasks);
351 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
352 RunBlendingWithRenderPass(PIXEL_TEST_GL,
353 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
354 kUseMasks | kUseAntialiasing);
357 TEST_F(LayerTreeHostBlendingPixelTest,
358 BlendingWithRenderPassWithMaskAA_Software) {
359 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
360 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
361 kUseMasks | kUseAntialiasing);
364 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
365 RunBlendingWithRenderPass(PIXEL_TEST_GL,
366 FILE_PATH_LITERAL("blending_render_pass.png"),
367 kUseColorMatrix);
370 TEST_F(LayerTreeHostBlendingPixelTest,
371 BlendingWithRenderPassColorMatrix_Software) {
372 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
373 FILE_PATH_LITERAL("blending_render_pass.png"),
374 kUseColorMatrix);
377 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
378 RunBlendingWithRenderPass(PIXEL_TEST_GL,
379 FILE_PATH_LITERAL("blending_render_pass.png"),
380 kUseAntialiasing | kUseColorMatrix);
383 TEST_F(LayerTreeHostBlendingPixelTest,
384 BlendingWithRenderPassColorMatrixAA_Software) {
385 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
386 FILE_PATH_LITERAL("blending_render_pass.png"),
387 kUseAntialiasing | kUseColorMatrix);
390 TEST_F(LayerTreeHostBlendingPixelTest,
391 BlendingWithRenderPassWithMaskColorMatrix_GL) {
392 RunBlendingWithRenderPass(PIXEL_TEST_GL,
393 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
394 kUseMasks | kUseColorMatrix);
397 TEST_F(LayerTreeHostBlendingPixelTest,
398 BlendingWithRenderPassWithMaskColorMatrix_Software) {
399 RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
400 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
401 kUseMasks | kUseColorMatrix);
404 TEST_F(LayerTreeHostBlendingPixelTest,
405 BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
406 RunBlendingWithRenderPass(PIXEL_TEST_GL,
407 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
408 kUseMasks | kUseAntialiasing | kUseColorMatrix);
411 TEST_F(LayerTreeHostBlendingPixelTest,
412 BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
413 RunBlendingWithRenderPass(PIXEL_TEST_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(PIXEL_TEST_GL,
421 FILE_PATH_LITERAL("blending_render_pass.png"),
422 kForceShaders);
425 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
426 RunBlendingWithRenderPass(PIXEL_TEST_GL,
427 FILE_PATH_LITERAL("blending_render_pass.png"),
428 kUseAntialiasing | kForceShaders);
431 TEST_F(LayerTreeHostBlendingPixelTest,
432 BlendingWithRenderPassShadersWithMask_GL) {
433 RunBlendingWithRenderPass(PIXEL_TEST_GL,
434 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
435 kUseMasks | kForceShaders);
438 TEST_F(LayerTreeHostBlendingPixelTest,
439 BlendingWithRenderPassShadersWithMaskAA_GL) {
440 RunBlendingWithRenderPass(PIXEL_TEST_GL,
441 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
442 kUseMasks | kUseAntialiasing | kForceShaders);
445 TEST_F(LayerTreeHostBlendingPixelTest,
446 BlendingWithRenderPassShadersColorMatrix_GL) {
447 RunBlendingWithRenderPass(PIXEL_TEST_GL,
448 FILE_PATH_LITERAL("blending_render_pass.png"),
449 kUseColorMatrix | kForceShaders);
452 TEST_F(LayerTreeHostBlendingPixelTest,
453 BlendingWithRenderPassShadersColorMatrixAA_GL) {
454 RunBlendingWithRenderPass(PIXEL_TEST_GL,
455 FILE_PATH_LITERAL("blending_render_pass.png"),
456 kUseAntialiasing | kUseColorMatrix | kForceShaders);
459 TEST_F(LayerTreeHostBlendingPixelTest,
460 BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
461 RunBlendingWithRenderPass(PIXEL_TEST_GL,
462 FILE_PATH_LITERAL("blending_render_pass_mask.png"),
463 kUseMasks | kUseColorMatrix | kForceShaders);
466 TEST_F(LayerTreeHostBlendingPixelTest,
467 BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
468 RunBlendingWithRenderPass(
469 PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass_mask.png"),
470 kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
473 } // namespace
474 } // namespace cc
476 #endif // OS_ANDROID