Chromium Code Reviews| Index: cc/trees/layer_tree_host_pixeltest_blending.cc |
| diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc |
| index f01d426c614d58e2ac8d0b7808e0a0778bd02f9f..6845749052f78f601d02c1618afd0a803c234a29 100644 |
| --- a/cc/trees/layer_tree_host_pixeltest_blending.cc |
| +++ b/cc/trees/layer_tree_host_pixeltest_blending.cc |
| @@ -2,8 +2,8 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "cc/layers/image_layer.h" |
| #include "cc/layers/solid_color_layer.h" |
| -#include "cc/layers/texture_layer.h" |
| #include "cc/test/layer_tree_pixel_test.h" |
| #include "cc/test/pixel_comparator.h" |
| @@ -22,7 +22,36 @@ SkXfermode::Mode const kBlendModes[] = { |
| SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode, |
| SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode}; |
| +SkColor kCSSTestColors[] = { |
| + 0xffff0000, // red |
| + 0xff00ff00, // lime |
| + 0xff0000ff, // blue |
| + 0xff00ffff, // aqua |
| + 0xffff00ff, // fuchsia |
| + 0xffffff00, // yellow |
| + 0xff008000, // green |
| + 0xff800000, // maroon |
| + 0xff000080, // navy |
| + 0xff800080, // purple |
| + 0xff808000, // olive |
| + 0xff008080, // teal |
| + 0xfffa8072, // salmon |
| + 0xffc0c0c0, // silver |
| + 0xff000000, // black |
| + 0xff808080, // gray |
| + 0x80000000, // black with transparency |
| + 0xffffffff, // white |
| + 0x80ffffff, // white with transparency |
| + 0x00000000 // transparent |
| +}; |
| + |
| const int kBlendModesCount = arraysize(kBlendModes); |
| +const int kCSSTestColorsCount = arraysize(kCSSTestColors); |
| + |
| +using RenderPassOptions = uint32; |
| +const uint32 kUseMasks = 1 << 0; |
| +const uint32 kUseAntialiasing = 1 << 1; |
| +const uint32 kUseColorMatrix = 1 << 2; |
| class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { |
| public: |
| @@ -82,6 +111,147 @@ class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { |
| root, |
| base::FilePath(FILE_PATH_LITERAL("blending_transparent.png"))); |
| } |
| + |
| + scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) { |
| + // Draw the backdrop with horizontal lanes. |
| + const int kLaneWidth = width; |
| + const int kLaneHeight = height / kCSSTestColorsCount; |
| + SkBitmap backing_store; |
| + backing_store.allocN32Pixels(width, height); |
| + SkCanvas canvas(backing_store); |
| + canvas.clear(SK_ColorTRANSPARENT); |
| + for (int i = 0; i < kCSSTestColorsCount; ++i) { |
| + SkPaint paint; |
| + paint.setColor(kCSSTestColors[i]); |
| + canvas.drawRect( |
| + SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint); |
| + } |
| + scoped_refptr<ImageLayer> layer = ImageLayer::Create(); |
| + layer->SetIsDrawable(true); |
| + layer->SetBounds(gfx::Size(width, height)); |
| + layer->SetBitmap(backing_store); |
| + return layer; |
| + } |
| + |
| + void SetupMaskLayer(scoped_refptr<Layer> layer) { |
| + const int kMaskOffset = 5; |
| + gfx::Size bounds = layer->bounds(); |
| + scoped_refptr<ImageLayer> mask = ImageLayer::Create(); |
| + mask->SetIsDrawable(true); |
| + mask->SetIsMask(true); |
| + mask->SetBounds(bounds); |
| + |
| + SkBitmap bitmap; |
| + bitmap.allocN32Pixels(bounds.width(), bounds.height()); |
| + SkCanvas canvas(bitmap); |
| + SkPaint paint; |
| + paint.setColor(SK_ColorWHITE); |
| + canvas.clear(SK_ColorTRANSPARENT); |
| + canvas.drawRect(SkRect::MakeXYWH(kMaskOffset, |
| + kMaskOffset, |
| + bounds.width() - kMaskOffset * 2, |
| + bounds.height() - kMaskOffset * 2), |
| + paint); |
| + mask->SetBitmap(bitmap); |
| + layer->SetMaskLayer(mask.get()); |
| + } |
| + |
| + void SetupAntiAliasing(scoped_refptr<Layer> layer) { |
| + gfx::Transform rotation; |
| + 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
|
| + layer->SetTransform(rotation); |
| + } |
| + |
| + void SetupColorMatrix(scoped_refptr<Layer> layer) { |
| + FilterOperations filter_operations; |
| + filter_operations.Append(FilterOperation::CreateSepiaFilter(1.f)); |
| + layer->SetFilters(filter_operations); |
| + } |
| + |
| + void CreateBlendingColorLayers(int width, |
| + int height, |
| + scoped_refptr<Layer> background, |
| + RenderPassOptions flags) { |
| + const int kLanesCount = kBlendModesCount + 4; |
| + const int kLaneWidth = width / kLanesCount; |
| + const int kLaneHeight = height; |
| + const SkColor kMiscOpaqueColor = 0xffc86464; |
| + const SkColor kMiscTransparentColor = 0x80c86464; |
| + const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode; |
| + const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode; |
| + // add vertical lanes with each of the blend modes |
| + for (int i = 0; i < kLanesCount; ++i) { |
| + gfx::Rect child_rect(i * kLaneWidth, 0, kLaneWidth, kLaneHeight); |
| + SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; |
| + float opacity = 1.f; |
| + SkColor color = kMiscOpaqueColor; |
| + |
| + if (i < kBlendModesCount) { |
| + blend_mode = kBlendModes[i]; |
| + } else if (i == kBlendModesCount) { |
| + blend_mode = kCoeffBlendMode; |
| + opacity = 0.5f; |
| + } else if (i == kBlendModesCount + 1) { |
| + blend_mode = kCoeffBlendMode; |
| + color = kMiscTransparentColor; |
| + } else if (i == kBlendModesCount + 2) { |
| + blend_mode = kShaderBlendMode; |
| + opacity = 0.5f; |
| + } else if (i == kBlendModesCount + 3) { |
| + blend_mode = kShaderBlendMode; |
| + color = kMiscTransparentColor; |
| + } |
| + |
| + scoped_refptr<SolidColorLayer> lane = |
| + CreateSolidColorLayer(child_rect, color); |
| + lane->SetBlendMode(blend_mode); |
| + lane->SetOpacity(opacity); |
| + lane->SetForceRenderSurface(true); |
| + if (flags & kUseMasks) |
| + SetupMaskLayer(lane); |
| + if (flags & kUseAntialiasing) |
| + SetupAntiAliasing(lane); |
| + if (flags & kUseColorMatrix) { |
| + SetupColorMatrix(lane); |
| + } |
| + background->AddChild(lane); |
| + } |
| + } |
| + |
| + void RunBlendingWithRenderPass(PixelTestType type, |
| + const base::FilePath::CharType* expected_path, |
| + RenderPassOptions flags) { |
| + const int kRootSize = 400; |
| + |
| + scoped_refptr<SolidColorLayer> root = |
| + CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE); |
| + scoped_refptr<Layer> background = |
| + CreateColorfulBackdropLayer(kRootSize, kRootSize); |
| + |
| + background->SetIsRootForIsolatedGroup(true); |
| + root->AddChild(background); |
| + |
| + CreateBlendingColorLayers(kRootSize, kRootSize, background.get(), flags); |
| + |
| + this->impl_side_painting_ = false; |
| + |
| +#if defined(OS_WIN) |
| + float percentage_pixels_large_error = 2.f; // max 3200px / (400*400) |
| + float percentage_pixels_small_error = 0.0f; |
| + float average_error_allowed_in_bad_pixels = 1.f; |
| + int large_error_allowed = 3; |
| + int small_error_allowed = 0; |
| + pixel_comparator_.reset( |
| + new FuzzyPixelComparator(true, // discard_alpha |
| + percentage_pixels_large_error, |
| + percentage_pixels_small_error, |
| + average_error_allowed_in_bad_pixels, |
| + large_error_allowed, |
| + small_error_allowed)); |
| +#endif |
| + |
| + RunPixelTest(type, root, base::FilePath(expected_path)); |
| + } |
| }; |
| TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) { |
| @@ -128,6 +298,117 @@ TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) { |
| RunBlendingWithTransparentPixelTestType(SOFTWARE_WITH_BITMAP); |
| } |
| +// Tests for render passes |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, FILE_PATH_LITERAL("blending_render_pass_gl.png"), 0); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) { |
| + RunBlendingWithRenderPass( |
| + SOFTWARE_WITH_BITMAP, FILE_PATH_LITERAL("blending_render_pass.png"), 0); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) { |
| + RunBlendingWithRenderPass(GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_aa_gl.png"), |
| + kUseAntialiasing); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) { |
| + RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_aa.png"), |
| + kUseAntialiasing); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_gl.png"), |
| + kUseMasks); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMask_Software) { |
| + RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask.png"), |
| + kUseMasks); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_aa_gl.png"), |
| + kUseMasks | kUseAntialiasing); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMaskAA_Software) { |
| + RunBlendingWithRenderPass( |
| + SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_aa.png"), |
| + kUseMasks | kUseAntialiasing); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) { |
| + RunBlendingWithRenderPass(GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_cm_gl.png"), |
| + kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassColorMatrix_Software) { |
| + RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_cm.png"), |
| + kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAAColorMatrix_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_aa_cm_gl.png"), |
| + kUseAntialiasing | kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassAAColorMatrix_Software) { |
| + RunBlendingWithRenderPass(SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_aa_cm.png"), |
| + kUseAntialiasing | kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMaskColorMatrix_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_cm_gl.png"), |
| + kUseMasks | kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMaskColorMatrix_Software) { |
| + RunBlendingWithRenderPass( |
| + SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), |
| + kUseMasks | kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMaskAAColorMatrix_GL) { |
| + RunBlendingWithRenderPass( |
| + GL_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_aa_cm_gl.png"), |
| + kUseMasks | kUseAntialiasing | kUseColorMatrix); |
| +} |
| + |
| +TEST_F(LayerTreeHostBlendingPixelTest, |
| + BlendingWithRenderPassWithMaskAAColorMatrix_Software) { |
| + RunBlendingWithRenderPass( |
| + SOFTWARE_WITH_BITMAP, |
| + FILE_PATH_LITERAL("blending_render_pass_mask_aa_cm.png"), |
| + kUseMasks | kUseAntialiasing | kUseColorMatrix); |
| +} |
| + |
| } // namespace |
| } // namespace cc |