// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/message_loop/message_loop.h"
#include "cc/layers/append_quads_data.h"
#include "cc/output/gl_renderer.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/picture_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/resources/video_resource_updater.h"
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/pixel_test.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
#include "ui/gfx/geometry/rect_conversions.h"

using gpu::gles2::GLES2Interface;

namespace cc {
namespace {

#if !defined(OS_ANDROID)
scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
                                                const gfx::Rect& rect) {
  scoped_ptr<RenderPass> pass = RenderPass::Create();
  const gfx::Rect output_rect = rect;
  const gfx::Rect damage_rect = rect;
  const gfx::Transform transform_to_root_target;
  pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
  return pass.Pass();
}

scoped_ptr<RenderPass> CreateTestRenderPass(
    RenderPassId id,
    const gfx::Rect& rect,
    const gfx::Transform& transform_to_root_target) {
  scoped_ptr<RenderPass> pass = RenderPass::Create();
  const gfx::Rect output_rect = rect;
  const gfx::Rect damage_rect = rect;
  pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
  return pass.Pass();
}

SharedQuadState* CreateTestSharedQuadState(
    gfx::Transform content_to_target_transform,
    const gfx::Rect& rect,
    RenderPass* render_pass) {
  const gfx::Size content_bounds = rect.size();
  const gfx::Rect visible_content_rect = rect;
  const gfx::Rect clip_rect = rect;
  const bool is_clipped = false;
  const float opacity = 1.0f;
  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
  int sorting_context_id = 0;
  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
  shared_state->SetAll(content_to_target_transform,
                       content_bounds,
                       visible_content_rect,
                       clip_rect,
                       is_clipped,
                       opacity,
                       blend_mode,
                       sorting_context_id);
  return shared_state;
}

SharedQuadState* CreateTestSharedQuadStateClipped(
    gfx::Transform content_to_target_transform,
    const gfx::Rect& rect,
    const gfx::Rect& clip_rect,
    RenderPass* render_pass) {
  const gfx::Size content_bounds = rect.size();
  const gfx::Rect visible_content_rect = clip_rect;
  const bool is_clipped = true;
  const float opacity = 1.0f;
  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
  int sorting_context_id = 0;
  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
  shared_state->SetAll(content_to_target_transform,
                       content_bounds,
                       visible_content_rect,
                       clip_rect,
                       is_clipped,
                       opacity,
                       blend_mode,
                       sorting_context_id);
  return shared_state;
}

void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
                                  const gfx::Rect& rect,
                                  RenderPassId pass_id,
                                  RenderPass* render_pass) {
  RenderPassDrawQuad* quad =
      render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  quad->SetNew(shared_state,
               rect,
               rect,
               pass_id,
               0,                    // mask_resource_id
               gfx::Vector2dF(),     // mask_uv_scale
               gfx::Size(),          // mask_texture_size
               FilterOperations(),   // foreground filters
               gfx::Vector2dF(),     // filters scale
               FilterOperations());  // background filters
}

void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
                                         SkColor texel_color,
                                         SkColor texel_stripe_color,
                                         SkColor background_color,
                                         bool premultiplied_alpha,
                                         const SharedQuadState* shared_state,
                                         ResourceProvider* resource_provider,
                                         RenderPass* render_pass) {
  SkPMColor pixel_color = premultiplied_alpha
                              ? SkPreMultiplyColor(texel_color)
                              : SkPackARGB32NoCheck(SkColorGetA(texel_color),
                                                    SkColorGetR(texel_color),
                                                    SkColorGetG(texel_color),
                                                    SkColorGetB(texel_color));
  SkPMColor pixel_stripe_color =
      premultiplied_alpha
          ? SkPreMultiplyColor(texel_stripe_color)
          : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
                                SkColorGetR(texel_stripe_color),
                                SkColorGetG(texel_stripe_color),
                                SkColorGetB(texel_stripe_color));
  std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
  for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
    for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
      pixels[i * rect.width() + k] = pixel_stripe_color;
    }
  }
  ResourceProvider::ResourceId resource = resource_provider->CreateResource(
      rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
      RGBA_8888);
  resource_provider->SetPixels(resource,
                               reinterpret_cast<uint8_t*>(&pixels.front()),
                               rect, rect, gfx::Vector2d());

  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
  const gfx::PointF uv_top_left(0.0f, 0.0f);
  const gfx::PointF uv_bottom_right(1.0f, 1.0f);
  const bool flipped = false;
  const bool nearest_neighbor = false;
  TextureDrawQuad* quad =
      render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
  quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
               premultiplied_alpha, uv_top_left, uv_bottom_right,
               background_color, vertex_opacity, flipped, nearest_neighbor);
}

void CreateTestTextureDrawQuad(const gfx::Rect& rect,
                               SkColor texel_color,
                               SkColor background_color,
                               bool premultiplied_alpha,
                               const SharedQuadState* shared_state,
                               ResourceProvider* resource_provider,
                               RenderPass* render_pass) {
  SkPMColor pixel_color = premultiplied_alpha ?
      SkPreMultiplyColor(texel_color) :
      SkPackARGB32NoCheck(SkColorGetA(texel_color),
                          SkColorGetR(texel_color),
                          SkColorGetG(texel_color),
                          SkColorGetB(texel_color));
  size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
  std::vector<uint32_t> pixels(num_pixels, pixel_color);

  ResourceProvider::ResourceId resource = resource_provider->CreateResource(
      rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
      RGBA_8888);
  resource_provider->CopyToResource(
      resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());

  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};

  const gfx::PointF uv_top_left(0.0f, 0.0f);
  const gfx::PointF uv_bottom_right(1.0f, 1.0f);
  const bool flipped = false;
  const bool nearest_neighbor = false;
  TextureDrawQuad* quad =
      render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
  quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
               premultiplied_alpha, uv_top_left, uv_bottom_right,
               background_color, vertex_opacity, flipped, nearest_neighbor);
}

void CreateTestYUVVideoDrawQuad_FromVideoFrame(
    const SharedQuadState* shared_state,
    scoped_refptr<media::VideoFrame> video_frame,
    uint8 alpha_value,
    const gfx::RectF& tex_coord_rect,
    RenderPass* render_pass,
    VideoResourceUpdater* video_resource_updater,
    const gfx::Rect& rect,
    ResourceProvider* resource_provider) {
  const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
  const YUVVideoDrawQuad::ColorSpace color_space =
      (video_frame->format() == media::VideoFrame::YV12J
           ? YUVVideoDrawQuad::JPEG
           : YUVVideoDrawQuad::REC_601);
  const gfx::Rect opaque_rect(0, 0, 0, 0);

  if (with_alpha) {
    memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
           video_frame->stride(media::VideoFrame::kAPlane) *
               video_frame->rows(media::VideoFrame::kAPlane));
  }

  VideoFrameExternalResources resources =
      video_resource_updater->CreateExternalResourcesFromVideoFrame(
          video_frame);

  EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
  EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
            resources.mailboxes.size());
  EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
            resources.release_callbacks.size());

  ResourceProvider::ResourceId y_resource =
      resource_provider->CreateResourceFromTextureMailbox(
          resources.mailboxes[media::VideoFrame::kYPlane],
          SingleReleaseCallbackImpl::Create(
              resources.release_callbacks[media::VideoFrame::kYPlane]));
  ResourceProvider::ResourceId u_resource =
      resource_provider->CreateResourceFromTextureMailbox(
          resources.mailboxes[media::VideoFrame::kUPlane],
          SingleReleaseCallbackImpl::Create(
              resources.release_callbacks[media::VideoFrame::kUPlane]));
  ResourceProvider::ResourceId v_resource =
      resource_provider->CreateResourceFromTextureMailbox(
          resources.mailboxes[media::VideoFrame::kVPlane],
          SingleReleaseCallbackImpl::Create(
              resources.release_callbacks[media::VideoFrame::kVPlane]));
  ResourceProvider::ResourceId a_resource = 0;
  if (with_alpha) {
    a_resource = resource_provider->CreateResourceFromTextureMailbox(
        resources.mailboxes[media::VideoFrame::kAPlane],
        SingleReleaseCallbackImpl::Create(
            resources.release_callbacks[media::VideoFrame::kAPlane]));
  }

  YUVVideoDrawQuad* yuv_quad =
      render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
  yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
                   video_frame->coded_size(), y_resource, u_resource,
                   v_resource, a_resource, color_space);
}

