// 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 "cc/layers/delegated_renderer_layer_impl.h"

#include "cc/base/scoped_ptr_vector.h"
#include "cc/layers/solid_color_layer_impl.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/test/fake_delegated_renderer_layer_impl.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_layer_tree_host_impl_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

class DelegatedRendererLayerImplTest : public testing::Test {
 public:
  DelegatedRendererLayerImplTest()
      : proxy_(),
        always_impl_thread_and_main_thread_blocked_(&proxy_) {
    LayerTreeSettings settings;
    settings.minimum_occlusion_tracking_size = gfx::Size();

    host_impl_.reset(new FakeLayerTreeHostImpl(
        settings, &proxy_, &shared_bitmap_manager_, &task_graph_runner_));
    host_impl_->InitializeRenderer(FakeOutputSurface::Create3d());
    host_impl_->SetViewportSize(gfx::Size(10, 10));
  }

 protected:
  FakeImplProxy proxy_;
  DebugScopedSetImplThreadAndMainThreadBlocked
      always_impl_thread_and_main_thread_blocked_;
  TestSharedBitmapManager shared_bitmap_manager_;
  TestTaskGraphRunner task_graph_runner_;
  scoped_ptr<LayerTreeHostImpl> host_impl_;
};

class DelegatedRendererLayerImplTestSimple
    : public DelegatedRendererLayerImplTest {
 public:
  DelegatedRendererLayerImplTestSimple()
      : DelegatedRendererLayerImplTest() {
    scoped_ptr<LayerImpl> root_layer =
        SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
    scoped_ptr<LayerImpl> layer_before =
        SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
    scoped_ptr<LayerImpl> layer_after =
        SolidColorLayerImpl::Create(host_impl_->active_tree(), 3);
    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 4);

    host_impl_->SetViewportSize(gfx::Size(100, 100));
    root_layer->SetBounds(gfx::Size(100, 100));
    root_layer->SetHasRenderSurface(true);

    layer_before->SetPosition(gfx::Point(20, 20));
    layer_before->SetBounds(gfx::Size(14, 14));
    layer_before->SetContentBounds(gfx::Size(14, 14));
    layer_before->SetDrawsContent(true);
    layer_before->SetHasRenderSurface(true);

    layer_after->SetPosition(gfx::Point(5, 5));
    layer_after->SetBounds(gfx::Size(15, 15));
    layer_after->SetContentBounds(gfx::Size(15, 15));
    layer_after->SetDrawsContent(true);
    layer_after->SetHasRenderSurface(true);

    delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
    delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetDrawsContent(true);
    gfx::Transform transform;
    transform.Translate(1.0, 1.0);
    delegated_renderer_layer->SetTransform(transform);

    RenderPassList delegated_render_passes;
    TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
                                          RenderPassId(9, 6),
                                          gfx::Rect(6, 6, 6, 6),
                                          gfx::Transform(1, 0, 0, 1, 5, 6));
    AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
    TestRenderPass* pass2 = AddRenderPass(&delegated_render_passes,
                                          RenderPassId(9, 7),
                                          gfx::Rect(7, 7, 7, 7),
                                          gfx::Transform(1, 0, 0, 1, 7, 8));
    AddQuad(pass2, gfx::Rect(0, 0, 7, 7), 22u);
    AddRenderPassQuad(pass2, pass1);
    TestRenderPass* pass3 = AddRenderPass(&delegated_render_passes,
                                          RenderPassId(9, 8),
                                          gfx::Rect(0, 0, 8, 8),
                                          gfx::Transform(1, 0, 0, 1, 9, 10));
    AddRenderPassQuad(pass3, pass2);
    delegated_renderer_layer->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    root_layer_ = root_layer.get();
    layer_before_ = layer_before.get();
    layer_after_ = layer_after.get();
    delegated_renderer_layer_ = delegated_renderer_layer.get();

    // Force the delegated RenderPasses to come before the RenderPass from
    // layer_after.
    layer_after->AddChild(delegated_renderer_layer.Pass());
    root_layer->AddChild(layer_after.Pass());

    // Get the RenderPass generated by layer_before to come before the delegated
    // RenderPasses.
    root_layer->AddChild(layer_before.Pass());
    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
  }

 protected:
  LayerImpl* root_layer_;
  LayerImpl* layer_before_;
  LayerImpl* layer_after_;
  DelegatedRendererLayerImpl* delegated_renderer_layer_;
};

TEST_F(DelegatedRendererLayerImplTest,
       ChangeContributingRenderPassForNewFrame) {
  FakeDelegatedRendererLayerImpl* fake_delegated_renderer_layer_impl;
  {
    scoped_ptr<LayerImpl> root_layer =
        SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 2);

    host_impl_->SetViewportSize(gfx::Size(100, 100));
    root_layer->SetBounds(gfx::Size(100, 100));
    root_layer->SetHasRenderSurface(true);

    delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
    delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetDrawsContent(true);
    delegated_renderer_layer->SetHasRenderSurface(true);
    gfx::Transform transform;
    transform.Translate(1.0, 1.0);
    delegated_renderer_layer->SetTransform(transform);

    RenderPassList delegated_render_passes;
    TestRenderPass* pass1 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 6),
                      gfx::Rect(6, 6, 6, 6), gfx::Transform(1, 0, 0, 1, 5, 6));
    AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
    TestRenderPass* pass2 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 7),
                      gfx::Rect(7, 7, 7, 7), gfx::Transform(1, 0, 0, 1, 7, 8));
    AddQuad(pass2, gfx::Rect(0, 0, 7, 7), 22u);
    AddRenderPassQuad(pass2, pass1);
    TestRenderPass* pass3 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 8),
                      gfx::Rect(0, 0, 8, 8), gfx::Transform(1, 0, 0, 1, 9, 10));
    AddRenderPassQuad(pass3, pass2);
    delegated_renderer_layer->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    fake_delegated_renderer_layer_impl = delegated_renderer_layer.get();

    root_layer->AddChild(delegated_renderer_layer.Pass());

    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());

    LayerTreeHostImpl::FrameData frame;
    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

    // Root layer has one render pass, and delegated renderer layer has two
    // contributing render passes and its own render pass.
    ASSERT_EQ(4u, frame.render_passes.size());

    host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
    host_impl_->DidDrawAllLayers(frame);
  }
  {
    // New frame makes delegated renderer layer loses its contributing render
    // passes.
    RenderPassList delegated_render_passes;
    AddRenderPass(&delegated_render_passes, RenderPassId(9, 8),
                  gfx::Rect(0, 0, 8, 8), gfx::Transform(1, 0, 0, 1, 9, 10));
    fake_delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    // Force damage to redraw a new frame.
    host_impl_->SetViewportDamage(gfx::Rect(10, 10));

    LayerTreeHostImpl::FrameData frame;
    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

    // Each non-DelegatedRendererLayer added one RenderPass. The
    // DelegatedRendererLayer added two contributing passes.
    ASSERT_EQ(1u, frame.render_passes.size());

    host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
    host_impl_->DidDrawAllLayers(frame);
  }
}

