Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layers/image_layer.h" | |
| 5 #include "cc/layers/solid_color_layer.h" | 6 #include "cc/layers/solid_color_layer.h" |
| 6 #include "cc/layers/texture_layer.h" | |
| 7 #include "cc/test/layer_tree_pixel_test.h" | 7 #include "cc/test/layer_tree_pixel_test.h" |
| 8 #include "cc/test/pixel_comparator.h" | 8 #include "cc/test/pixel_comparator.h" |
| 9 | 9 |
| 10 #if !defined(OS_ANDROID) | 10 #if !defined(OS_ANDROID) |
| 11 | 11 |
| 12 namespace cc { | 12 namespace cc { |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 SkXfermode::Mode const kBlendModes[] = { | 15 SkXfermode::Mode const kBlendModes[] = { |
| 16 SkXfermode::kSrcOver_Mode, SkXfermode::kScreen_Mode, | 16 SkXfermode::kSrcOver_Mode, SkXfermode::kScreen_Mode, |
| 17 SkXfermode::kOverlay_Mode, SkXfermode::kDarken_Mode, | 17 SkXfermode::kOverlay_Mode, SkXfermode::kDarken_Mode, |
| 18 SkXfermode::kLighten_Mode, SkXfermode::kColorDodge_Mode, | 18 SkXfermode::kLighten_Mode, SkXfermode::kColorDodge_Mode, |
| 19 SkXfermode::kColorBurn_Mode, SkXfermode::kHardLight_Mode, | 19 SkXfermode::kColorBurn_Mode, SkXfermode::kHardLight_Mode, |
| 20 SkXfermode::kSoftLight_Mode, SkXfermode::kDifference_Mode, | 20 SkXfermode::kSoftLight_Mode, SkXfermode::kDifference_Mode, |
| 21 SkXfermode::kExclusion_Mode, SkXfermode::kMultiply_Mode, | 21 SkXfermode::kExclusion_Mode, SkXfermode::kMultiply_Mode, |
| 22 SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode, | 22 SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode, |
| 23 SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode}; | 23 SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode}; |
| 24 | 24 |
| 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 | |
| 46 }; | |
| 47 | |
| 25 const int kBlendModesCount = arraysize(kBlendModes); | 48 const int kBlendModesCount = arraysize(kBlendModes); |
| 49 const int kCSSTestColorsCount = arraysize(kCSSTestColors); | |
| 50 | |
| 51 using RenderPassOptions = uint32; | |
| 52 const uint32 kUseMasks = 1 << 0; | |
| 53 const uint32 kUseAntialiasing = 1 << 1; | |
| 54 const uint32 kUseColorMatrix = 1 << 2; | |
| 26 | 55 |
| 27 class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { | 56 class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { |
| 28 public: | 57 public: |
| 29 LayerTreeHostBlendingPixelTest() { | 58 LayerTreeHostBlendingPixelTest() { |
| 30 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true)); | 59 pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true)); |
| 31 } | 60 } |
| 32 | 61 |
| 33 protected: | 62 protected: |
| 34 void RunBlendingWithRootPixelTestType(PixelTestType type) { | 63 void RunBlendingWithRootPixelTestType(PixelTestType type) { |
| 35 const int kLaneWidth = 15; | 64 const int kLaneWidth = 15; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 scoped_refptr<SolidColorLayer> green_lane = | 104 scoped_refptr<SolidColorLayer> green_lane = |
| 76 CreateSolidColorLayer(child_rect, kCSSGreen); | 105 CreateSolidColorLayer(child_rect, kCSSGreen); |
| 77 background->AddChild(green_lane); | 106 background->AddChild(green_lane); |
| 78 green_lane->SetBlendMode(kBlendModes[i]); | 107 green_lane->SetBlendMode(kBlendModes[i]); |
| 79 } | 108 } |
| 80 | 109 |
| 81 RunPixelTest(type, | 110 RunPixelTest(type, |
| 82 root, | 111 root, |
| 83 base::FilePath(FILE_PATH_LITERAL("blending_transparent.png"))); | 112 base::FilePath(FILE_PATH_LITERAL("blending_transparent.png"))); |
| 84 } | 113 } |
| 114 | |
| 115 scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) { | |
| 116 // Draw the backdrop with horizontal lanes. | |
| 117 const int kLaneWidth = width; | |
| 118 const int kLaneHeight = height / kCSSTestColorsCount; | |
| 119 SkBitmap backing_store; | |
| 120 backing_store.allocN32Pixels(width, height); | |
| 121 SkCanvas canvas(backing_store); | |
| 122 canvas.clear(SK_ColorTRANSPARENT); | |
| 123 for (int i = 0; i < kCSSTestColorsCount; ++i) { | |
| 124 SkPaint paint; | |
| 125 paint.setColor(kCSSTestColors[i]); | |
| 126 canvas.drawRect( | |
| 127 SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint); | |
| 128 } | |
| 129 scoped_refptr<ImageLayer> layer = ImageLayer::Create(); | |
| 130 layer->SetIsDrawable(true); | |
| 131 layer->SetBounds(gfx::Size(width, height)); | |
| 132 layer->SetBitmap(backing_store); | |
| 133 return layer; | |
| 134 } | |
| 135 | |
| 136 void SetupMaskLayer(scoped_refptr<Layer> layer) { | |
| 137 const int kMaskOffset = 5; | |
| 138 gfx::Size bounds = layer->bounds(); | |
| 139 scoped_refptr<ImageLayer> mask = ImageLayer::Create(); | |
| 140 mask->SetIsDrawable(true); | |
| 141 mask->SetIsMask(true); | |
| 142 mask->SetBounds(bounds); | |
| 143 | |
| 144 SkBitmap bitmap; | |
| 145 bitmap.allocN32Pixels(bounds.width(), bounds.height()); | |
| 146 SkCanvas canvas(bitmap); | |
| 147 SkPaint paint; | |
| 148 paint.setColor(SK_ColorWHITE); | |
| 149 canvas.clear(SK_ColorTRANSPARENT); | |
| 150 canvas.drawRect(SkRect::MakeXYWH(kMaskOffset, | |
| 151 kMaskOffset, | |
| 152 bounds.width() - kMaskOffset * 2, | |
| 153 bounds.height() - kMaskOffset * 2), | |
| 154 paint); | |
| 155 mask->SetBitmap(bitmap); | |
| 156 layer->SetMaskLayer(mask.get()); | |
| 157 } | |
| 158 | |
| 159 void SetupAntiAliasing(scoped_refptr<Layer> layer) { | |
| 160 gfx::Transform rotation; | |
| 161 rotation.RotateAboutZAxis(5.0); | |
|
enne (OOO)
2014/10/07 19:57:58
There's already some pixel tests for general antia
rosca
2014/10/07 21:30:29
These tests are going to cover each type of shader
| |
| 162 layer->SetTransform(rotation); | |
| 163 } | |
| 164 | |
| 165 void SetupColorMatrix(scoped_refptr<Layer> layer) { | |
| 166 FilterOperations filter_operations; | |
| 167 filter_operations.Append(FilterOperation::CreateSepiaFilter(1.f)); | |
| 168 layer->SetFilters(filter_operations); | |
| 169 } | |
| 170 | |
| 171 void CreateBlendingColorLayers(int width, | |
| 172 int height, | |
| 173 scoped_refptr<Layer> background, | |
| 174 RenderPassOptions flags) { | |
| 175 const int kLanesCount = kBlendModesCount + 4; | |
| 176 const int kLaneWidth = width / kLanesCount; | |
| 177 const int kLaneHeight = height; | |
| 178 const SkColor kMiscOpaqueColor = 0xffc86464; | |
| 179 const SkColor kMiscTransparentColor = 0x80c86464; | |
| 180 const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode; | |
| 181 const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode; | |
| 182 // add vertical lanes with each of the blend modes | |
| 183 for (int i = 0; i < kLanesCount; ++i) { | |
| 184 gfx::Rect child_rect(i * kLaneWidth, 0, kLaneWidth, kLaneHeight); | |
| 185 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; | |
| 186 float opacity = 1.f; | |
| 187 SkColor color = kMiscOpaqueColor; | |
| 188 | |
| 189 if (i < kBlendModesCount) { | |
| 190 blend_mode = kBlendModes[i]; | |
| 191 } else if (i == kBlendModesCount) { | |
| 192 blend_mode = kCoeffBlendMode; | |
| 193 opacity = 0.5f; | |
| 194 } else if (i == kBlendModesCount + 1) { | |
| 195 blend_mode = kCoeffBlendMode; | |
| 196 color = kMiscTransparentColor; | |
| 197 } else if (i == kBlendModesCount + 2) { | |
| 198 blend_mode = kShaderBlendMode; | |
| 199 opacity = 0.5f; | |
| 200 } else if (i == kBlendModesCount + 3) { | |
| 201 blend_mode = kShaderBlendMode; | |
| 202 color = kMiscTransparentColor; | |
| 203 } | |
| 204 | |
| 205 scoped_refptr<SolidColorLayer> lane = | |
| 206 CreateSolidColorLayer(child_rect, color); | |
| 207 lane->SetBlendMode(blend_mode); | |
| 208 lane->SetOpacity(opacity); | |
| 209 lane->SetForceRenderSurface(true); | |
| 210 if (flags & kUseMasks) | |
| 211 SetupMaskLayer(lane); | |
| 212 if (flags & kUseAntialiasing) | |
| 213 SetupAntiAliasing(lane); | |
| 214 if (flags & kUseColorMatrix) { | |
| 215 SetupColorMatrix(lane); | |
| 216 } | |
| 217 background->AddChild(lane); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 void RunBlendingWithRenderPass(PixelTestType type, | |
| 222 const base::FilePath::CharType* expected_path, | |
| 223 RenderPassOptions flags) { | |
| 224 const int kRootSize = 400; | |
| 225 | |
| 226 scoped_refptr<SolidColorLayer> root = | |
| 227 CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE); | |
| 228 scoped_refptr<Layer> background = | |
| 229 CreateColorfulBackdropLayer(kRootSize, kRootSize); | |
| 230 | |
| 231 background->SetIsRootForIsolatedGroup(true); | |
| 232 root->AddChild(background); | |
| 233 | |
| 234 CreateBlendingColorLayers(kRootSize, kRootSize, background.get(), flags); | |
| 235 | |
| 236 this->impl_side_painting_ = false; | |
| 237 | |
| 238 #if defined(OS_WIN) | |
| 239 float percentage_pixels_large_error = 2.f; // max 3200px / (400*400) | |
| 240 float percentage_pixels_small_error = 0.0f; | |
| 241 float average_error_allowed_in_bad_pixels = 1.f; | |
| 242 int large_error_allowed = 3; | |
| 243 int small_error_allowed = 0; | |
| 244 pixel_comparator_.reset( | |
| 245 new FuzzyPixelComparator(true, // discard_alpha | |
| 246 percentage_pixels_large_error, | |
| 247 percentage_pixels_small_error, | |
| 248 average_error_allowed_in_bad_pixels, | |
| 249 large_error_allowed, | |
| 250 small_error_allowed)); | |
| 251 #endif | |
| 252 | |
| 253 RunPixelTest(type, root, base::FilePath(expected_path)); | |
| 254 } | |
| 85 }; | 255 }; |
| 86 | 256 |
| 87 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) { | 257 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) { |
| 88 RunBlendingWithRootPixelTestType(GL_WITH_BITMAP); | 258 RunBlendingWithRootPixelTestType(GL_WITH_BITMAP); |
| 89 } | 259 } |
| 90 | 260 |
| 91 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) { | 261 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) { |
| 92 RunBlendingWithRootPixelTestType(SOFTWARE_WITH_BITMAP); | 262 RunBlendingWithRootPixelTestType(SOFTWARE_WITH_BITMAP); |
| 93 } | 263 } |
| 94 | 264 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 121 } | 291 } |
| 122 | 292 |
| 123 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) { | 293 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) { |
| 124 RunBlendingWithTransparentPixelTestType(GL_WITH_BITMAP); | 294 RunBlendingWithTransparentPixelTestType(GL_WITH_BITMAP); |
| 125 } | 295 } |
| 126 | 296 |
| 127 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) { | 297 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) { |
| 128 RunBlendingWithTransparentPixelTestType(SOFTWARE_WITH_BITMAP); | 298 RunBlendingWithTransparentPixelTestType(SOFTWARE_WITH_BITMAP); |
| 129 } | 299 } |
| 130 | 300 |
| 301 // Tests for render passes | |
| 302 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) { | |
| 303 RunBlendingWithRenderPass( | |
| 304 GL_WITH_BITMAP, FILE_PATH_LITERAL("blending_render_pass_gl.png"), 0); | |
| 305 } | |
| 306 | |
| 307 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) { | |
| 308 RunBlendingWithRenderPass( | |
| 309 SOFTWARE_WITH_BITMAP, FILE_PATH_LITERAL("blending_render_pass.png"), 0); | |
| 310 } | |
| 311 | |
| 312 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) { | |
| 313 RunBlendingWithRenderPass(GL_WITH_BITMAP, | |
| 314 FILE_PATH_LITERAL("blending_render_pass_aa_gl.png"), | |
| 315 kUseAntialiasing); | |
| 316 } | |
| 317 | |
| 318 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) { | |
| 319 RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, | |
| 320 FILE_PATH_LITERAL("blending_render_pass_aa.png"), | |
| 321 kUseAntialiasing); | |
| 322 } | |
| 323 | |
| 324 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) { | |
| 325 RunBlendingWithRenderPass( | |
| 326 GL_WITH_BITMAP, | |
| 327 FILE_PATH_LITERAL("blending_render_pass_mask_gl.png"), | |
| 328 kUseMasks); | |
| 329 } | |
| 330 | |
| 331 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 332 BlendingWithRenderPassWithMask_Software) { | |
| 333 RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, | |
| 334 FILE_PATH_LITERAL("blending_render_pass_mask.png"), | |
| 335 kUseMasks); | |
| 336 } | |
| 337 | |
| 338 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) { | |
| 339 RunBlendingWithRenderPass( | |
| 340 GL_WITH_BITMAP, | |
| 341 FILE_PATH_LITERAL("blending_render_pass_mask_aa_gl.png"), | |
| 342 kUseMasks | kUseAntialiasing); | |
| 343 } | |
| 344 | |
| 345 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 346 BlendingWithRenderPassWithMaskAA_Software) { | |
| 347 RunBlendingWithRenderPass( | |
| 348 SOFTWARE_WITH_BITMAP, | |
| 349 FILE_PATH_LITERAL("blending_render_pass_mask_aa.png"), | |
| 350 kUseMasks | kUseAntialiasing); | |
| 351 } | |
| 352 | |
| 353 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) { | |
| 354 RunBlendingWithRenderPass(GL_WITH_BITMAP, | |
| 355 FILE_PATH_LITERAL("blending_render_pass_cm_gl.png"), | |
| 356 kUseColorMatrix); | |
| 357 } | |
| 358 | |
| 359 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 360 BlendingWithRenderPassColorMatrix_Software) { | |
| 361 RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, | |
| 362 FILE_PATH_LITERAL("blending_render_pass_cm.png"), | |
| 363 kUseColorMatrix); | |
| 364 } | |
| 365 | |
| 366 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAAColorMatrix_GL) { | |
| 367 RunBlendingWithRenderPass( | |
| 368 GL_WITH_BITMAP, | |
| 369 FILE_PATH_LITERAL("blending_render_pass_aa_cm_gl.png"), | |
| 370 kUseAntialiasing | kUseColorMatrix); | |
| 371 } | |
| 372 | |
| 373 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 374 BlendingWithRenderPassAAColorMatrix_Software) { | |
| 375 RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, | |
| 376 FILE_PATH_LITERAL("blending_render_pass_aa_cm.png"), | |
| 377 kUseAntialiasing | kUseColorMatrix); | |
| 378 } | |
| 379 | |
| 380 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 381 BlendingWithRenderPassWithMaskColorMatrix_GL) { | |
| 382 RunBlendingWithRenderPass( | |
| 383 GL_WITH_BITMAP, | |
| 384 FILE_PATH_LITERAL("blending_render_pass_mask_cm_gl.png"), | |
| 385 kUseMasks | kUseColorMatrix); | |
| 386 } | |
| 387 | |
| 388 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 389 BlendingWithRenderPassWithMaskColorMatrix_Software) { | |
| 390 RunBlendingWithRenderPass( | |
| 391 SOFTWARE_WITH_BITMAP, | |
| 392 FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), | |
| 393 kUseMasks | kUseColorMatrix); | |
| 394 } | |
| 395 | |
| 396 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 397 BlendingWithRenderPassWithMaskAAColorMatrix_GL) { | |
| 398 RunBlendingWithRenderPass( | |
| 399 GL_WITH_BITMAP, | |
| 400 FILE_PATH_LITERAL("blending_render_pass_mask_aa_cm_gl.png"), | |
| 401 kUseMasks | kUseAntialiasing | kUseColorMatrix); | |
| 402 } | |
| 403 | |
| 404 TEST_F(LayerTreeHostBlendingPixelTest, | |
| 405 BlendingWithRenderPassWithMaskAAColorMatrix_Software) { | |
| 406 RunBlendingWithRenderPass( | |
| 407 SOFTWARE_WITH_BITMAP, | |
| 408 FILE_PATH_LITERAL("blending_render_pass_mask_aa_cm.png"), | |
| 409 kUseMasks | kUseAntialiasing | kUseColorMatrix); | |
| 410 } | |
| 411 | |
| 131 } // namespace | 412 } // namespace |
| 132 } // namespace cc | 413 } // namespace cc |
| 133 | 414 |
| 134 #endif // OS_ANDROID | 415 #endif // OS_ANDROID |
| OLD | NEW |