void CreateTestYUVVideoDrawQuad_Striped(
    const SharedQuadState* shared_state,
    media::VideoFrame::Format format,
    bool is_transparent,
    const gfx::RectF& tex_coord_rect,
    RenderPass* render_pass,
    VideoResourceUpdater* video_resource_updater,
    const gfx::Rect& rect,
    ResourceProvider* resource_provider) {
  scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
      format, rect.size(), rect, rect.size(), base::TimeDelta());

  // YUV values representing a striped pattern, for validating texture
  // coordinates for sampling.
  uint8_t y_value = 0;
  uint8_t u_value = 0;
  uint8_t v_value = 0;
  for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
    uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
                     video_frame->stride(media::VideoFrame::kYPlane) * i;
    for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
         ++j) {
      y_row[j] = (y_value += 1);
    }
  }
  for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
    uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
                     video_frame->stride(media::VideoFrame::kUPlane) * i;
    uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
                     video_frame->stride(media::VideoFrame::kVPlane) * i;
    for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
         ++j) {
      u_row[j] = (u_value += 3);
      v_row[j] = (v_value += 5);
    }
  }
  uint8 alpha_value = is_transparent ? 0 : 128;
  CreateTestYUVVideoDrawQuad_FromVideoFrame(
      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
      video_resource_updater, rect, resource_provider);
}

// Creates a video frame of size background_size filled with yuv_background,
// and then draws a foreground rectangle in a different color on top of
// that. The foreground rectangle must have coordinates that are divisible
// by 2 because YUV is a block format.
void CreateTestYUVVideoDrawQuad_TwoColor(
    const SharedQuadState* shared_state,
    media::VideoFrame::Format format,
    bool is_transparent,
    const gfx::RectF& tex_coord_rect,
    const gfx::Size& background_size,
    uint8 y_background,
    uint8 u_background,
    uint8 v_background,
    const gfx::Rect& foreground_rect,
    uint8 y_foreground,
    uint8 u_foreground,
    uint8 v_foreground,
    RenderPass* render_pass,
    VideoResourceUpdater* video_resource_updater,
    ResourceProvider* resource_provider) {
  const gfx::Rect rect(background_size);

  scoped_refptr<media::VideoFrame> video_frame =
      media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
                                     foreground_rect.size(), base::TimeDelta());

  int planes[] = {media::VideoFrame::kYPlane,
                  media::VideoFrame::kUPlane,
                  media::VideoFrame::kVPlane};
  uint8 yuv_background[] = {y_background, u_background, v_background};
  uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
  int sample_size[] = {1, 2, 2};

  for (int i = 0; i < 3; ++i) {
    memset(video_frame->data(planes[i]), yuv_background[i],
           video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
  }

  for (int i = 0; i < 3; ++i) {
    // Since yuv encoding uses block encoding, widths have to be divisible
    // by the sample size in order for this function to behave properly.
    DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
    DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
    DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
    DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);

    gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
                          foreground_rect.y() / sample_size[i],
                          foreground_rect.width() / sample_size[i],
                          foreground_rect.height() / sample_size[i]);
    for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
      for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
        size_t offset = y * video_frame->stride(planes[i]) + x;
        video_frame->data(planes[i])[offset] = yuv_foreground[i];
      }
    }
  }

  uint8 alpha_value = 255;
  CreateTestYUVVideoDrawQuad_FromVideoFrame(
      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
      video_resource_updater, rect, resource_provider);
}

void CreateTestYUVVideoDrawQuad_Solid(
    const SharedQuadState* shared_state,
    media::VideoFrame::Format format,
    bool is_transparent,
    const gfx::RectF& tex_coord_rect,
    uint8 y,
    uint8 u,
    uint8 v,
    RenderPass* render_pass,
    VideoResourceUpdater* video_resource_updater,
    const gfx::Rect& rect,
    ResourceProvider* resource_provider) {
  scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
      format, rect.size(), rect, rect.size(), base::TimeDelta());

  // YUV values of a solid, constant, color. Useful for testing that color
  // space/color range are being handled properly.
  memset(video_frame->data(media::VideoFrame::kYPlane), y,
         video_frame->stride(media::VideoFrame::kYPlane) *
             video_frame->rows(media::VideoFrame::kYPlane));
  memset(video_frame->data(media::VideoFrame::kUPlane), u,
         video_frame->stride(media::VideoFrame::kUPlane) *
             video_frame->rows(media::VideoFrame::kUPlane));
  memset(video_frame->data(media::VideoFrame::kVPlane), v,
         video_frame->stride(media::VideoFrame::kVPlane) *
             video_frame->rows(media::VideoFrame::kVPlane));

  uint8 alpha_value = is_transparent ? 0 : 128;
  CreateTestYUVVideoDrawQuad_FromVideoFrame(
      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
      video_resource_updater, rect, resource_provider);
}

typedef ::testing::Types<GLRenderer,
                         SoftwareRenderer,
                         GLRendererWithExpandedViewport,
                         SoftwareRendererWithExpandedViewport> RendererTypes;
TYPED_TEST_CASE(RendererPixelTest, RendererTypes);

template <typename RendererType>
class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};

typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
    SoftwareRendererTypes;
TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);

template <typename RendererType>
class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
 public:
  explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
      : fuzzy_(discard_alpha), exact_(discard_alpha) {}

  bool Compare(const SkBitmap& actual_bmp,
               const SkBitmap& expected_bmp) const override;

 private:
  FuzzyPixelOffByOneComparator fuzzy_;
  ExactPixelComparator exact_;
};

template<>
bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
    const SkBitmap& actual_bmp,
    const SkBitmap& expected_bmp) const {
  return fuzzy_.Compare(actual_bmp, expected_bmp);
}

template <>
bool FuzzyForSoftwareOnlyPixelComparator<
    SoftwareRendererWithExpandedViewport>::Compare(
    const SkBitmap& actual_bmp,
    const SkBitmap& expected_bmp) const {
  return fuzzy_.Compare(actual_bmp, expected_bmp);
}

template<typename RendererType>
bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
    const SkBitmap& actual_bmp,
    const SkBitmap& expected_bmp) const {
  return exact_.Compare(actual_bmp, expected_bmp);
}

TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());

  SolidColorDrawQuad* color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
  gfx::Rect rect(this->device_viewport_size_);
  gfx::Rect small_rect(100, 100);

  RenderPassId child_id(2, 1);
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_id, small_rect, gfx::Transform());

  SharedQuadState* child_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());

  SolidColorDrawQuad* color_quad =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);

  RenderPassId root_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRenderPass(root_id, rect, gfx::Transform());

  SharedQuadState* root_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());

  CreateTestRenderPassDrawQuad(
      root_shared_state, small_rect, child_id, root_pass.get());

  RenderPass* child_pass_ptr = child_pass.get();

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
      &pass_list,
      child_pass_ptr,
      base::FilePath(FILE_PATH_LITERAL("green_small.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());

  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
                            SK_ColorTRANSPARENT,  // Background color.
                            true,                 // Premultiplied alpha.
                            shared_state,
                            this->resource_provider_.get(),
                            pass.get());

  SolidColorDrawQuad* color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
      FuzzyPixelOffByOneComparator(true)));
}

TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* texture_quad_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  texture_quad_state->opacity = 0.8f;

  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
                            SK_ColorGREEN,  // Background color.
                            true,           // Premultiplied alpha.
                            texture_quad_state,
                            this->resource_provider_.get(),
                            pass.get());

  SharedQuadState* color_quad_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
      FuzzyPixelOffByOneComparator(true)));
}

template <typename QuadType>
static const base::FilePath::CharType* IntersectingQuadImage() {
  return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
}
template <>
const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
  return FILE_PATH_LITERAL("intersecting_blue_green.png");
}
template <>
const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
  return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
}

template <typename TypeParam>
class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
 protected:
  void SetupQuadStateAndRenderPass() {
    // This sets up a pair of draw quads. They are both rotated
    // relative to the root plane, they are also rotated relative to each other.
    // The intersect in the middle at a non-perpendicular angle so that any
    // errors are hopefully magnified.
    // The quads should intersect correctly, as in the front quad should only
    // be partially in front of the back quad, and partially behind.

    viewport_rect_ = gfx::Rect(this->device_viewport_size_);
    quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
                           this->device_viewport_size_.height() / 2.0);

    RenderPassId id(1, 1);
    render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);

    // Create the front quad rotated on the Z and Y axis.
    gfx::Transform trans;
    trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
    trans.RotateAboutZAxis(45.0);
    trans.RotateAboutYAxis(45.0);
    front_quad_state_ =
        CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
    front_quad_state_->clip_rect = quad_rect_;
    // Make sure they end up in a 3d sorting context.
    front_quad_state_->sorting_context_id = 1;

    // Create the back quad, and rotate on just the y axis. This will intersect
    // the first quad partially.
    trans = gfx::Transform();
    trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
    trans.RotateAboutYAxis(-45.0);
    back_quad_state_ =
        CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
    back_quad_state_->sorting_context_id = 1;
    back_quad_state_->clip_rect = quad_rect_;
  }
  template <typename T>
  void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
    SharedQuadState* background_quad_state = CreateTestSharedQuadState(
        gfx::Transform(), viewport_rect_, render_pass_.get());
    SolidColorDrawQuad* background_quad =
        render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    background_quad->SetNew(background_quad_state, viewport_rect_,
                            viewport_rect_, SK_ColorWHITE, false);
    pass_list_.push_back(render_pass_.Pass());
    const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
    EXPECT_TRUE(
        this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
  }
  template <typename T>
  T* CreateAndAppendDrawQuad() {
    return render_pass_->CreateAndAppendDrawQuad<T>();
  }

  scoped_ptr<RenderPass> render_pass_;
  gfx::Rect viewport_rect_;
  SharedQuadState* front_quad_state_;
  SharedQuadState* back_quad_state_;
  gfx::Rect quad_rect_;
  RenderPassList pass_list_;
};

template <typename TypeParam>
class IntersectingQuadGLPixelTest
    : public IntersectingQuadPixelTest<TypeParam> {
 public:
  void SetUp() override {
    IntersectingQuadPixelTest<TypeParam>::SetUp();
    video_resource_updater_.reset(
        new VideoResourceUpdater(this->output_surface_->context_provider(),
                                 this->resource_provider_.get()));
    video_resource_updater2_.reset(
        new VideoResourceUpdater(this->output_surface_->context_provider(),
                                 this->resource_provider_.get()));
  }

 protected:
  scoped_ptr<VideoResourceUpdater> video_resource_updater_;
  scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
};

template <typename TypeParam>
class IntersectingQuadSoftwareTest
    : public IntersectingQuadPixelTest<TypeParam> {};

typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
    SoftwareRendererTypes;
typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
    GLRendererTypes;

TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);

TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
  this->SetupQuadStateAndRenderPass();

  SolidColorDrawQuad* quad =
      this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  SolidColorDrawQuad* quad2 =
      this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();

  quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
               SK_ColorBLUE, false);
  quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
                SK_ColorGREEN, false);
  SCOPED_TRACE("IntersectingSolidColorQuads");
  this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
}

template <typename TypeParam>
SkColor GetColor(const SkColor& color) {
  return color;
}

template <>
SkColor GetColor<GLRenderer>(const SkColor& color) {
  return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
                        SkColorGetG(color), SkColorGetR(color));
}
template <>
SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
  return GetColor<GLRenderer>(color);
}

TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
  this->SetupQuadStateAndRenderPass();
  CreateTestTwoColoredTextureDrawQuad(
      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
      true, this->front_quad_state_, this->resource_provider_.get(),
      this->render_pass_.get());
  CreateTestTwoColoredTextureDrawQuad(
      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
      true, this->back_quad_state_, this->resource_provider_.get(),
      this->render_pass_.get());

  SCOPED_TRACE("IntersectingTexturedQuads");
  this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
}

TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
  this->SetupQuadStateAndRenderPass();
  gfx::RectF outer_rect(this->quad_rect_);
  gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
                        this->quad_rect_.y() + (this->quad_rect_.height() / 4),
                        this->quad_rect_.width() / 2,
                        this->quad_rect_.height() / 2);

  SkPaint black_paint;
  black_paint.setColor(SK_ColorBLACK);
  SkPaint blue_paint;
  blue_paint.setColor(SK_ColorBLUE);
  SkPaint green_paint;
  green_paint.setColor(SK_ColorGREEN);

  scoped_ptr<FakePicturePile> blue_recording =
      FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
                                        this->quad_rect_.size());
  blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
  blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
  blue_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> blue_pile =
      FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);

  PictureDrawQuad* blue_quad =
      this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();

  blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
                    this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
                    false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);

  scoped_ptr<FakePicturePile> green_recording =
      FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
                                        this->quad_rect_.size());
  green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
  green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
  green_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> green_pile =
      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);

  PictureDrawQuad* green_quad =
      this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
  green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
                     this->quad_rect_, this->quad_rect_,
                     this->quad_rect_.size(), false, RGBA_8888,
                     this->quad_rect_, 1.f, green_pile);
  SCOPED_TRACE("IntersectingPictureQuadsPass");
  this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
}

TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
  this->SetupQuadStateAndRenderPass();
  RenderPassId child_pass_id1(2, 2);
  RenderPassId child_pass_id2(2, 3);
  scoped_ptr<RenderPass> child_pass1 =
      CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
  SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
      gfx::Transform(), this->quad_rect_, child_pass1.get());
  scoped_ptr<RenderPass> child_pass2 =
      CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
  SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
      gfx::Transform(), this->quad_rect_, child_pass2.get());

  CreateTestTwoColoredTextureDrawQuad(
      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
      true, child1_quad_state, this->resource_provider_.get(),
      child_pass1.get());
  CreateTestTwoColoredTextureDrawQuad(
      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
      true, child2_quad_state, this->resource_provider_.get(),
      child_pass2.get());

  CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
                               child_pass_id1, this->render_pass_.get());
  CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
                               child_pass_id2, this->render_pass_.get());

  this->pass_list_.push_back(child_pass1.Pass());
  this->pass_list_.push_back(child_pass2.Pass());
  SCOPED_TRACE("IntersectingRenderQuadsPass");
  this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
}

TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
  this->SetupQuadStateAndRenderPass();
  gfx::Rect inner_rect(
      ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
      ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
      (this->quad_rect_.width() / 2) & ~0xF,
      (this->quad_rect_.height() / 2) & ~0xF);

  CreateTestYUVVideoDrawQuad_TwoColor(
      this->front_quad_state_, media::VideoFrame::YV12J, false,
      gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 0, 128, 128,
      inner_rect, 29, 255, 107, this->render_pass_.get(),
      this->video_resource_updater_.get(), this->resource_provider_.get());

  CreateTestYUVVideoDrawQuad_TwoColor(
      this->back_quad_state_, media::VideoFrame::YV12J, false,
      gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 149, 43, 21,
      inner_rect, 0, 128, 128, this->render_pass_.get(),
      this->video_resource_updater2_.get(), this->resource_provider_.get());

  SCOPED_TRACE("IntersectingVideoQuads");
  this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
      FuzzyPixelOffByOneComparator(false));
}

// TODO(skaslev): The software renderer does not support non-premultplied alpha.
TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());

  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
                            SK_ColorTRANSPARENT,  // Background color.
                            false,                // Premultiplied alpha.
                            shared_state,
                            this->resource_provider_.get(),
                            pass.get());

  SolidColorDrawQuad* color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
      FuzzyPixelOffByOneComparator(true)));
}

// TODO(skaslev): The software renderer does not support non-premultplied alpha.
TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* texture_quad_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  texture_quad_state->opacity = 0.8f;

  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
                            SK_ColorGREEN,  // Background color.
                            false,          // Premultiplied alpha.
                            texture_quad_state,
                            this->resource_provider_.get(),
                            pass.get());

  SharedQuadState* color_quad_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
      FuzzyPixelOffByOneComparator(true)));
}

TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());
  shared_state->opacity = 0.5f;

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* blank_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  SolidColorDrawQuad* white =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  white->SetNew(
      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());

  SkScalar matrix[20];
  float amount = 0.5f;
  matrix[0] = 0.213f + 0.787f * amount;
  matrix[1] = 0.715f - 0.715f * amount;
  matrix[2] = 1.f - (matrix[0] + matrix[1]);
  matrix[3] = matrix[4] = 0;
  matrix[5] = 0.213f - 0.213f * amount;
  matrix[6] = 0.715f + 0.285f * amount;
  matrix[7] = 1.f - (matrix[5] + matrix[6]);
  matrix[8] = matrix[9] = 0;
  matrix[10] = 0.213f - 0.213f * amount;
  matrix[11] = 0.715f - 0.715f * amount;
  matrix[12] = 1.f - (matrix[10] + matrix[11]);
  matrix[13] = matrix[14] = 0;
  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
  matrix[18] = 1;
  skia::RefPtr<SkColorFilter> colorFilter(
      skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
  skia::RefPtr<SkImageFilter> filter =
      skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
  FilterOperations filters;
  filters.Append(FilterOperation::CreateReferenceFilter(filter));

  RenderPassDrawQuad* render_pass_quad =
      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  render_pass_quad->SetNew(pass_shared_state,
                           pass_rect,
                           pass_rect,
                           child_pass_id,
                           0,
                           gfx::Vector2dF(),
                           gfx::Size(),
                           filters,
                           gfx::Vector2dF(),
                           FilterOperations());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
  // renderer so use a fuzzy comparator.
  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
      FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
}

TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());
  shared_state->opacity = 0.5f;

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* blank_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  SolidColorDrawQuad* white =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  white->SetNew(
      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());

  FilterOperations filters;
  filters.Append(FilterOperation::CreateSaturateFilter(0.5f));

  RenderPassDrawQuad* render_pass_quad =
      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  render_pass_quad->SetNew(pass_shared_state,
                           pass_rect,
                           pass_rect,
                           child_pass_id,
                           0,
                           gfx::Vector2dF(),
                           gfx::Size(),
                           filters,
                           gfx::Vector2dF(),
                           FilterOperations());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());
  shared_state->opacity = 0.5f;

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* blank_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  SolidColorDrawQuad* white =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  white->SetNew(
      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());

  FilterOperations filters;
  filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
  filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));

  RenderPassDrawQuad* render_pass_quad =
      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  render_pass_quad->SetNew(pass_shared_state,
                           pass_rect,
                           pass_rect,
                           child_pass_id,
                           0,
                           gfx::Vector2dF(),
                           gfx::Size(),
                           filters,
                           gfx::Vector2dF(),
                           FilterOperations());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());
  shared_state->opacity = 0.5f;

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* blank_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  SolidColorDrawQuad* white =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  white->SetNew(
      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());

  SkScalar matrix[20];
  float amount = 0.5f;
  matrix[0] = 0.213f + 0.787f * amount;
  matrix[1] = 0.715f - 0.715f * amount;
  matrix[2] = 1.f - (matrix[0] + matrix[1]);
  matrix[3] = 0;
  matrix[4] = 20.f;
  matrix[5] = 0.213f - 0.213f * amount;
  matrix[6] = 0.715f + 0.285f * amount;
  matrix[7] = 1.f - (matrix[5] + matrix[6]);
  matrix[8] = 0;
  matrix[9] = 200.f;
  matrix[10] = 0.213f - 0.213f * amount;
  matrix[11] = 0.715f - 0.715f * amount;
  matrix[12] = 1.f - (matrix[10] + matrix[11]);
  matrix[13] = 0;
  matrix[14] = 1.5f;
  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
  matrix[18] = 1;
  skia::RefPtr<SkColorFilter> colorFilter(
      skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
  skia::RefPtr<SkImageFilter> filter =
      skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
  FilterOperations filters;
  filters.Append(FilterOperation::CreateReferenceFilter(filter));

  RenderPassDrawQuad* render_pass_quad =
      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  render_pass_quad->SetNew(pass_shared_state,
                           pass_rect,
                           pass_rect,
                           child_pass_id,
                           0,
                           gfx::Vector2dF(),
                           gfx::Size(),
                           filters,
                           gfx::Vector2dF(),
                           FilterOperations());

  RenderPassList pass_list;

  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
  // renderer so use a fuzzy comparator.
  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
      FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
}

TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  gfx::Transform aa_transform;
  aa_transform.Translate(0.5, 0.0);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());

  SharedQuadState* root_shared_state = CreateTestSharedQuadState(
      gfx::Transform(), viewport_rect, root_pass.get());
  SolidColorDrawQuad* background =
      root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  background->SetNew(root_shared_state,
                     gfx::Rect(this->device_viewport_size_),
                     gfx::Rect(this->device_viewport_size_),
                     SK_ColorWHITE,
                     false);

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
      FuzzyPixelOffByOneComparator(true)));
}