TEST_F(DelegatedRendererLayerImplTest,
       ChangeContributingRenderPassNonFullTreeSync) {
  FakeDelegatedRendererLayerImpl* fake_delegated_renderer_layer_impl;
  {
    host_impl_->CreatePendingTree();
    scoped_ptr<LayerImpl> root_layer =
        SolidColorLayerImpl::Create(host_impl_->pending_tree(), 1);
    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
        FakeDelegatedRendererLayerImpl::Create(host_impl_->pending_tree(), 2);

    host_impl_->SetViewportSize(gfx::Size(100, 100));
    root_layer->SetBounds(gfx::Size(100, 100));
    root_layer->SetHasRenderSurface(true);

    delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
    delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
    delegated_renderer_layer->SetDrawsContent(true);
    delegated_renderer_layer->SetHasRenderSurface(true);
    gfx::Transform transform;
    transform.Translate(1.0, 1.0);
    delegated_renderer_layer->SetTransform(transform);

    RenderPassList delegated_render_passes;
    TestRenderPass* pass1 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 6),
                      gfx::Rect(6, 6, 6, 6), gfx::Transform(1, 0, 0, 1, 5, 6));
    AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
    TestRenderPass* pass2 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 7),
                      gfx::Rect(7, 7, 7, 7), gfx::Transform(1, 0, 0, 1, 7, 8));
    AddQuad(pass2, gfx::Rect(0, 0, 7, 7), 22u);
    AddRenderPassQuad(pass2, pass1);
    TestRenderPass* pass3 =
        AddRenderPass(&delegated_render_passes, RenderPassId(9, 8),
                      gfx::Rect(0, 0, 8, 8), gfx::Transform(1, 0, 0, 1, 9, 10));
    AddRenderPassQuad(pass3, pass2);
    delegated_renderer_layer->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    fake_delegated_renderer_layer_impl = delegated_renderer_layer.get();

    root_layer->AddChild(delegated_renderer_layer.Pass());

    host_impl_->pending_tree()->SetRootLayer(root_layer.Pass());
    host_impl_->ActivateSyncTree();

    LayerTreeHostImpl::FrameData frame;
    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

    // Root layer has one render pass, and delegated renderer layer has two
    // contributing render passes and its own render pass.
    ASSERT_EQ(4u, frame.render_passes.size());

    host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
    host_impl_->DidDrawAllLayers(frame);
  }
  {
    // Remove contributing render passes from the delegated renderer layer.
    host_impl_->CreatePendingTree();
    host_impl_->pending_tree()->set_needs_full_tree_sync(false);
    RenderPassList delegated_render_passes;
    AddRenderPass(&delegated_render_passes, RenderPassId(9, 8),
                  gfx::Rect(0, 0, 8, 8), gfx::Transform(1, 0, 0, 1, 9, 10));

    fake_delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    // Force damage to redraw a new frame.

    host_impl_->ActivateSyncTree();
    host_impl_->SetViewportDamage(gfx::Rect(100, 100));
    LayerTreeHostImpl::FrameData frame;
    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

    // Root layer has one render pass, and delegated renderer layer no longer
    // has contributing render passes.
    ASSERT_EQ(1u, frame.render_passes.size());

    host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
    host_impl_->DidDrawAllLayers(frame);
  }
}

TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes.
  ASSERT_EQ(5u, frame.render_passes.size());

  // The DelegatedRendererLayer should have added its contributing RenderPasses
  // to the frame.
  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
  EXPECT_EQ(1, frame.render_passes[1]->id.index);
  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
  EXPECT_EQ(2, frame.render_passes[2]->id.index);
  // And all other RenderPasses should be non-delegated.
  EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[0]->id.index);
  EXPECT_NE(4, frame.render_passes[3]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[3]->id.index);
  EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[4]->id.index);

  // The DelegatedRendererLayer should have added its RenderPasses to the frame
  // in order.
  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
            frame.render_passes[1]->output_rect.ToString());
  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
            frame.render_passes[2]->output_rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestSimple,
       AddsQuadsToContributingRenderPasses) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes.
  ASSERT_EQ(5u, frame.render_passes.size());

  // The DelegatedRendererLayer should have added its contributing RenderPasses
  // to the frame.
  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
  EXPECT_EQ(1, frame.render_passes[1]->id.index);
  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
  EXPECT_EQ(2, frame.render_passes[2]->id.index);

  // The DelegatedRendererLayer should have added copies of its quads to
  // contributing RenderPasses.
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
            frame.render_passes[1]->quad_list.front()->rect.ToString());

  // Verify it added the right quads.
  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
  EXPECT_EQ(gfx::Rect(0, 0, 7, 7).ToString(),
            frame.render_passes[2]->quad_list.front()->rect.ToString());
  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
            frame.render_passes[2]->quad_list.ElementAt(1)->rect.ToString());
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
            frame.render_passes[1]->quad_list.front()->rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes.
  ASSERT_EQ(5u, frame.render_passes.size());

  // The layer's target is the RenderPass from layer_after_.
  EXPECT_EQ(RenderPassId(3, 0), frame.render_passes[3]->id);

  // The DelegatedRendererLayer should have added copies of quads in its root
  // RenderPass to its target RenderPass. The layer_after_ also adds one quad.
  ASSERT_EQ(2u, frame.render_passes[3]->quad_list.size());

  // Verify it added the right quads.
  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
            frame.render_passes[3]->quad_list.front()->rect.ToString());

  // Its target layer should have a quad as well.
  EXPECT_EQ(gfx::Rect(0, 0, 15, 15).ToString(),
            frame.render_passes[3]->quad_list.ElementAt(1)->rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestSimple,
       QuadsFromRootRenderPassAreModifiedForTheTarget) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes.
  ASSERT_EQ(5u, frame.render_passes.size());

  // The DelegatedRendererLayer is at position 3,3 compared to its target, and
  // has a translation transform of 1,1. So its root RenderPass' quads should
  // all be transformed by that combined amount.
  gfx::Transform transform;
  transform.Translate(4.0, 4.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      transform, frame.render_passes[3]->quad_list.front()->quadTransform());

  // Quads from non-root RenderPasses should not be shifted though.
  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[2]->quad_list.front()->quadTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[2]->quad_list.ElementAt(1)->quadTransform());
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[1]->quad_list.front()->quadTransform());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestSimple, RenderPassTransformIsModified) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // The delegated layer has a surface between it and the root.
  EXPECT_TRUE(delegated_renderer_layer_->render_target()->parent());

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes.
  ASSERT_EQ(5u, frame.render_passes.size());

  // The DelegatedRendererLayer is at position 9,9 compared to the root, so all
  // render pass' transforms to the root should be shifted by this amount.
  gfx::Transform transform;
  transform.Translate(9.0, 9.0);

  // The first contributing surface has a translation of 5, 6.
  gfx::Transform five_six(1, 0, 0, 1, 5, 6);

  // The second contributing surface has a translation of 7, 8.
  gfx::Transform seven_eight(1, 0, 0, 1, 7, 8);

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      transform * five_six, frame.render_passes[1]->transform_to_root_target);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      transform * seven_eight,
      frame.render_passes[2]->transform_to_root_target);

  host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
  host_impl_->DidDrawAllLayers(frame);
}

