Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / trees / layer_tree_host_pixeltest_blending.cc
index f01d426..7a9ef21 100644 (file)
@@ -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:
@@ -30,6 +59,10 @@ class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
     pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
   }
 
+  virtual void InitializeSettings(LayerTreeSettings* settings) override {
+    settings->force_antialiasing = force_antialiasing_;
+  }
+
  protected:
   void RunBlendingWithRootPixelTestType(PixelTestType type) {
     const int kLaneWidth = 15;
@@ -82,14 +115,179 @@ 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 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;
+    int lane_width = width / kLanesCount;
+    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 * lane_width, 0, lane_width, height);
+      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 & 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;
+    this->force_antialiasing_ = (flags & kUseAntialiasing);
+
+    if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
+      // Anti aliasing causes differences up to 7 pixels at the edges.
+      // Several pixels have 9 units difference on the alpha channel.
+      int large_error_allowed = (flags & kUseMasks) ? 7 : 9;
+      // Blending results might differ with one pixel.
+      int small_error_allowed = 1;
+      // Most of the errors are one pixel errors.
+      float percentage_pixels_small_error = (flags & kUseMasks) ? 7.7f : 12.1f;
+      // Because of anti-aliasing, around 3% of pixels (at the edges) have
+      // bigger errors (from small_error_allowed + 1 to large_error_allowed).
+      float percentage_pixels_error = (flags & kUseMasks) ? 12.4f : 15.f;
+      // The average error is still close to 1.
+      float average_error_allowed_in_bad_pixels =
+          (flags & kUseMasks) ? 1.3f : 1.f;
+
+      // The sepia filter generates more small errors, but the number of large
+      // errors remains around 3%.
+      if (flags & kUseColorMatrix) {
+        percentage_pixels_small_error = (flags & kUseMasks) ? 14.0f : 26.f;
+        percentage_pixels_error = (flags & kUseMasks) ? 18.5f : 29.f;
+        average_error_allowed_in_bad_pixels = (flags & kUseMasks) ? 0.9f : 0.7f;
+      }
+
+      pixel_comparator_.reset(
+          new FuzzyPixelComparator(false,  // discard_alpha
+                                   percentage_pixels_error,
+                                   percentage_pixels_small_error,
+                                   average_error_allowed_in_bad_pixels,
+                                   large_error_allowed,
+                                   small_error_allowed));
+    } else if ((flags & kUseColorMatrix) && (type == PIXEL_TEST_GL)) {
+      float percentage_pixels_error = 100.f;
+      float percentage_pixels_small_error = 0.f;
+      float average_error_allowed_in_bad_pixels = 1.f;
+      int large_error_allowed = 2;
+      int small_error_allowed = 0;
+      pixel_comparator_.reset(
+          new FuzzyPixelComparator(false,  // discard_alpha
+                                   percentage_pixels_error,
+                                   percentage_pixels_small_error,
+                                   average_error_allowed_in_bad_pixels,
+                                   large_error_allowed,
+                                   small_error_allowed));
+    }
+
+    RunPixelTest(type, root, base::FilePath(expected_path));
+  }
+
+  bool force_antialiasing_ = false;
 };
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
-  RunBlendingWithRootPixelTestType(GL_WITH_BITMAP);
+  RunBlendingWithRootPixelTestType(PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
-  RunBlendingWithRootPixelTestType(SOFTWARE_WITH_BITMAP);
+  RunBlendingWithRootPixelTestType(PIXEL_TEST_SOFTWARE);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
@@ -115,17 +313,124 @@ TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
     green_lane->SetBlendMode(kBlendModes[i]);
   }
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
-  RunBlendingWithTransparentPixelTestType(GL_WITH_BITMAP);
+  RunBlendingWithTransparentPixelTestType(PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
-  RunBlendingWithTransparentPixelTestType(SOFTWARE_WITH_BITMAP);
+  RunBlendingWithTransparentPixelTestType(PIXEL_TEST_SOFTWARE);
+}
+
+// Tests for render passes
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass.png"),
+                            kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass.png"),
+                            kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMask_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks | kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks | kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassColorMatrix_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassColorMatrixAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrix_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrix_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseAntialiasing | kUseColorMatrix);
 }
 
 }  // namespace