// This tests the case where we have a RenderPass with a mask, but the quad
// for the masked surface does not include the full surface texture.
TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);
  SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
      gfx::Transform(), viewport_rect, root_pass.get());

  RenderPassId child_pass_id(2, 2);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
  SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
      gfx::Transform(), viewport_rect, child_pass.get());

  // The child render pass is just a green box.
  static const SkColor kCSSGreen = 0xff008000;
  SolidColorDrawQuad* green =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  green->SetNew(
      child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);

  // Make a mask.
  gfx::Rect mask_rect = viewport_rect;
  SkBitmap bitmap;
  bitmap.allocPixels(
      SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
  SkCanvas canvas(bitmap);
  SkPaint paint;
  paint.setStyle(SkPaint::kStroke_Style);
  paint.setStrokeWidth(SkIntToScalar(4));
  paint.setColor(SK_ColorWHITE);
  canvas.clear(SK_ColorTRANSPARENT);
  gfx::Rect rect = mask_rect;
  while (!rect.IsEmpty()) {
    rect.Inset(6, 6, 4, 4);
    canvas.drawRect(
        SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
        paint);
    rect.Inset(6, 6, 4, 4);
  }

  ResourceProvider::ResourceId mask_resource_id =
      this->resource_provider_->CreateResource(
          mask_rect.size(), GL_CLAMP_TO_EDGE,
          ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
  {
    SkAutoLockPixels lock(bitmap);
    this->resource_provider_->CopyToResource(
        mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
        mask_rect.size());
  }

  // This RenderPassDrawQuad does not include the full |viewport_rect| which is
  // the size of the child render pass.
  gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
  EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
  EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
  EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
  EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());

  // Set up a mask on the RenderPassDrawQuad.
  RenderPassDrawQuad* mask_quad =
      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
  mask_quad->SetNew(root_pass_shared_state,
                    sub_rect,
                    sub_rect,
                    child_pass_id,
                    mask_resource_id,
                    gfx::Vector2dF(2.f, 1.f),     // mask_uv_scale
                    gfx::Size(mask_rect.size()),  // mask_texture_size
                    FilterOperations(),           // foreground filters
                    gfx::Vector2dF(),             // filters scale
                    FilterOperations());          // background filters

  // White background behind the masked render pass.
  SolidColorDrawQuad* white =
      root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  white->SetNew(root_pass_shared_state,
                viewport_rect,
                viewport_rect,
                SK_ColorWHITE,
                false);

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
      ExactPixelComparator(true)));
}

template <typename RendererType>
class RendererPixelTestWithBackgroundFilter
    : public RendererPixelTest<RendererType> {
 protected:
  void SetUpRenderPassList() {
    gfx::Rect device_viewport_rect(this->device_viewport_size_);

    RenderPassId root_id(1, 1);
    scoped_ptr<RenderPass> root_pass =
        CreateTestRootRenderPass(root_id, device_viewport_rect);
    root_pass->has_transparent_background = false;

    gfx::Transform identity_content_to_target_transform;

    RenderPassId filter_pass_id(2, 1);
    gfx::Transform transform_to_root;
    scoped_ptr<RenderPass> filter_pass =
        CreateTestRenderPass(filter_pass_id,
                             filter_pass_content_rect_,
                             transform_to_root);

    // A non-visible quad in the filtering render pass.
    {
      SharedQuadState* shared_state =
          CreateTestSharedQuadState(identity_content_to_target_transform,
                                    filter_pass_content_rect_,
                                    filter_pass.get());
      SolidColorDrawQuad* color_quad =
          filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(shared_state,
                         filter_pass_content_rect_,
                         filter_pass_content_rect_,
                         SK_ColorTRANSPARENT,
                         false);
    }

    {
      SharedQuadState* shared_state =
          CreateTestSharedQuadState(filter_pass_to_target_transform_,
                                    filter_pass_content_rect_,
                                    filter_pass.get());
      RenderPassDrawQuad* filter_pass_quad =
          root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
      filter_pass_quad->SetNew(shared_state,
                               filter_pass_content_rect_,
                               filter_pass_content_rect_,
                               filter_pass_id,
                               0,                   // mask_resource_id
                               gfx::Vector2dF(),    // mask_uv_scale
                               gfx::Size(),         // mask_texture_size
                               FilterOperations(),  // filters
                               gfx::Vector2dF(),    // filters_scale
                               this->background_filters_);
    }

    const int kColumnWidth = device_viewport_rect.width() / 3;

    gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
    for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
      SharedQuadState* shared_state = CreateTestSharedQuadState(
          identity_content_to_target_transform, left_rect, root_pass.get());
      SolidColorDrawQuad* color_quad =
          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(
          shared_state, left_rect, left_rect, SK_ColorGREEN, false);
      left_rect += gfx::Vector2d(0, left_rect.height() + 1);
    }

    gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
    for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
      SharedQuadState* shared_state = CreateTestSharedQuadState(
          identity_content_to_target_transform, middle_rect, root_pass.get());
      SolidColorDrawQuad* color_quad =
          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(
          shared_state, middle_rect, middle_rect, SK_ColorRED, false);
      middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
    }

    gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
    for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
      SharedQuadState* shared_state = CreateTestSharedQuadState(
          identity_content_to_target_transform, right_rect, root_pass.get());
      SolidColorDrawQuad* color_quad =
          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(
          shared_state, right_rect, right_rect, SK_ColorBLUE, false);
      right_rect += gfx::Vector2d(0, right_rect.height() + 1);
    }

    SharedQuadState* shared_state =
        CreateTestSharedQuadState(identity_content_to_target_transform,
                                  device_viewport_rect,
                                  root_pass.get());
    SolidColorDrawQuad* background_quad =
        root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    background_quad->SetNew(shared_state,
                            device_viewport_rect,
                            device_viewport_rect,
                            SK_ColorWHITE,
                            false);

    pass_list_.push_back(filter_pass.Pass());
    pass_list_.push_back(root_pass.Pass());
  }

  RenderPassList pass_list_;
  FilterOperations background_filters_;
  gfx::Transform filter_pass_to_target_transform_;
  gfx::Rect filter_pass_content_rect_;
};

typedef ::testing::Types<GLRenderer, SoftwareRenderer>
    BackgroundFilterRendererTypes;
TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
                BackgroundFilterRendererTypes);

typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
GLRendererPixelTestWithBackgroundFilter;

// TODO(skaslev): The software renderer does not support filters yet.
TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
  this->background_filters_.Append(
      FilterOperation::CreateInvertFilter(1.f));

  this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
  this->filter_pass_content_rect_.Inset(12, 14, 16, 18);

  this->SetUpRenderPassList();
  EXPECT_TRUE(this->RunPixelTest(
      &this->pass_list_,
      base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
      ExactPixelComparator(true)));
}

class ExternalStencilPixelTest : public GLRendererPixelTest {
 protected:
  void ClearBackgroundToGreen() {
    GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
    output_surface_->EnsureBackbuffer();
    output_surface_->Reshape(device_viewport_size_, 1);
    gl->ClearColor(0.f, 1.f, 0.f, 1.f);
    gl->Clear(GL_COLOR_BUFFER_BIT);
  }

  void PopulateStencilBuffer() {
    // Set two quadrants of the stencil buffer to 1.
    GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
    output_surface_->EnsureBackbuffer();
    output_surface_->Reshape(device_viewport_size_, 1);
    gl->ClearStencil(0);
    gl->Clear(GL_STENCIL_BUFFER_BIT);
    gl->Enable(GL_SCISSOR_TEST);
    gl->ClearStencil(1);
    gl->Scissor(0,
                0,
                device_viewport_size_.width() / 2,
                device_viewport_size_.height() / 2);
    gl->Clear(GL_STENCIL_BUFFER_BIT);
    gl->Scissor(device_viewport_size_.width() / 2,
                device_viewport_size_.height() / 2,
                device_viewport_size_.width(),
                device_viewport_size_.height());
    gl->Clear(GL_STENCIL_BUFFER_BIT);
  }
};

TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
  ClearBackgroundToGreen();
  PopulateStencilBuffer();
  this->EnableExternalStencilTest();

  // Draw a blue quad that covers the entire device viewport. It should be
  // clipped to the bottom left and top right corners by the external stencil.
  gfx::Rect rect(this->device_viewport_size_);
  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
  SharedQuadState* blue_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* blue =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
  pass->has_transparent_background = false;
  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
  PopulateStencilBuffer();

  // Draw a green quad that covers the entire device viewport. The stencil
  // buffer should be ignored.
  gfx::Rect rect(this->device_viewport_size_);
  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
  SharedQuadState* green_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* green =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green.png")),
      ExactPixelComparator(true)));
}

TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
  // The stencil test should apply only to the final render pass.
  ClearBackgroundToGreen();
  PopulateStencilBuffer();
  this->EnableExternalStencilTest();

  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);
  root_pass->has_transparent_background = false;

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height());
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

TEST_F(ExternalStencilPixelTest, DeviceClip) {
  ClearBackgroundToGreen();
  gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
  this->ForceDeviceClip(clip_rect);

  // Draw a blue quad that covers the entire device viewport. It should be
  // clipped to the bottom right corner by the device clip.
  gfx::Rect rect(this->device_viewport_size_);
  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
  SharedQuadState* blue_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* blue =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
      ExactPixelComparator(true)));
}

// Software renderer does not support anti-aliased edges.
TEST_F(GLRendererPixelTest, AntiAliasing) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  gfx::Transform red_content_to_target_transform;
  red_content_to_target_transform.Rotate(10);
  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
      red_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);

  gfx::Transform yellow_content_to_target_transform;
  yellow_content_to_target_transform.Rotate(5);
  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
      yellow_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* yellow =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);

  gfx::Transform blue_content_to_target_transform;
  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
      blue_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* blue =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
      FuzzyPixelOffByOneComparator(true)));
}

// This test tests that anti-aliasing works for axis aligned quads.
// Anti-aliasing is only supported in the gl renderer.
TEST_F(GLRendererPixelTest, AxisAligned) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, rect, transform_to_root);

  gfx::Transform red_content_to_target_transform;
  red_content_to_target_transform.Translate(50, 50);
  red_content_to_target_transform.Scale(
      0.5f + 1.0f / (rect.width() * 2.0f),
      0.5f + 1.0f / (rect.height() * 2.0f));
  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
      red_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);

  gfx::Transform yellow_content_to_target_transform;
  yellow_content_to_target_transform.Translate(25.5f, 25.5f);
  yellow_content_to_target_transform.Scale(0.5f, 0.5f);
  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
      yellow_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* yellow =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);

  gfx::Transform blue_content_to_target_transform;
  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
      blue_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* blue =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
      ExactPixelComparator(true)));
}

// This test tests that forcing anti-aliasing off works as expected.
// Anti-aliasing is only supported in the gl renderer.
TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, rect, transform_to_root);

  gfx::Transform hole_content_to_target_transform;
  hole_content_to_target_transform.Translate(50, 50);
  hole_content_to_target_transform.Scale(
      0.5f + 1.0f / (rect.width() * 2.0f),
      0.5f + 1.0f / (rect.height() * 2.0f));
  SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
      hole_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* hole =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  hole->SetAll(
      hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);

  gfx::Transform green_content_to_target_transform;
  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
      green_content_to_target_transform, rect, pass.get());

  SolidColorDrawQuad* green =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
      ExactPixelComparator(false)));
}

TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
  gfx::Rect rect(this->device_viewport_size_);

  scoped_ptr<RenderPass> pass =
      CreateTestRootRenderPass(RenderPassId(1, 1), rect);

  gfx::Rect red_rect(0, 0, 180, 500);
  gfx::Transform red_content_to_target_transform(
      1.0f,  2.4520f,  10.6206f, 19.0f,
      0.0f,  0.3528f,  5.9737f,  9.5f,
      0.0f, -0.2250f, -0.9744f,  0.0f,
      0.0f,  0.0225f,  0.0974f,  1.0f);
  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
      red_content_to_target_transform, red_rect, pass.get());
  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);

  gfx::Rect green_rect(19, 7, 180, 10);
  SharedQuadState* green_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
  SolidColorDrawQuad* green =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  green->SetNew(
      green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);

  SharedQuadState* blue_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
  SolidColorDrawQuad* blue =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
      FuzzyPixelOffByOneComparator(true)));
}

TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
  gfx::Size pile_tile_size(1000, 1000);
  gfx::Rect viewport(this->device_viewport_size_);
  // TODO(enne): the renderer should figure this out on its own.
  ResourceFormat texture_format = RGBA_8888;
  bool nearest_neighbor = false;

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  // One clipped blue quad in the lower right corner.  Outside the clip
  // is red, which should not appear.
  gfx::Rect blue_rect(gfx::Size(100, 100));
  gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));

  scoped_ptr<FakePicturePile> blue_recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
  SkPaint red_paint;
  red_paint.setColor(SK_ColorRED);
  blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
  SkPaint blue_paint;
  blue_paint.setColor(SK_ColorBLUE);
  blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
  blue_recording->RerecordPile();

  scoped_refptr<FakePicturePileImpl> blue_pile =
      FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);

  gfx::Transform blue_content_to_target_transform;
  gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
  blue_content_to_target_transform.Translate(offset.x(), offset.y());
  gfx::RectF blue_scissor_rect = blue_clip_rect;
  blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
  SharedQuadState* blue_shared_state =
      CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
                                       blue_rect,
                                       gfx::ToEnclosingRect(blue_scissor_rect),
                                       pass.get());

  PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();

  blue_quad->SetNew(blue_shared_state,
                    viewport,  // Intentionally bigger than clip.
                    gfx::Rect(), viewport, gfx::RectF(viewport),
                    viewport.size(), nearest_neighbor, texture_format, viewport,
                    1.f, blue_pile.get());

  // One viewport-filling green quad.
  scoped_ptr<FakePicturePile> green_recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
  SkPaint green_paint;
  green_paint.setColor(SK_ColorGREEN);
  green_recording->add_draw_rect_with_paint(viewport, green_paint);
  green_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> green_pile =
      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);

  gfx::Transform green_content_to_target_transform;
  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
      green_content_to_target_transform, viewport, pass.get());

  PictureDrawQuad* green_quad =
      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
                     gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
                     nearest_neighbor, texture_format, viewport, 1.f,
                     green_pile.get());

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
      ExactPixelComparator(true)));
}

// Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
  gfx::Size pile_tile_size(1000, 1000);
  gfx::Rect viewport(this->device_viewport_size_);
  ResourceFormat texture_format = RGBA_8888;
  bool nearest_neighbor = false;

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  // One viewport-filling 0.5-opacity green quad.
  scoped_ptr<FakePicturePile> green_recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
  SkPaint green_paint;
  green_paint.setColor(SK_ColorGREEN);
  green_recording->add_draw_rect_with_paint(viewport, green_paint);
  green_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> green_pile =
      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);

  gfx::Transform green_content_to_target_transform;
  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
      green_content_to_target_transform, viewport, pass.get());
  green_shared_state->opacity = 0.5f;

  PictureDrawQuad* green_quad =
      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
                     gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
                     texture_format, viewport, 1.f, green_pile.get());

  // One viewport-filling white quad.
  scoped_ptr<FakePicturePile> white_recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
  SkPaint white_paint;
  white_paint.setColor(SK_ColorWHITE);
  white_recording->add_draw_rect_with_paint(viewport, white_paint);
  white_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> white_pile =
      FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);

  gfx::Transform white_content_to_target_transform;
  SharedQuadState* white_shared_state = CreateTestSharedQuadState(
      white_content_to_target_transform, viewport, pass.get());

  PictureDrawQuad* white_quad =
      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
                     gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
                     texture_format, viewport, 1.f, white_pile.get());

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
      FuzzyPixelOffByOneComparator(true)));
}