class DelegatedRendererLayerImplTestOwnSurface
    : public DelegatedRendererLayerImplTestSimple {
 public:
  DelegatedRendererLayerImplTestOwnSurface()
      : DelegatedRendererLayerImplTestSimple() {
    delegated_renderer_layer_->SetHasRenderSurface(true);
  }
};

TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes and its owned surface
  // added one pass.
  ASSERT_EQ(6u, frame.render_passes.size());

  // The DelegatedRendererLayer should have added its contributing RenderPasses
  // to the frame.
  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
  EXPECT_EQ(1, frame.render_passes[1]->id.index);
  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
  EXPECT_EQ(2, frame.render_passes[2]->id.index);
  // The DelegatedRendererLayer should have added a RenderPass for its surface
  // to the frame.
  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[3]->id.index);
  // And all other RenderPasses should be non-delegated.
  EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[0]->id.index);
  EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[4]->id.index);
  EXPECT_NE(4, frame.render_passes[5]->id.layer_id);
  EXPECT_EQ(0, frame.render_passes[5]->id.index);

  // The DelegatedRendererLayer should have added its RenderPasses to the frame
  // in order.
  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
            frame.render_passes[1]->output_rect.ToString());
  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
            frame.render_passes[2]->output_rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestOwnSurface,
       AddsQuadsToContributingRenderPasses) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes and its owned surface
  // added one pass.
  ASSERT_EQ(6u, frame.render_passes.size());

  // The DelegatedRendererLayer should have added its contributing RenderPasses
  // to the frame.
  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
  EXPECT_EQ(1, frame.render_passes[1]->id.index);
  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
  EXPECT_EQ(2, frame.render_passes[2]->id.index);

  // The DelegatedRendererLayer should have added copies of its quads to
  // contributing RenderPasses.
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
            frame.render_passes[1]->quad_list.front()->rect.ToString());

  // Verify it added the right quads.
  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());

  EXPECT_EQ(gfx::Rect(0, 0, 7, 7).ToString(),
            frame.render_passes[2]->quad_list.front()->rect.ToString());
  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
            frame.render_passes[2]->quad_list.ElementAt(1)->rect.ToString());
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
            frame.render_passes[1]->quad_list.front()->rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes and its owned surface
  // added one pass.
  ASSERT_EQ(6u, frame.render_passes.size());

  // The layer's target is the RenderPass owned by itself.
  EXPECT_EQ(RenderPassId(4, 0), frame.render_passes[3]->id);

  // The DelegatedRendererLayer should have added copies of quads in its root
  // RenderPass to its target RenderPass.
  // The layer_after also adds one quad.
  ASSERT_EQ(1u, frame.render_passes[3]->quad_list.size());

  // Verify it added the right quads.
  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
            frame.render_passes[3]->quad_list.front()->rect.ToString());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestOwnSurface,
       QuadsFromRootRenderPassAreNotModifiedForTheTarget) {
  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // Each non-DelegatedRendererLayer added one RenderPass. The
  // DelegatedRendererLayer added two contributing passes and its owned surface
  // added one pass.
  ASSERT_EQ(6u, frame.render_passes.size());

  // Because the DelegatedRendererLayer owns a RenderSurfaceImpl, its root
  // RenderPass' quads do not need to be translated at all.
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[3]->quad_list.front()->quadTransform());

  // Quads from non-root RenderPasses should not be shifted either.
  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());

  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[2]->quad_list.front()->quadTransform());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[2]->quad_list.ElementAt(1)->quadTransform());
  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      gfx::Transform(),
      frame.render_passes[1]->quad_list.front()->quadTransform());

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