template<typename TypeParam> bool IsSoftwareRenderer() {
  return false;
}

template<>
bool IsSoftwareRenderer<SoftwareRenderer>() {
  return true;
}

template<>
bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
  return true;
}

// If we disable image filtering, then a 2x2 bitmap should appear as four
// huge sharp squares.
TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
  // We only care about this in software mode since bilinear filtering is
  // cheap in hardware.
  if (!IsSoftwareRenderer<TypeParam>())
    return;

  gfx::Size pile_tile_size(1000, 1000);
  gfx::Rect viewport(this->device_viewport_size_);
  ResourceFormat texture_format = RGBA_8888;
  bool nearest_neighbor = false;

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  SkBitmap bitmap;
  bitmap.allocN32Pixels(2, 2);
  {
    SkAutoLockPixels lock(bitmap);
    SkCanvas canvas(bitmap);
    canvas.drawPoint(0, 0, SK_ColorGREEN);
    canvas.drawPoint(0, 1, SK_ColorBLUE);
    canvas.drawPoint(1, 0, SK_ColorBLUE);
    canvas.drawPoint(1, 1, SK_ColorGREEN);
  }

  scoped_ptr<FakePicturePile> recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
  SkPaint paint;
  paint.setFilterLevel(SkPaint::kLow_FilterLevel);
  recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
  recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> pile =
      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport, pass.get());

  PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
               gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
               texture_format, viewport, 1.f, pile.get());

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  this->disable_picture_quad_image_filtering_ = true;

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

// This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
  gfx::Size pile_tile_size(1000, 1000);
  gfx::Rect viewport(this->device_viewport_size_);
  ResourceFormat texture_format = RGBA_8888;
  bool nearest_neighbor = true;

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  SkBitmap bitmap;
  bitmap.allocN32Pixels(2, 2);
  {
    SkAutoLockPixels lock(bitmap);
    SkCanvas canvas(bitmap);
    canvas.drawPoint(0, 0, SK_ColorGREEN);
    canvas.drawPoint(0, 1, SK_ColorBLUE);
    canvas.drawPoint(1, 0, SK_ColorBLUE);
    canvas.drawPoint(1, 1, SK_ColorGREEN);
  }

  scoped_ptr<FakePicturePile> recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
  SkPaint paint;
  paint.setFilterLevel(SkPaint::kLow_FilterLevel);
  recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
  recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> pile =
      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport, pass.get());

  PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
               gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
               texture_format, viewport, 1.f, pile.get());

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

// This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
  gfx::Rect viewport(this->device_viewport_size_);
  bool swizzle_contents = true;
  bool nearest_neighbor = true;

  SkBitmap bitmap;
  bitmap.allocN32Pixels(2, 2);
  {
    SkAutoLockPixels lock(bitmap);
    SkCanvas canvas(bitmap);
    canvas.drawPoint(0, 0, SK_ColorGREEN);
    canvas.drawPoint(0, 1, SK_ColorBLUE);
    canvas.drawPoint(1, 0, SK_ColorBLUE);
    canvas.drawPoint(1, 1, SK_ColorGREEN);
  }

  gfx::Size tile_size(2, 2);
  ResourceProvider::ResourceId resource =
      this->resource_provider_->CreateResource(
          tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
          RGBA_8888);

  {
    SkAutoLockPixels lock(bitmap);
    this->resource_provider_->CopyToResource(
        resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
  }

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport, pass.get());

  TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
               gfx::Rect(tile_size), tile_size, swizzle_contents,
               nearest_neighbor);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
  gfx::Size pile_tile_size(1000, 1000);
  gfx::Rect viewport(this->device_viewport_size_);
  // TODO(enne): the renderer should figure this out on its own.
  ResourceFormat texture_format = RGBA_8888;
  bool nearest_neighbor = false;

  RenderPassId id(1, 1);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> pass =
      CreateTestRenderPass(id, viewport, transform_to_root);

  // As scaling up the blue checkerboards will cause sampling on the GPU,
  // a few extra "cleanup rects" need to be added to clobber the blending
  // to make the output image more clean.  This will also test subrects
  // of the layer.
  gfx::Transform green_content_to_target_transform;
  gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
  gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));

  scoped_ptr<FakePicturePile> green_recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());

  SkPaint red_paint;
  red_paint.setColor(SK_ColorRED);
  green_recording->add_draw_rect_with_paint(viewport, red_paint);
  SkPaint green_paint;
  green_paint.setColor(SK_ColorGREEN);
  green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
  green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
  green_recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> green_pile =
      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);

  SharedQuadState* top_right_green_shared_quad_state =
      CreateTestSharedQuadState(
          green_content_to_target_transform, viewport, pass.get());

  PictureDrawQuad* green_quad1 =
      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
                      gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
                      green_rect1.size(), nearest_neighbor, texture_format,
                      green_rect1, 1.f, green_pile.get());

  PictureDrawQuad* green_quad2 =
      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
                      gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
                      green_rect2.size(), nearest_neighbor, texture_format,
                      green_rect2, 1.f, green_pile.get());

  // Add a green clipped checkerboard in the bottom right to help test
  // interleaving picture quad content and solid color content.
  gfx::Rect bottom_right_rect(
      gfx::Point(viewport.width() / 2, viewport.height() / 2),
      gfx::Size(viewport.width() / 2, viewport.height() / 2));
  SharedQuadState* bottom_right_green_shared_state =
      CreateTestSharedQuadStateClipped(green_content_to_target_transform,
                                       viewport,
                                       bottom_right_rect,
                                       pass.get());
  SolidColorDrawQuad* bottom_right_color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
                                  viewport,
                                  viewport,
                                  SK_ColorGREEN,
                                  false);

  // Add two blue checkerboards taking up the bottom left and top right,
  // but use content scales as content rects to make this happen.
  // The content is at a 4x content scale.
  gfx::Rect layer_rect(gfx::Size(20, 30));
  float contents_scale = 4.f;
  // Two rects that touch at their corners, arbitrarily placed in the layer.
  gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
  gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
  gfx::RectF union_layer_rect = blue_layer_rect1;
  union_layer_rect.Union(blue_layer_rect2);

  // Because scaling up will cause sampling outside the rects, add one extra
  // pixel of buffer at the final content scale.
  float inset = -1.f / contents_scale;
  blue_layer_rect1.Inset(inset, inset, inset, inset);
  blue_layer_rect2.Inset(inset, inset, inset, inset);

  scoped_ptr<FakePicturePile> recording =
      FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());

  Region outside(layer_rect);
  outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
  for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
    recording->add_draw_rect_with_paint(iter.rect(), red_paint);
  }

  SkPaint blue_paint;
  blue_paint.setColor(SK_ColorBLUE);
  recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
  recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
  recording->RerecordPile();
  scoped_refptr<FakePicturePileImpl> pile =
      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);

  gfx::Rect content_rect(
      gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
  gfx::Rect content_union_rect(
      gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));

  // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
  // so scale an additional 10x to make them 100x100.
  gfx::Transform content_to_target_transform;
  content_to_target_transform.Scale(10.0, 10.0);
  gfx::Rect quad_content_rect(gfx::Size(20, 20));
  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
      content_to_target_transform, quad_content_rect, pass.get());

  PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
  blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
                    quad_content_rect, gfx::RectF(quad_content_rect),
                    content_union_rect.size(), nearest_neighbor, texture_format,
                    content_union_rect, contents_scale, pile.get());

  // Fill left half of viewport with green.
  gfx::Transform half_green_content_to_target_transform;
  gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
  SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
      half_green_content_to_target_transform, half_green_rect, pass.get());
  SolidColorDrawQuad* half_color_quad =
      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  half_color_quad->SetNew(half_green_shared_state,
                          half_green_rect,
                          half_green_rect,
                          SK_ColorGREEN,
                          false);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
      ExactPixelComparator(true)));
}