class DelegatedRendererLayerImplTestTransform
    : public DelegatedRendererLayerImplTest {
 public:
  DelegatedRendererLayerImplTestTransform()
      : root_delegated_render_pass_is_clipped_(false),
        delegated_device_scale_factor_(2.f) {}

  void SetUpTest() {
    host_impl_->SetDeviceScaleFactor(2.f);

    scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(
        host_impl_->active_tree(), 1);
    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 2);

    host_impl_->SetViewportSize(gfx::Size(200, 200));
    root_layer->SetBounds(gfx::Size(100, 100));
    root_layer->SetHasRenderSurface(true);

    delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
    delegated_renderer_layer->SetBounds(gfx::Size(75, 75));
    delegated_renderer_layer->SetContentBounds(gfx::Size(75, 75));
    delegated_renderer_layer->SetDrawsContent(true);
    gfx::Transform transform;
    transform.Scale(2.0, 2.0);
    transform.Translate(8.0, 8.0);
    delegated_renderer_layer->SetTransform(transform);

    RenderPassList delegated_render_passes;

    gfx::Size child_pass_content_bounds(7, 7);
    gfx::Rect child_pass_rect(20, 20, 7, 7);
    gfx::Transform child_pass_transform;
    child_pass_transform.Scale(0.8f, 0.8f);
    child_pass_transform.Translate(9.0, 9.0);
    gfx::Rect child_pass_clip_rect(21, 21, 3, 3);
    bool child_pass_clipped = false;

    {
      TestRenderPass* pass = AddRenderPass(&delegated_render_passes,
                                           RenderPassId(10, 7),
                                           child_pass_rect,
                                           gfx::Transform());
      SharedQuadState* shared_quad_state =
          pass->CreateAndAppendSharedQuadState();
      shared_quad_state->SetAll(child_pass_transform,
                                child_pass_content_bounds,
                                child_pass_rect,
                                child_pass_clip_rect,
                                child_pass_clipped,
                                1.f,
                                SkXfermode::kSrcOver_Mode,
                                0);

      SolidColorDrawQuad* color_quad;
      color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(shared_quad_state,
                         gfx::Rect(20, 20, 3, 7),
                         gfx::Rect(20, 20, 3, 7),
                         1u,
                         false);

      color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(shared_quad_state,
                         gfx::Rect(23, 20, 4, 7),
                         gfx::Rect(23, 20, 4, 7),
                         1u,
                         false);
    }

    gfx::Size root_pass_content_bounds(100, 100);
    gfx::Rect root_pass_rect(0, 0, 100, 100);
    gfx::Transform root_pass_transform;
    root_pass_transform.Scale(1.5, 1.5);
    root_pass_transform.Translate(7.0, 7.0);
    gfx::Rect root_pass_clip_rect(10, 10, 35, 35);
    bool root_pass_clipped = root_delegated_render_pass_is_clipped_;

    TestRenderPass* pass = AddRenderPass(&delegated_render_passes,
                                         RenderPassId(9, 6),
                                         root_pass_rect,
                                         gfx::Transform());
    SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
    shared_quad_state->SetAll(root_pass_transform,
                              root_pass_content_bounds,
                              root_pass_rect,
                              root_pass_clip_rect,
                              root_pass_clipped,
                              1.f,
                              SkXfermode::kSrcOver_Mode,
                              0);

    RenderPassDrawQuad* render_pass_quad =
        pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
    render_pass_quad->SetNew(shared_quad_state,
                             gfx::Rect(5, 5, 7, 7),  // quad_rect
                             gfx::Rect(5, 5, 7, 7),  // visible_rect
                             RenderPassId(10, 7),    // render_pass_id
                             0,                      // mask_resource_id
                             gfx::Vector2dF(),       // mask_uv_scale
                             gfx::Size(),            // mask_texture_size
                             FilterOperations(),     // filters
                             gfx::Vector2dF(),       // filters_scale
                             FilterOperations());    // background_filters

    SolidColorDrawQuad* color_quad;
    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(0, 0, 10, 10),
                       gfx::Rect(0, 0, 10, 10),
                       1u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(0, 10, 10, 10),
                       gfx::Rect(0, 10, 10, 10),
                       2u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(10, 0, 10, 10),
                       gfx::Rect(10, 0, 10, 10),
                       3u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(10, 10, 10, 10),
                       gfx::Rect(10, 10, 10, 10),
                       4u,
                       false);

    delegated_renderer_layer->SetFrameDataForRenderPasses(
        delegated_device_scale_factor_, delegated_render_passes);

    root_layer_ = root_layer.get();
    delegated_renderer_layer_ = delegated_renderer_layer.get();

    root_layer->AddChild(delegated_renderer_layer.Pass());
    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
  }

  void VerifyRenderPasses(
      const LayerTreeHostImpl::FrameData& frame,
      size_t num_render_passes,
      const SharedQuadState** root_delegated_shared_quad_state,
      const SharedQuadState** contrib_delegated_shared_quad_state) {
    ASSERT_EQ(num_render_passes, frame.render_passes.size());
    // The contributing render pass in the DelegatedRendererLayer.
    EXPECT_EQ(2, frame.render_passes[0]->id.layer_id);
    EXPECT_EQ(1, frame.render_passes[0]->id.index);
    // The root render pass.
    EXPECT_EQ(1, frame.render_passes.back()->id.layer_id);
    EXPECT_EQ(0, frame.render_passes.back()->id.index);

    const QuadList& contrib_delegated_quad_list =
        frame.render_passes[0]->quad_list;
    ASSERT_EQ(2u, contrib_delegated_quad_list.size());

    const QuadList& root_delegated_quad_list =
        frame.render_passes[1]->quad_list;
    ASSERT_EQ(5u, root_delegated_quad_list.size());

    // All quads in a render pass should share the same state.
    *contrib_delegated_shared_quad_state =
        contrib_delegated_quad_list.front()->shared_quad_state;
    EXPECT_EQ(*contrib_delegated_shared_quad_state,
              contrib_delegated_quad_list.ElementAt(1)->shared_quad_state);

    *root_delegated_shared_quad_state =
        root_delegated_quad_list.front()->shared_quad_state;
    EXPECT_EQ(*root_delegated_shared_quad_state,
              root_delegated_quad_list.ElementAt(1)->shared_quad_state);
    EXPECT_EQ(*root_delegated_shared_quad_state,
              root_delegated_quad_list.ElementAt(2)->shared_quad_state);
    EXPECT_EQ(*root_delegated_shared_quad_state,
              root_delegated_quad_list.ElementAt(3)->shared_quad_state);
    EXPECT_EQ(*root_delegated_shared_quad_state,
              root_delegated_quad_list.ElementAt(4)->shared_quad_state);

    EXPECT_NE(*contrib_delegated_shared_quad_state,
              *root_delegated_shared_quad_state);
  }

 protected:
  LayerImpl* root_layer_;
  DelegatedRendererLayerImpl* delegated_renderer_layer_;
  bool root_delegated_render_pass_is_clipped_;
  float delegated_device_scale_factor_;
};

TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = false;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  const SharedQuadState* root_delegated_shared_quad_state = nullptr;
  const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
  VerifyRenderPasses(
      frame,
      2,
      &root_delegated_shared_quad_state,
      &contrib_delegated_shared_quad_state);

  // When the quads don't have a clip of their own, the clip rect is set to
  // the drawable_content_rect of the delegated renderer layer.
  EXPECT_EQ(delegated_renderer_layer_->drawable_content_rect().ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());

  // Even though the quads in the root pass have no clip of their own, they
  // inherit the clip rect from the delegated renderer layer if it does not
  // own a surface.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  gfx::Transform expected;
  // Device scale factor.
  expected.Scale(2.0, 2.0);
  // This is the transform from the layer's space to its target.
  expected.Translate(20, 20);
  expected.Scale(2.0, 2.0);
  expected.Translate(8.0, 8.0);
  // This is the transform within the source frame.
  // Inverse device scale factor to go from physical space to layer space.
  expected.Scale(0.5, 0.5);
  expected.Scale(1.5, 1.5);
  expected.Translate(7.0, 7.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected, root_delegated_shared_quad_state->content_to_target_transform);

  // The contributing render pass should not be transformed from its input.
  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
            contrib_delegated_shared_quad_state->clip_rect.ToString());
  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
  expected.MakeIdentity();
  expected.Scale(0.8f, 0.8f);
  expected.Translate(9.0, 9.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected,
      contrib_delegated_shared_quad_state->content_to_target_transform);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = true;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  const SharedQuadState* root_delegated_shared_quad_state = nullptr;
  const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
  VerifyRenderPasses(
      frame,
      2,
      &root_delegated_shared_quad_state,
      &contrib_delegated_shared_quad_state);

  // Since the quads have a clip_rect it should be modified by delegated
  // renderer layer's draw_transform.
  // The position of the resulting clip_rect is:
  // (clip rect position (10) * inverse dsf (1/2) + translate (8)) *
  //     layer scale (2) + layer position (20) = 46
  // The device scale is 2, so everything gets doubled, giving 92.
  //
  // The size is 35x35 scaled by the device scale.
  EXPECT_EQ(gfx::Rect(92, 92, 70, 70).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());

  // The quads had a clip and it should be preserved.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  gfx::Transform expected;
  // Device scale factor.
  expected.Scale(2.0, 2.0);
  // This is the transform from the layer's space to its target.
  expected.Translate(20, 20);
  expected.Scale(2.0, 2.0);
  expected.Translate(8.0, 8.0);
  // This is the transform within the source frame.
  // Inverse device scale factor to go from physical space to layer space.
  expected.Scale(0.5, 0.5);
  expected.Scale(1.5, 1.5);
  expected.Translate(7.0, 7.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected, root_delegated_shared_quad_state->content_to_target_transform);

  // The contributing render pass should not be transformed from its input.
  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
            contrib_delegated_shared_quad_state->clip_rect.ToString());
  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
  expected.MakeIdentity();
  expected.Scale(0.8f, 0.8f);
  expected.Translate(9.0, 9.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected,
      contrib_delegated_shared_quad_state->content_to_target_transform);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
  root_delegated_render_pass_is_clipped_ = false;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  const SharedQuadState* root_delegated_shared_quad_state = nullptr;
  const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
  VerifyRenderPasses(
      frame,
      3,
      &root_delegated_shared_quad_state,
      &contrib_delegated_shared_quad_state);

  // When the layer owns a surface, then its translation is not part of its
  // draw transform, but its scale is.
  EXPECT_EQ(gfx::Rect(20, 20, 70, 70).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());

  // Since the layer owns a surface it doesn't need to clip its quads, so
  // unclipped quads remain unclipped.
  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);

  gfx::Transform expected;
  // This is the transform within the source frame scaled by the delegated
  // render layer transform.
  expected.Scale(3.0, 3.0);
  expected.Translate(7.0, 7.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected, root_delegated_shared_quad_state->content_to_target_transform);

  // The contributing render pass should not be transformed from its input.
  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
            contrib_delegated_shared_quad_state->clip_rect.ToString());
  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
  expected.MakeIdentity();
  expected.Scale(0.8f, 0.8f);
  expected.Translate(9.0, 9.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected,
      contrib_delegated_shared_quad_state->content_to_target_transform);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
  root_delegated_render_pass_is_clipped_ = true;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  const SharedQuadState* root_delegated_shared_quad_state = nullptr;
  const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
  VerifyRenderPasses(
      frame,
      3,
      &root_delegated_shared_quad_state,
      &contrib_delegated_shared_quad_state);

  // When the layer owns a surface, then its translation is not part of its
  // draw transform, but its scale is.
  EXPECT_EQ(gfx::Rect(20, 20, 70, 70).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());

  // The quads had a clip and it should be preserved.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  gfx::Transform expected;
  // This is the transform within the source frame scaled by the delegated
  // render layer transform.
  expected.Scale(3.0, 3.0);
  expected.Translate(7.0, 7.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected, root_delegated_shared_quad_state->content_to_target_transform);

  // The contributing render pass should not be transformed from its input.
  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
            contrib_delegated_shared_quad_state->clip_rect.ToString());
  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
  expected.MakeIdentity();
  expected.Scale(0.8f, 0.8f);
  expected.Translate(9.0, 9.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected,
      contrib_delegated_shared_quad_state->content_to_target_transform);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestTransform, MismatchedDeviceScaleFactor) {
  root_delegated_render_pass_is_clipped_ = true;
  delegated_device_scale_factor_ = 1.3f;

  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  const SharedQuadState* root_delegated_shared_quad_state = nullptr;
  const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
  VerifyRenderPasses(frame,
                     2,
                     &root_delegated_shared_quad_state,
                     &contrib_delegated_shared_quad_state);

  // The parent tree's device scale factor is 2.0, but the child has submitted a
  // frame with a device scale factor of 1.3.  Absent any better option, the
  // only thing we can do is scale from 1.3 -> 2.0.

  gfx::Transform expected;
  // Device scale factor (from parent).
  expected.Scale(2.0, 2.0);
  // This is the transform from the layer's space to its target.
  expected.Translate(20, 20);
  expected.Scale(2.0, 2.0);
  expected.Translate(8.0, 8.0);
  // This is the transform within the source frame.
  // Inverse device scale factor (from child).
  expected.Scale(1.0f / 1.3f, 1.0f / 1.3f);
  expected.Scale(1.5, 1.5);
  expected.Translate(7.0, 7.0);
  EXPECT_TRANSFORMATION_MATRIX_EQ(
      expected, root_delegated_shared_quad_state->content_to_target_transform);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

class DelegatedRendererLayerImplTestClip
    : public DelegatedRendererLayerImplTest {
 public:
  void SetUpTest() {
    scoped_ptr<LayerImpl> root_layer =
        LayerImpl::Create(host_impl_->active_tree(), 1);
    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 2);
    scoped_ptr<LayerImpl> clip_layer =
        LayerImpl::Create(host_impl_->active_tree(), 3);
    scoped_ptr<LayerImpl> origin_layer =
        LayerImpl::Create(host_impl_->active_tree(), 4);

    host_impl_->SetViewportSize(gfx::Size(100, 100));
    root_layer->SetBounds(gfx::Size(100, 100));
    root_layer->SetHasRenderSurface(true);

    delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
    delegated_renderer_layer->SetBounds(gfx::Size(50, 50));
    delegated_renderer_layer->SetContentBounds(gfx::Size(50, 50));
    delegated_renderer_layer->SetDrawsContent(true);

    RenderPassList delegated_render_passes;

    gfx::Size child_pass_content_bounds(7, 7);
    gfx::Rect child_pass_rect(20, 20, 7, 7);
    gfx::Transform child_pass_transform;
    gfx::Rect child_pass_clip_rect(21, 21, 3, 3);
    bool child_pass_clipped = false;

    {
      TestRenderPass* pass = AddRenderPass(&delegated_render_passes,
                                           RenderPassId(10, 7),
                                           child_pass_rect,
                                           gfx::Transform());
      SharedQuadState* shared_quad_state =
          pass->CreateAndAppendSharedQuadState();
      shared_quad_state->SetAll(child_pass_transform,
                                child_pass_content_bounds,
                                child_pass_rect,
                                child_pass_clip_rect,
                                child_pass_clipped,
                                1.f,
                                SkXfermode::kSrcOver_Mode,
                                0);

      SolidColorDrawQuad* color_quad;
      color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(shared_quad_state,
                         gfx::Rect(20, 20, 3, 7),
                         gfx::Rect(20, 20, 3, 7),
                         1u,
                         false);

      color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      color_quad->SetNew(shared_quad_state,
                         gfx::Rect(23, 20, 4, 7),
                         gfx::Rect(23, 20, 4, 7),
                         1u,
                         false);
    }

    gfx::Size root_pass_content_bounds(50, 50);
    gfx::Rect root_pass_rect(0, 0, 50, 50);
    gfx::Transform root_pass_transform;
    gfx::Rect root_pass_clip_rect(5, 5, 40, 40);
    bool root_pass_clipped = root_delegated_render_pass_is_clipped_;

    TestRenderPass* pass = AddRenderPass(&delegated_render_passes,
                                         RenderPassId(9, 6),
                                         root_pass_rect,
                                         gfx::Transform());
    SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
    shared_quad_state->SetAll(root_pass_transform,
                              root_pass_content_bounds,
                              root_pass_rect,
                              root_pass_clip_rect,
                              root_pass_clipped,
                              1.f,
                              SkXfermode::kSrcOver_Mode,
                              0);

    RenderPassDrawQuad* render_pass_quad =
        pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
    render_pass_quad->SetNew(shared_quad_state,
                             gfx::Rect(5, 5, 7, 7),  // quad_rect
                             gfx::Rect(5, 5, 7, 7),  // visible_quad_rect
                             RenderPassId(10, 7),    // render_pass_id
                             0,                      // mask_resource_id
                             gfx::Vector2dF(),       // mask_uv_scale
                             gfx::Size(),            // mask_texture_size,
                             FilterOperations(),     // filters
                             gfx::Vector2dF(),       // filters_scale
                             FilterOperations());    // background_filters

    SolidColorDrawQuad* color_quad;
    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(0, 0, 10, 10),
                       gfx::Rect(0, 0, 10, 10),
                       1u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(0, 10, 10, 10),
                       gfx::Rect(0, 10, 10, 10),
                       2u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(10, 0, 10, 10),
                       gfx::Rect(10, 0, 10, 10),
                       3u,
                       false);

    color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    color_quad->SetNew(shared_quad_state,
                       gfx::Rect(10, 10, 10, 10),
                       gfx::Rect(10, 10, 10, 10),
                       4u,
                       false);

    delegated_renderer_layer->SetFrameDataForRenderPasses(
        1.f, delegated_render_passes);

    root_layer_ = root_layer.get();
    delegated_renderer_layer_ = delegated_renderer_layer.get();

    if (clip_delegated_renderer_layer_) {
      gfx::Rect clip_rect(21, 27, 23, 21);

      clip_layer->SetPosition(clip_rect.origin());
      clip_layer->SetBounds(clip_rect.size());
      clip_layer->SetContentBounds(clip_rect.size());
      clip_layer->SetMasksToBounds(true);

      origin_layer->SetPosition(
          gfx::PointAtOffsetFromOrigin(-clip_rect.OffsetFromOrigin()));

      origin_layer->AddChild(delegated_renderer_layer.Pass());
      clip_layer->AddChild(origin_layer.Pass());
      root_layer->AddChild(clip_layer.Pass());
    } else {
      root_layer->AddChild(delegated_renderer_layer.Pass());
    }

    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
  }

 protected:
  LayerImpl* root_layer_;
  DelegatedRendererLayerImpl* delegated_renderer_layer_;
  bool root_delegated_render_pass_is_clipped_;
  bool clip_delegated_renderer_layer_;
};

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsUnclipped_LayerUnclipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = false;
  clip_delegated_renderer_layer_ = false;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(2u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads don't have a clip of their own, the clip rect is set to
  // the drawable_content_rect of the delegated renderer layer.
  EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads are clipped to the delegated renderer layer.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsClipped_LayerUnclipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = true;
  clip_delegated_renderer_layer_ = false;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(2u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list =
      frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads have a clip of their own, it is used.
  EXPECT_EQ(gfx::Rect(25, 25, 40, 40).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads came with a clip rect.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsUnclipped_LayerClipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = false;
  clip_delegated_renderer_layer_ = true;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(2u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads don't have a clip of their own, the clip rect is set to
  // the drawable_content_rect of the delegated renderer layer. When the layer
  // is clipped, that should be seen in the quads' clip_rect.
  EXPECT_EQ(gfx::Rect(21, 27, 23, 21).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads are clipped to the delegated renderer layer.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsClipped_LayerClipped_NoSurface) {
  root_delegated_render_pass_is_clipped_ = true;
  clip_delegated_renderer_layer_ = true;
  SetUpTest();

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(2u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads have a clip of their own, it is used, but it is
  // combined with the clip rect of the delegated renderer layer.
  EXPECT_EQ(gfx::Rect(25, 27, 19, 21).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads came with a clip rect.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsUnclipped_LayerUnclipped_Surface) {
  root_delegated_render_pass_is_clipped_ = false;
  clip_delegated_renderer_layer_ = false;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(3u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the layer owns a surface, the quads don't need to be clipped
  // further than they already specify. If they aren't clipped, then their
  // clip rect is ignored, and they are not set as clipped.
  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsClipped_LayerUnclipped_Surface) {
  root_delegated_render_pass_is_clipped_ = true;
  clip_delegated_renderer_layer_ = false;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(3u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads have a clip of their own, it is used.
  EXPECT_EQ(gfx::Rect(5, 5, 40, 40).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads came with a clip rect.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip,
       QuadsUnclipped_LayerClipped_Surface) {
  root_delegated_render_pass_is_clipped_ = false;
  clip_delegated_renderer_layer_ = true;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(3u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the layer owns a surface, the quads don't need to be clipped
  // further than they already specify. If they aren't clipped, then their
  // clip rect is ignored, and they are not set as clipped.
  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTestClip, QuadsClipped_LayerClipped_Surface) {
  root_delegated_render_pass_is_clipped_ = true;
  clip_delegated_renderer_layer_ = true;
  SetUpTest();

  delegated_renderer_layer_->SetHasRenderSurface(true);

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  ASSERT_EQ(3u, frame.render_passes.size());
  const QuadList& contrib_delegated_quad_list =
      frame.render_passes[0]->quad_list;
  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
  ASSERT_EQ(5u, root_delegated_quad_list.size());
  const SharedQuadState* root_delegated_shared_quad_state =
      root_delegated_quad_list.front()->shared_quad_state;

  // When the quads have a clip of their own, it is used, but it is
  // combined with the clip rect of the delegated renderer layer. If the
  // layer owns a surface, then it does not have a clip rect of its own.
  EXPECT_EQ(gfx::Rect(5, 5, 40, 40).ToString(),
            root_delegated_shared_quad_state->clip_rect.ToString());
  // Quads came with a clip rect.
  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTest, InvalidRenderPassDrawQuad) {
  scoped_ptr<LayerImpl> root_layer =
      LayerImpl::Create(host_impl_->active_tree(), 1);
  scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
      FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 4);

  host_impl_->SetViewportSize(gfx::Size(100, 100));
  root_layer->SetHasRenderSurface(true);

  delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
  delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
  delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
  delegated_renderer_layer->SetDrawsContent(true);

  RenderPassList delegated_render_passes;
  TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
                                        RenderPassId(9, 6),
                                        gfx::Rect(0, 0, 10, 10),
                                        gfx::Transform());
  AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);

  // This render pass isn't part of the frame.
  scoped_ptr<TestRenderPass> missing_pass(TestRenderPass::Create());
  missing_pass->SetNew(RenderPassId(9, 7),
                       gfx::Rect(7, 7, 7, 7),
                       gfx::Rect(7, 7, 7, 7),
                       gfx::Transform());

  // But a render pass quad refers to it.
  AddRenderPassQuad(pass1, missing_pass.get());

  delegated_renderer_layer->SetFrameDataForRenderPasses(
      1.f, delegated_render_passes);

  root_layer->AddChild(delegated_renderer_layer.Pass());
  host_impl_->active_tree()->SetRootLayer(root_layer.Pass());

  LayerTreeHostImpl::FrameData frame;
  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));

  // The DelegatedRendererLayerImpl should drop the bad RenderPassDrawQuad.
  ASSERT_EQ(1u, frame.render_passes.size());
  ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
  EXPECT_EQ(DrawQuad::SOLID_COLOR,
            frame.render_passes[0]->quad_list.front()->material);

  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
  host_impl_->DidDrawAllLayers(frame);
}

TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
  gfx::Size layer_size(1000, 1000);
  gfx::Size viewport_size(1000, 1000);
  gfx::Rect quad_screen_rect(211, 300, 400, 500);

  gfx::Transform transform;
  transform.Translate(211.0, 300.0);

  LayerTestCommon::LayerImplTest impl;

  FakeDelegatedRendererLayerImpl* delegated_renderer_layer_impl =
      impl.AddChildToRoot<FakeDelegatedRendererLayerImpl>();
  delegated_renderer_layer_impl->SetBounds(layer_size);
  delegated_renderer_layer_impl->SetContentBounds(layer_size);
  delegated_renderer_layer_impl->SetDrawsContent(true);

  // Contributing render pass is offset by a transform and holds a quad that
  // covers it entirely.
  RenderPassList delegated_render_passes;
  // pass2 is just the size of the quad. It contributes to |pass1| with a
  // translation of (211,300).
  RenderPassId pass2_id =
      delegated_renderer_layer_impl->FirstContributingRenderPassId();
  TestRenderPass* pass2 = AddRenderPass(&delegated_render_passes,
                                        pass2_id,
                                        gfx::Rect(quad_screen_rect.size()),
                                        transform);
  AddQuad(pass2, gfx::Rect(quad_screen_rect.size()), SK_ColorRED);
  // |pass1| covers the whole layer.
  RenderPassId pass1_id = RenderPassId(impl.root_layer()->id(), 0);
  TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
                                        pass1_id,
                                        gfx::Rect(layer_size),
                                        gfx::Transform());
  AddRenderPassQuad(pass1,
                    pass2,
                    0,
                    FilterOperations(),
                    transform,
                    SkXfermode::kSrcOver_Mode);
  delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
      1.f, delegated_render_passes);

  impl.CalcDrawProps(viewport_size);

  {
    SCOPED_TRACE("No occlusion");
    gfx::Rect occluded;

    {
      SCOPED_TRACE("Root render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass1,
                                           occluded);
      LayerTestCommon::VerifyQuadsExactlyCoverRect(pass1->quad_list,
                                                   quad_screen_rect);
      ASSERT_EQ(1u, pass1->quad_list.size());
      EXPECT_EQ(DrawQuad::RENDER_PASS, pass1->quad_list.front()->material);
    }
    {
      SCOPED_TRACE("Contributing render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass2,
                                           occluded);
      LayerTestCommon::VerifyQuadsExactlyCoverRect(
          pass2->quad_list, gfx::Rect(quad_screen_rect.size()));
      ASSERT_EQ(1u, pass2->quad_list.size());
      EXPECT_EQ(DrawQuad::SOLID_COLOR, pass2->quad_list.front()->material);
    }
  }

  {
    SCOPED_TRACE("Full occlusion");
    {
      gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());

      SCOPED_TRACE("Root render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass1,
                                           occluded);
      LayerTestCommon::VerifyQuadsExactlyCoverRect(pass1->quad_list,
                                                   gfx::Rect());
      EXPECT_EQ(pass1->quad_list.size(), 0u);
    }
    {
      gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());

      SCOPED_TRACE("Contributing render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass2,
                                           occluded);
      LayerTestCommon::VerifyQuadsExactlyCoverRect(pass2->quad_list,
                                                   gfx::Rect());
      EXPECT_EQ(pass2->quad_list.size(), 0u);
    }
  }

  {
    SCOPED_TRACE("Partial occlusion");
    {
      gfx::Rect occlusion_in_root_target(0, 0, 500, 1000);

      SCOPED_TRACE("Root render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass1,
                                           occlusion_in_root_target);
      size_t partially_occluded_count = 0;
      LayerTestCommon::VerifyQuadsAreOccluded(pass1->quad_list,
                                              occlusion_in_root_target,
                                              &partially_occluded_count);
      // The layer outputs one quad, which is partially occluded.
      EXPECT_EQ(1u, pass1->quad_list.size());
      EXPECT_EQ(1u, partially_occluded_count);
    }
    {
      gfx::Rect occlusion_in_root_target(0, 0, 500, 1000);
      // Move the occlusion to where it is in the contributing surface.
      gfx::Rect occlusion_in_target_of_delegated_quad =
          occlusion_in_root_target - quad_screen_rect.OffsetFromOrigin();

      SCOPED_TRACE("Contributing render pass");
      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass2,
                                           occlusion_in_root_target);
      size_t partially_occluded_count = 0;
      LayerTestCommon::VerifyQuadsAreOccluded(
          pass2->quad_list, occlusion_in_target_of_delegated_quad,
          &partially_occluded_count);
      // The layer outputs one quad, which is partially occluded.
      EXPECT_EQ(1u, pass2->quad_list.size());
      EXPECT_EQ(1u, partially_occluded_count);
      // The quad in the contributing surface is at (211,300) in the root.
      // The occlusion extends to 500 in the x-axis, pushing the left of the
      // visible part of the quad to 500 - 211 = 300 - 11 inside the quad.
      EXPECT_EQ(gfx::Rect(300 - 11, 0, 100 + 11, 500).ToString(),
                pass2->quad_list.front()->visible_rect.ToString());
    }
    {
      gfx::Rect occlusion_in_root_target(0, 0, 500, 1000);
      // Move the occlusion to where it is in the contributing surface.
      gfx::Rect occlusion_in_target_of_delegated_quad =
          occlusion_in_root_target - quad_screen_rect.OffsetFromOrigin();

      SCOPED_TRACE("Contributing render pass with transformed root");

      gfx::Transform layer_transform;
      layer_transform.Translate(11.0, 0.0);
      delegated_renderer_layer_impl->SetTransform(layer_transform);

      occlusion_in_target_of_delegated_quad += gfx::Vector2d(11, 0);

      impl.CalcDrawProps(viewport_size);

      impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass2,
                                           occlusion_in_root_target);
      size_t partially_occluded_count = 0;
      LayerTestCommon::VerifyQuadsAreOccluded(
          pass2->quad_list, occlusion_in_target_of_delegated_quad,
          &partially_occluded_count);
      // The layer outputs one quad, which is partially occluded.
      EXPECT_EQ(1u, pass2->quad_list.size());
      EXPECT_EQ(1u, partially_occluded_count);
      // The quad in the contributing surface is at (222,300) in the transformed
      // root. The occlusion extends to 500 in the x-axis, pushing the left of
      // the visible part of the quad to 500 - 222 = 300 - 22 inside the quad.
      EXPECT_EQ(gfx::Rect(300 - 22, 0, 100 + 22, 500).ToString(),
                pass2->quad_list.front()->visible_rect.ToString());
    }
  }
}

TEST_F(DelegatedRendererLayerImplTest, PushPropertiesTo) {
  gfx::Size layer_size(1000, 1000);

  scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer_impl =
      FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 5);
  delegated_renderer_layer_impl->SetBounds(layer_size);
  delegated_renderer_layer_impl->SetContentBounds(layer_size);
  delegated_renderer_layer_impl->SetDrawsContent(true);

  RenderPassList delegated_render_passes;
  // |pass1| covers the whole layer.
  RenderPassId pass1_id = RenderPassId(5, 0);
  AddRenderPass(&delegated_render_passes,
                pass1_id,
                gfx::Rect(layer_size),
                gfx::Transform());
  delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
      2.f, delegated_render_passes);
  EXPECT_EQ(0.5f, delegated_renderer_layer_impl->inverse_device_scale_factor());

  scoped_ptr<DelegatedRendererLayerImpl> other_layer =
      DelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 6);

  delegated_renderer_layer_impl->PushPropertiesTo(other_layer.get());

  EXPECT_EQ(0.5f, other_layer->inverse_device_scale_factor());
}

}  // namespace
}  // namespace cc