typedef RendererPixelTest<GLRendererWithFlippedSurface>
    GLRendererPixelTestWithFlippedOutputSurface;

TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
  // This draws a blue rect above a yellow rect with an inverted output surface.
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
      ExactPixelComparator(true)));
}

TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
  // This draws a blue rect above a yellow rect with an inverted output surface.
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  gfx::Rect blue_rect(0,
                      0,
                      this->device_viewport_size_.width(),
                      this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect yellow_rect(0,
                        this->device_viewport_size_.height() / 2,
                        this->device_viewport_size_.width(),
                        this->device_viewport_size_.height() / 2);
  SolidColorDrawQuad* yellow =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  // Check that the child pass remains unflipped.
  EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
      &pass_list,
      pass_list.front(),
      base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
      ExactPixelComparator(true)));
}

TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
  gfx::Rect viewport_rect(this->device_viewport_size_);

  RenderPassId root_pass_id(1, 1);
  scoped_ptr<RenderPass> root_pass =
      CreateTestRootRenderPass(root_pass_id, viewport_rect);

  RenderPassId child_pass_id(2, 2);
  gfx::Rect pass_rect(this->device_viewport_size_);
  gfx::Transform transform_to_root;
  scoped_ptr<RenderPass> child_pass =
      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);

  gfx::Transform content_to_target_transform;
  SharedQuadState* shared_state = CreateTestSharedQuadState(
      content_to_target_transform, viewport_rect, child_pass.get());

  // Draw a green quad full-size with a blue quad in the lower-right corner.
  gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
                      this->device_viewport_size_.height() * 3 / 4,
                      this->device_viewport_size_.width() * 3 / 4,
                      this->device_viewport_size_.height() * 3 / 4);
  SolidColorDrawQuad* blue =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
  gfx::Rect green_rect(0,
                       0,
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height());
  SolidColorDrawQuad* green =
      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);

  SharedQuadState* pass_shared_state =
      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
  CreateTestRenderPassDrawQuad(
      pass_shared_state, pass_rect, child_pass_id, root_pass.get());

  RenderPassList pass_list;
  pass_list.push_back(child_pass.Pass());
  pass_list.push_back(root_pass.Pass());

  // Check that the child pass remains unflipped.
  gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width() / 2,
                         this->device_viewport_size_.height() / 2);
  EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
      &pass_list,
      pass_list.front(),
      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
      ExactPixelComparator(true),
      &capture_rect));
}

TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());

  gfx::Size texture_size(4, 4);
  SkPMColor colors[4] = {
    SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
    SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
    SkPreMultiplyColor(SkColorSetARGB(255, 0,  64, 0)),
    SkPreMultiplyColor(SkColorSetARGB(255, 0,   0, 0)),
  };
  uint32_t pixels[16] = {
    colors[0], colors[0], colors[1], colors[1],
    colors[0], colors[0], colors[1], colors[1],
    colors[2], colors[2], colors[3], colors[3],
    colors[2], colors[2], colors[3], colors[3],
  };
  ResourceProvider::ResourceId resource =
      this->resource_provider_->CreateResource(
          texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
          RGBA_8888);
  this->resource_provider_->CopyToResource(
      resource, reinterpret_cast<uint8_t*>(pixels), texture_size);

  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
  TextureDrawQuad* texture_quad =
      pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
  texture_quad->SetNew(
      shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
      gfx::Rect(this->device_viewport_size_), resource,
      true,                     // premultiplied_alpha
      gfx::PointF(0.0f, 0.0f),  // uv_top_left
      gfx::PointF(              // uv_bottom_right
          this->device_viewport_size_.width() / texture_size.width(),
          this->device_viewport_size_.height() / texture_size.height()),
      SK_ColorWHITE, vertex_opacity,
      false,   // flipped
      false);  // nearest_neighbor

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  EXPECT_TRUE(this->RunPixelTest(
      &pass_list,
      base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
      FuzzyPixelOffByOneComparator(true)));
}

TYPED_TEST(RendererPixelTest, Checkerboards) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());

  // The color's alpha value is not used.
  SkColor color1 = SK_ColorGREEN;
  color1 = SkColorSetA(color1, 0);
  SkColor color2 = SK_ColorBLUE;
  color2 = SkColorSetA(color2, 0);

  gfx::Rect content_rect(rect);

  gfx::Rect top_left(content_rect);
  gfx::Rect top_right(content_rect);
  gfx::Rect bottom_left(content_rect);
  gfx::Rect bottom_right(content_rect);
  // The format is Inset(left, top, right, bottom).
  top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
  top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
  bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
  bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);

  // Appends checkerboard quads with a scale of 1.
  CheckerboardDrawQuad* quad =
      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, top_left, top_left, color1, 1.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, top_right, top_right, color2, 1.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  base::FilePath::StringType path =
      IsSoftwareRenderer<TypeParam>()
          ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
          : FILE_PATH_LITERAL("checkers.png");
  EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
                                 ExactPixelComparator(true)));
}

TYPED_TEST(RendererPixelTest, CheckerboardsScaled) {
  gfx::Rect rect(this->device_viewport_size_);

  RenderPassId id(1, 1);
  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);

  gfx::Transform scale;
  scale.Scale(2.f, 2.f);

  SharedQuadState* shared_state =
      CreateTestSharedQuadState(scale, rect, pass.get());

  // The color's alpha value is not used.
  SkColor color1 = SK_ColorGREEN;
  color1 = SkColorSetA(color1, 0);
  SkColor color2 = SK_ColorBLUE;
  color2 = SkColorSetA(color2, 0);

  gfx::Rect content_rect(rect);
  content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2);

  gfx::Rect top_left(content_rect);
  gfx::Rect top_right(content_rect);
  gfx::Rect bottom_left(content_rect);
  gfx::Rect bottom_right(content_rect);
  // The format is Inset(left, top, right, bottom).
  top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
  top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
  bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
  bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);

  // Appends checkerboard quads with a scale of 2, and a shared quad state
  // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
  CheckerboardDrawQuad* quad =
      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, top_left, top_left, color1, 2.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, top_right, top_right, color2, 2.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f);
  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
  quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f);

  RenderPassList pass_list;
  pass_list.push_back(pass.Pass());

  base::FilePath::StringType path =
      IsSoftwareRenderer<TypeParam>()
          ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
          : FILE_PATH_LITERAL("checkers_big.png");
  EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
                                 ExactPixelComparator(true)));
}

#endif  // !defined(OS_ANDROID)

}  // namespace
}  // namespace cc
