// 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/trees/occlusion_tracker.h"

#include "cc/animation/layer_animation_controller.h"
#include "cc/base/math_util.h"
#include "cc/debug/overdraw_metrics.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/filter_operation.h"
#include "cc/output/filter_operations.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/occlusion_tracker_test_common.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

class TestContentLayer : public Layer {
 public:
  TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}

  virtual bool DrawsContent() const OVERRIDE { return true; }
  virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
    if (override_opaque_contents_rect_)
      return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
    return Layer::VisibleContentOpaqueRegion();
  }
  void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
    override_opaque_contents_rect_ = true;
    opaque_contents_rect_ = opaque_contents_rect;
  }

 private:
  virtual ~TestContentLayer() {}

  bool override_opaque_contents_rect_;
  gfx::Rect opaque_contents_rect_;
};

class TestContentLayerImpl : public LayerImpl {
 public:
  TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
      : LayerImpl(tree_impl, id), override_opaque_contents_rect_(false) {
    SetDrawsContent(true);
  }

  virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
    if (override_opaque_contents_rect_)
      return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
    return LayerImpl::VisibleContentOpaqueRegion();
  }
  void SetOpaqueContentsRect(gfx::Rect opaque_contents_rect) {
    override_opaque_contents_rect_ = true;
    opaque_contents_rect_ = opaque_contents_rect;
  }

 private:
  bool override_opaque_contents_rect_;
  gfx::Rect opaque_contents_rect_;
};

static inline bool LayerImplDrawTransformIsUnknown(const Layer* layer) {
  return layer->draw_transform_is_animating();
}
static inline bool LayerImplDrawTransformIsUnknown(const LayerImpl* layer) {
  return false;
}

template <typename LayerType, typename RenderSurfaceType>
class TestOcclusionTrackerWithClip
    : public TestOcclusionTrackerBase<LayerType, RenderSurfaceType> {
 public:
  TestOcclusionTrackerWithClip(gfx::Rect viewport_rect,
                               bool record_metrics_for_frame)
      : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(
            viewport_rect,
            record_metrics_for_frame) {}
  explicit TestOcclusionTrackerWithClip(gfx::Rect viewport_rect)
      : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect,
                                                               false) {}

  bool OccludedLayer(const LayerType* layer, gfx::Rect content_rect) {
    bool temp;
    return OccludedLayer(layer, content_rect, &temp);
  }

  bool OccludedLayer(const LayerType* layer,
                     gfx::Rect content_rect,
                     bool* has_occlusion_from_outside_target_surface) const {
    return this->Occluded(layer->render_target(),
                          content_rect,
                          layer->draw_transform(),
                          LayerImplDrawTransformIsUnknown(layer),
                          layer->is_clipped(),
                          layer->clip_rect(),
                          has_occlusion_from_outside_target_surface);
  }
  // Gives an unoccluded sub-rect of |content_rect| in the content space of the
  // layer. Simple wrapper around UnoccludedContentRect.
  gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
                                       gfx::Rect content_rect) const {
    bool temp;
    return UnoccludedLayerContentRect(layer, content_rect, &temp);
  }

  gfx::Rect UnoccludedLayerContentRect(
      const LayerType* layer,
      gfx::Rect content_rect,
      bool* has_occlusion_from_outside_target_surface) const {
    return this->UnoccludedContentRect(
        layer->render_target(),
        content_rect,
        layer->draw_transform(),
        LayerImplDrawTransformIsUnknown(layer),
        layer->is_clipped(),
        layer->clip_rect(),
        has_occlusion_from_outside_target_surface);
  }
};

struct OcclusionTrackerTestMainThreadTypes {
  typedef Layer LayerType;
  typedef LayerTreeHost HostType;
  typedef RenderSurface RenderSurfaceType;
  typedef TestContentLayer ContentLayerType;
  typedef scoped_refptr<Layer> LayerPtrType;
  typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
  typedef LayerIterator<Layer,
                        RenderSurfaceLayerList,
                        RenderSurface,
                        LayerIteratorActions::FrontToBack> TestLayerIterator;
  typedef OcclusionTracker OcclusionTrackerType;

  static LayerPtrType CreateLayer(HostType*  host) { return Layer::Create(); }
  static ContentLayerPtrType CreateContentLayer(HostType* host) {
    return make_scoped_refptr(new ContentLayerType());
  }

  static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
    LayerPtrType ref(*layer);
    *layer = NULL;
    return ref;
  }

  static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
    LayerPtrType ref(*layer);
    *layer = NULL;
    return ref;
  }

  static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
};

struct OcclusionTrackerTestImplThreadTypes {
  typedef LayerImpl LayerType;
  typedef LayerTreeImpl HostType;
  typedef RenderSurfaceImpl RenderSurfaceType;
  typedef TestContentLayerImpl ContentLayerType;
  typedef scoped_ptr<LayerImpl> LayerPtrType;
  typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
  typedef LayerIterator<LayerImpl,
                        LayerImplList,
                        RenderSurfaceImpl,
                        LayerIteratorActions::FrontToBack> TestLayerIterator;
  typedef OcclusionTrackerImpl OcclusionTrackerType;

  static LayerPtrType CreateLayer(HostType* host) {
    return LayerImpl::Create(host, next_layer_impl_id++);
  }
  static ContentLayerPtrType CreateContentLayer(HostType* host) {
    return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
  }
  static int next_layer_impl_id;

  static LayerPtrType PassLayerPtr(LayerPtrType* layer) {
    return layer->Pass();
  }

  static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) {
    return layer->PassAs<LayerType>();
  }

  static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
};

int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;

template <typename Types> class OcclusionTrackerTest : public testing::Test {
 protected:
  explicit OcclusionTrackerTest(bool opaque_layers)
      : host_impl_(&proxy_), opaque_layers_(opaque_layers) {}

  virtual void RunMyTest() = 0;

  virtual void TearDown() {
    Types::DestroyLayer(&root_);
    render_surface_layer_list_.reset();
    render_surface_layer_list_impl_.clear();
    replica_layers_.clear();
    mask_layers_.clear();
  }

  typename Types::HostType* GetHost();

  typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
                                               gfx::PointF position,
                                               gfx::Size bounds) {
    typename Types::ContentLayerPtrType layer(
        Types::CreateContentLayer(GetHost()));
    typename Types::ContentLayerType* layer_ptr = layer.get();
    SetProperties(layer_ptr, transform, position, bounds);

    DCHECK(!root_.get());
    root_ = Types::PassLayerPtr(&layer);
    return layer_ptr;
  }

  typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
                                         const gfx::Transform& transform,
                                         gfx::PointF position,
                                         gfx::Size bounds) {
    typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
    typename Types::LayerType* layer_ptr = layer.get();
    SetProperties(layer_ptr, transform, position, bounds);
    parent->AddChild(Types::PassLayerPtr(&layer));
    return layer_ptr;
  }

  typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
                                           const gfx::Transform& transform,
                                           gfx::PointF position,
                                           gfx::Size bounds) {
    typename Types::LayerType* layer =
        CreateLayer(parent, transform, position, bounds);
    layer->SetForceRenderSurface(true);
    return layer;
  }

  typename Types::ContentLayerType* CreateDrawingLayer(
      typename Types::LayerType* parent,
      const gfx::Transform& transform,
      gfx::PointF position,
      gfx::Size bounds,
      bool opaque) {
    typename Types::ContentLayerPtrType layer(
        Types::CreateContentLayer(GetHost()));
    typename Types::ContentLayerType* layer_ptr = layer.get();
    SetProperties(layer_ptr, transform, position, bounds);

    if (opaque_layers_) {
      layer_ptr->SetContentsOpaque(opaque);
    } else {
      layer_ptr->SetContentsOpaque(false);
      if (opaque)
        layer_ptr->SetOpaqueContentsRect(gfx::Rect(bounds));
      else
        layer_ptr->SetOpaqueContentsRect(gfx::Rect());
    }

    parent->AddChild(Types::PassLayerPtr(&layer));
    return layer_ptr;
  }

  typename Types::LayerType* CreateReplicaLayer(
      typename Types::LayerType* owning_layer,
      const gfx::Transform& transform,
      gfx::PointF position,
      gfx::Size bounds) {
    typename Types::ContentLayerPtrType layer(
        Types::CreateContentLayer(GetHost()));
    typename Types::ContentLayerType* layer_ptr = layer.get();
    SetProperties(layer_ptr, transform, position, bounds);
    SetReplica(owning_layer, Types::PassLayerPtr(&layer));
    return layer_ptr;
  }

  typename Types::LayerType* CreateMaskLayer(
      typename Types::LayerType* owning_layer,
      gfx::Size bounds) {
    typename Types::ContentLayerPtrType layer(
        Types::CreateContentLayer(GetHost()));
    typename Types::ContentLayerType* layer_ptr = layer.get();
    SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
    SetMask(owning_layer, Types::PassLayerPtr(&layer));
    return layer_ptr;
  }

  typename Types::ContentLayerType* CreateDrawingSurface(
      typename Types::LayerType* parent,
      const gfx::Transform& transform,
      gfx::PointF position,
      gfx::Size bounds,
      bool opaque) {
    typename Types::ContentLayerType* layer =
        CreateDrawingLayer(parent, transform, position, bounds, opaque);
    layer->SetForceRenderSurface(true);
    return layer;
  }


  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}

  void AddCopyRequest(Layer* layer) {
    layer->RequestCopyOfOutput(
        CopyOutputRequest::CreateBitmapRequest(base::Bind(
            &OcclusionTrackerTest<Types>::CopyOutputCallback,
            base::Unretained(this))));
  }

  void AddCopyRequest(LayerImpl* layer) {
    ScopedPtrVector<CopyOutputRequest> requests;
    requests.push_back(
        CopyOutputRequest::CreateBitmapRequest(base::Bind(
            &OcclusionTrackerTest<Types>::CopyOutputCallback,
            base::Unretained(this))));
    layer->PassCopyRequests(&requests);
  }

  void CalcDrawEtc(TestContentLayerImpl* root) {
    DCHECK(root == root_.get());
    DCHECK(!root->render_surface());

    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
        root, root->bounds(), &render_surface_layer_list_impl_);
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    layer_iterator_ = layer_iterator_begin_ =
        Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
  }

  void CalcDrawEtc(TestContentLayer* root) {
    DCHECK(root == root_.get());
    DCHECK(!root->render_surface());

    render_surface_layer_list_.reset(new RenderSurfaceLayerList);
    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        root, root->bounds(), render_surface_layer_list_.get());
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);

    layer_iterator_ = layer_iterator_begin_ =
        Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
  }

  void EnterLayer(typename Types::LayerType* layer,
                  typename Types::OcclusionTrackerType* occlusion,
                  bool prevent_occlusion) {
    ASSERT_EQ(layer, *layer_iterator_);
    ASSERT_TRUE(layer_iterator_.represents_itself());
    occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
  }

  void LeaveLayer(typename Types::LayerType* layer,
                  typename Types::OcclusionTrackerType* occlusion) {
    ASSERT_EQ(layer, *layer_iterator_);
    ASSERT_TRUE(layer_iterator_.represents_itself());
    occlusion->LeaveLayer(layer_iterator_);
    ++layer_iterator_;
  }

  void VisitLayer(typename Types::LayerType* layer,
                  typename Types::OcclusionTrackerType* occlusion) {
    EnterLayer(layer, occlusion, false);
    LeaveLayer(layer, occlusion);
  }

  void EnterContributingSurface(
      typename Types::LayerType* layer,
      typename Types::OcclusionTrackerType* occlusion,
      bool prevent_occlusion) {
    ASSERT_EQ(layer, *layer_iterator_);
    ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
    occlusion->EnterLayer(layer_iterator_, false);
    occlusion->LeaveLayer(layer_iterator_);
    ++layer_iterator_;
    ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
    occlusion->EnterLayer(layer_iterator_, prevent_occlusion);
  }

  void LeaveContributingSurface(
      typename Types::LayerType* layer,
      typename Types::OcclusionTrackerType* occlusion) {
    ASSERT_EQ(layer, *layer_iterator_);
    ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
    occlusion->LeaveLayer(layer_iterator_);
    ++layer_iterator_;
  }

  void VisitContributingSurface(
      typename Types::LayerType* layer,
      typename Types::OcclusionTrackerType* occlusion) {
    EnterContributingSurface(layer, occlusion, false);
    LeaveContributingSurface(layer, occlusion);
  }

  void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }

  const gfx::Transform identity_matrix;

 private:
  void SetBaseProperties(typename Types::LayerType* layer,
                         const gfx::Transform& transform,
                         gfx::PointF position,
                         gfx::Size bounds) {
    layer->SetTransform(transform);
    layer->SetSublayerTransform(gfx::Transform());
    layer->SetAnchorPoint(gfx::PointF());
    layer->SetPosition(position);
    layer->SetBounds(bounds);
  }

  void SetProperties(Layer* layer,
                     const gfx::Transform& transform,
                     gfx::PointF position,
                     gfx::Size bounds) {
    SetBaseProperties(layer, transform, position, bounds);
  }

  void SetProperties(LayerImpl* layer,
                     const gfx::Transform& transform,
                     gfx::PointF position,
                     gfx::Size bounds) {
    SetBaseProperties(layer, transform, position, bounds);

    layer->SetContentBounds(layer->bounds());
  }

  void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
    owning_layer->SetReplicaLayer(layer.get());
    replica_layers_.push_back(layer);
  }

  void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
    owning_layer->SetReplicaLayer(layer.Pass());
  }

  void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
    owning_layer->SetMaskLayer(layer.get());
    mask_layers_.push_back(layer);
  }

  void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
    owning_layer->SetMaskLayer(layer.Pass());
  }

  FakeImplProxy proxy_;
  FakeLayerTreeHostImpl host_impl_;
  bool opaque_layers_;
  // These hold ownership of the layers for the duration of the test.
  typename Types::LayerPtrType root_;
  scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
  LayerImplList render_surface_layer_list_impl_;
  typename Types::TestLayerIterator layer_iterator_begin_;
  typename Types::TestLayerIterator layer_iterator_;
  typename Types::LayerType* last_layer_visited_;
  LayerList replica_layers_;
  LayerList mask_layers_;
};

template <>
LayerTreeHost*
OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
  return NULL;
}

template <>
LayerTreeImpl*
OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
  return host_impl_.active_tree();
}

#define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                          \
  class ClassName##MainThreadOpaqueLayers                                      \
      : public ClassName<OcclusionTrackerTestMainThreadTypes> {                \
   public: /* NOLINT(whitespace/indent) */                                     \
    ClassName##MainThreadOpaqueLayers()                                        \
        : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {}              \
  };                                                                           \
  TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
#define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)                          \
  class ClassName##MainThreadOpaquePaints                                      \
      : public ClassName<OcclusionTrackerTestMainThreadTypes> {                \
   public: /* NOLINT(whitespace/indent) */                                     \
    ClassName##MainThreadOpaquePaints()                                        \
        : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {}             \
  };                                                                           \
  TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }

#define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)                          \
  class ClassName##ImplThreadOpaqueLayers                                      \
      : public ClassName<OcclusionTrackerTestImplThreadTypes> {                \
   public: /* NOLINT(whitespace/indent) */                                     \
    ClassName##ImplThreadOpaqueLayers()                                        \
        : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {}              \
  };                                                                           \
  TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
#define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)                          \
  class ClassName##ImplThreadOpaquePaints                                      \
      : public ClassName<OcclusionTrackerTestImplThreadTypes> {                \
   public: /* NOLINT(whitespace/indent) */                                     \
    ClassName##ImplThreadOpaquePaints()                                        \
        : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {}             \
  };                                                                           \
  TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }

#define ALL_OCCLUSIONTRACKER_TEST(ClassName)                                   \
  RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                                \
      RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)                            \
      RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)                            \
      RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)

#define MAIN_THREAD_TEST(ClassName)                                            \
  RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)

#define IMPL_THREAD_TEST(ClassName)                                            \
  RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)

#define MAIN_AND_IMPL_THREAD_TEST(ClassName)                                   \
  RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)                                \
      RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)

template <class Types>
class OcclusionTrackerTestIdentityTransforms
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}

  void RunMyTest() {
    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);
    parent->SetMasksToBounds(true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000), false);

    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 30, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 30, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 31, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 31, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 31, 70, 70)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);

template <class Types>
class OcclusionTrackerTestQuadsMismatchLayer
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform layer_transform;
    layer_transform.Translate(10.0, 10.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100));
    typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
        parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true);
    typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
        layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer2, &occlusion);
    this->EnterLayer(layer1, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // This checks cases where the quads don't match their "containing"
    // layers, e.g. in terms of transforms or clip rect. This is typical for
    // DelegatedRendererLayer.

    gfx::Transform quad_transform;
    quad_transform.Translate(30.0, 30.0);
    gfx::Rect clip_rect_in_target(0, 0, 100, 100);

    EXPECT_TRUE(occlusion.UnoccludedContentRect(parent,
                                                gfx::Rect(0, 0, 10, 10),
                                                quad_transform,
                                                false,
                                                true,
                                                clip_rect_in_target,
                                                NULL).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10),
                   occlusion.UnoccludedContentRect(parent,
                                                   gfx::Rect(0, 0, 10, 10),
                                                   quad_transform,
                                                   true,
                                                   true,
                                                   clip_rect_in_target,
                                                   NULL));
    EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10),
                   occlusion.UnoccludedContentRect(parent,
                                                   gfx::Rect(40, 40, 10, 10),
                                                   quad_transform,
                                                   false,
                                                   true,
                                                   clip_rect_in_target,
                                                   NULL));
    EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10),
                   occlusion.UnoccludedContentRect(parent,
                                                   gfx::Rect(35, 30, 10, 10),
                                                   quad_transform,
                                                   false,
                                                   true,
                                                   clip_rect_in_target,
                                                   NULL));
    EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5),
                   occlusion.UnoccludedContentRect(parent,
                                                   gfx::Rect(40, 40, 10, 10),
                                                   quad_transform,
                                                   false,
                                                   true,
                                                   gfx::Rect(0, 0, 75, 75),
                                                   NULL));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer);

template <class Types>
class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform layer_transform;
    layer_transform.Translate(250.0, 250.0);
    layer_transform.Rotate(90.0);
    layer_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 layer_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);
    parent->SetMasksToBounds(true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 70, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 70)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 30, 70, 70)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 30, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 29, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 30, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 31, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 31, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 31, 70, 70)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);

template <class Types>
class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform layer_transform;
    layer_transform.Translate(20.0, 20.0);

    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 layer_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);
    parent->SetMasksToBounds(true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 50, 50)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 50)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(50, 50, 50, 50)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(49, 50, 50, 50)));
    EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(49, 49, 50, 50)));
    EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(50, 49, 50, 50)));
    EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(51, 49, 50, 50)));
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(51, 50, 50, 50)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(51, 51, 50, 50)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(50, 51, 50, 50)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(49, 51, 50, 50)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);

template <class Types>
class OcclusionTrackerTestChildInRotatedChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(90.0);
    child_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* child = this->CreateSurface(
        parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
    child->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(child,
                                 this->identity_matrix,
                                 gfx::PointF(10.f, 10.f),
                                 gfx::Size(500, 500),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer, &occlusion);
    this->EnterContributingSurface(child, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->LeaveContributingSurface(child, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 70, 60)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 60)));

    /* Justification for the above occlusion from |layer|:
                  100
         +---------------------+
         |                     |
         |    30               |           rotate(90)
         | 30 + ---------------------------------+
     100 |    |  10            |                 |            ==>
         |    |10+---------------------------------+
         |    |  |             |                 | |
         |    |  |             |                 | |
         |    |  |             |                 | |
         +----|--|-------------+                 | |
              |  |                               | |
              |  |                               | |
              |  |                               | |500
              |  |                               | |
              |  |                               | |
              |  |                               | |
              |  |                               | |
              +--|-------------------------------+ |
                 |                                 |
                 +---------------------------------+
                                500

        +---------------------+
        |                     |30  Visible region of |layer|: /////
        |                     |
        |     +---------------------------------+
     100|     |               |10               |
        |  +---------------------------------+  |
        |  |  |///////////////|     420      |  |
        |  |  |///////////////|60            |  |
        |  |  |///////////////|              |  |
        +--|--|---------------+              |  |
         20|10|     70                       |  |
           |  |                              |  |
           |  |                              |  |
           |  |                              |  |
           |  |                              |  |
           |  |                              |  |
           |  |                              |10|
           |  +------------------------------|--+
           |                 490             |
           +---------------------------------+
                          500

     */
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);

template <class Types>
class OcclusionTrackerTestScaledRenderSurface
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}

  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));

    gfx::Transform layer1_matrix;
    layer1_matrix.Scale(2.0, 2.0);
    typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
        parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    layer1->SetForceRenderSurface(true);

    gfx::Transform layer2_matrix;
    layer2_matrix.Translate(25.0, 25.0);
    typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
        layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
    typename Types::ContentLayerType* occluder =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(500, 500),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(occluder, &occlusion);
    this->EnterLayer(layer2, &occlusion, false);

    EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_RECT_EQ(
        gfx::Rect(0, 0, 25, 25),
        occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25)));
    EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25),
                   occlusion.UnoccludedLayerContentRect(
                       layer2, gfx::Rect(10, 25, 25, 25)));
    EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15),
                   occlusion.UnoccludedLayerContentRect(
                       layer2, gfx::Rect(25, 10, 25, 25)));
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);

template <class Types>
class OcclusionTrackerTestVisitTargetTwoTimes
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(90.0);
    child_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    parent->SetMasksToBounds(true);
    typename Types::LayerType* child = this->CreateSurface(
        parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
    child->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(child,
                                 this->identity_matrix,
                                 gfx::PointF(10.f, 10.f),
                                 gfx::Size(500, 500),
                                 true);
    // |child2| makes |parent|'s surface get considered by OcclusionTracker
    // first, instead of |child|'s. This exercises different code in
    // LeaveToRenderTarget, as the target surface has already been seen.
    typename Types::ContentLayerType* child2 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(60, 20),
                                 true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(child2, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(layer, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->EnterContributingSurface(child, &occlusion, false);

    EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // Occlusion in |child2| should get merged with the |child| surface we are
    // leaving now.
    this->LeaveContributingSurface(child, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60))
                  .ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70)));
    EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 30, 70, 70)));

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10)));

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 30, 60, 10)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 30, 60, 10)));
    EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 29, 60, 10)));
    EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 30, 60, 10)));
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 31, 60, 10)).IsEmpty());

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 40, 70, 60)));
    // This rect is mostly occluded by |child2|.
    EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 39, 70, 60)));
    // This rect extends past top/right ends of |child2|.
    EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 29, 70, 70)));
    // This rect extends past left/right ends of |child2|.
    EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(20, 39, 80, 60)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 40, 70, 60)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 41, 70, 60)));

    /* Justification for the above occlusion from |layer|:
               100
      +---------------------+
      |                     |
      |    30               |           rotate(90)
      | 30 + ------------+--------------------+
  100 |    |  10         |  |                 |            ==>
      |    |10+----------|----------------------+
      |    + ------------+  |                 | |
      |    |  |             |                 | |
      |    |  |             |                 | |
      +----|--|-------------+                 | |
           |  |                               | |
           |  |                               | |
           |  |                               | |500
           |  |                               | |
           |  |                               | |
           |  |                               | |
           |  |                               | |
           +--|-------------------------------+ |
              |                                 |
              +---------------------------------+
                             500


       +---------------------+
       |                     |30  Visible region of |layer|: /////
       |     30   60         |    |child2|: \\\\\
       |  30 +------------+--------------------+
       |     |\\\\\\\\\\\\|  |10               |
       |  +--|\\\\\\\\\\\\|-----------------+  |
       |  |  +------------+//|     420      |  |
       |  |  |///////////////|60            |  |
       |  |  |///////////////|              |  |
       +--|--|---------------+              |  |
        20|10|     70                       |  |
          |  |                              |  |
          |  |                              |  |
          |  |                              |  |
          |  |                              |  |
          |  |                              |  |
          |  |                              |10|
          |  +------------------------------|--+
          |                 490             |
          +---------------------------------+
                         500
     */
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);

template <class Types>
class OcclusionTrackerTestSurfaceRotatedOffAxis
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(95.0);
    child_transform.Translate(-250.0, -250.0);

    gfx::Transform layer_transform;
    layer_transform.Translate(10.0, 10.0);

    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    typename Types::LayerType* child = this->CreateLayer(
        parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
    child->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
        child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    gfx::Rect clipped_layer_in_child = MathUtil::MapClippedRect(
        layer_transform, layer->visible_content_rect());

    this->VisitLayer(layer, &occlusion);
    this->EnterContributingSurface(child, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(clipped_layer_in_child.ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->LeaveContributingSurface(child, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1)));
    EXPECT_RECT_EQ(
        gfx::Rect(75, 55, 1, 1),
        occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);

template <class Types>
class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(90.0);
    child_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
    parent->SetMasksToBounds(true);
    typename Types::ContentLayerType* child =
        this->CreateDrawingSurface(parent,
                                 child_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 false);
    child->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer1 =
        this->CreateDrawingLayer(child,
                                 this->identity_matrix,
                                 gfx::PointF(10.f, 10.f),
                                 gfx::Size(500, 500),
                                 true);
    typename Types::ContentLayerType* layer2 =
        this->CreateDrawingLayer(child,
                                 this->identity_matrix,
                                 gfx::PointF(10.f, 450.f),
                                 gfx::Size(500, 60),
                                 true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer2, &occlusion);
    this->VisitLayer(layer1, &occlusion);
    this->VisitLayer(child, &occlusion);
    this->EnterContributingSurface(child, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70)));
    // These rects are occluded except for the part outside the bounds of the
    // target surface.
    EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 429, 60, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 60, 70)));
    EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 70)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        child, gfx::Rect(10, 430, 60, 70)).IsEmpty());
    EXPECT_RECT_EQ(
        gfx::Rect(9, 430, 1, 70),
        occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70)));
    // These rects are occluded except for the part outside the bounds of the
    // target surface.
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       child, gfx::Rect(10, 429, 60, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       child, gfx::Rect(11, 430, 60, 70)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       child, gfx::Rect(10, 431, 60, 70)));

    this->LeaveContributingSurface(child, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(30, 40, 70, 60)).IsEmpty());
    EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(29, 40, 70, 60)));
    EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 39, 70, 60)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(31, 40, 70, 60)));
    EXPECT_RECT_EQ(gfx::Rect(),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(30, 41, 70, 60)));

    /* Justification for the above occlusion from |layer1| and |layer2|:

           +---------------------+
           |                     |30  Visible region of |layer1|: /////
           |                     |    Visible region of |layer2|: \\\\\
           |     +---------------------------------+
           |     |               |10               |
           |  +---------------+-----------------+  |
           |  |  |\\\\\\\\\\\\|//|     420      |  |
           |  |  |\\\\\\\\\\\\|//|60            |  |
           |  |  |\\\\\\\\\\\\|//|              |  |
           +--|--|------------|--+              |  |
            20|10|     70     |                 |  |
              |  |            |                 |  |
              |  |            |                 |  |
              |  |            |                 |  |
              |  |            |                 |  |
              |  |            |                 |  |
              |  |            |                 |10|
              |  +------------|-----------------|--+
              |               | 490             |
              +---------------+-----------------+
                     60               440
         */
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);

template <class Types>
class OcclusionTrackerTestOverlappingSurfaceSiblings
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(90.0);
    child_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* child1 = this->CreateSurface(
        parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10));
    typename Types::LayerType* child2 = this->CreateSurface(
        parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10));
    typename Types::ContentLayerType* layer1 =
        this->CreateDrawingLayer(child1,
                                 this->identity_matrix,
                                 gfx::PointF(-10.f, -10.f),
                                 gfx::Size(510, 510),
                                 true);
    typename Types::ContentLayerType* layer2 =
        this->CreateDrawingLayer(child2,
                                 this->identity_matrix,
                                 gfx::PointF(-10.f, -10.f),
                                 gfx::Size(510, 510),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer2, &occlusion);
    this->EnterContributingSurface(child2, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 80)));
    EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-11, 420, 70, 80)));
    EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 419, 70, 80)));
    EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 71, 80)));
    EXPECT_TRUE(occlusion.OccludedLayer(child2, gfx::Rect(-10, 420, 70, 81)));

    // There is nothing above child2's surface in the z-order.
    EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child2, false, gfx::Rect(-10, 420, 70, 80), NULL));

    this->LeaveContributingSurface(child2, &occlusion);
    this->VisitLayer(layer1, &occlusion);
    this->EnterContributingSurface(child1, &occlusion, false);

    EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // child2's contents will occlude child1 below it.
    EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child1, false, gfx::Rect(-10, 430, 80, 70), NULL));

    this->LeaveContributingSurface(child1, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70))
                  .ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80)));

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80)));

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70)));

    /* Justification for the above occlusion:
               100
      +---------------------+
      |    20               |       layer1
      |  30+ ---------------------------------+
  100 |  30|                |     layer2      |
      |20+----------------------------------+ |
      |  | |                |               | |
      |  | |                |               | |
      |  | |                |               | |
      +--|-|----------------+               | |
         | |                                | | 510
         | |                                | |
         | |                                | |
         | |                                | |
         | |                                | |
         | |                                | |
         | |                                | |
         | +--------------------------------|-+
         |                                  |
         +----------------------------------+
                         510
     */
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);

template <class Types>
class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform child1_transform;
    child1_transform.Translate(250.0, 250.0);
    child1_transform.Rotate(-90.0);
    child1_transform.Translate(-250.0, -250.0);

    gfx::Transform child2_transform;
    child2_transform.Translate(250.0, 250.0);
    child2_transform.Rotate(90.0);
    child2_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* child1 = this->CreateSurface(
        parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
    typename Types::LayerType* child2 =
        this->CreateDrawingSurface(parent,
                                   child2_transform,
                                   gfx::PointF(20.f, 40.f),
                                   gfx::Size(10, 10),
                                   false);
    typename Types::ContentLayerType* layer1 =
        this->CreateDrawingLayer(child1,
                                 this->identity_matrix,
                                 gfx::PointF(-10.f, -20.f),
                                 gfx::Size(510, 510),
                                 true);
    typename Types::ContentLayerType* layer2 =
        this->CreateDrawingLayer(child2,
                                 this->identity_matrix,
                                 gfx::PointF(-10.f, -10.f),
                                 gfx::Size(510, 510),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(layer2, &occlusion);
    this->EnterLayer(child2, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->LeaveLayer(child2, &occlusion);
    this->EnterContributingSurface(child2, &occlusion, false);

    // There is nothing above child2's surface in the z-order.
    EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child2, false, gfx::Rect(-10, 420, 70, 80), NULL));

    this->LeaveContributingSurface(child2, &occlusion);
    this->VisitLayer(layer1, &occlusion);
    this->EnterContributingSurface(child1, &occlusion, false);

    EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // child2's contents will occlude child1 below it.
    EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child1, false, gfx::Rect(420, -20, 80, 90), NULL));
    EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child1, false, gfx::Rect(420, -10, 80, 90), NULL));
    EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       child1, false, gfx::Rect(420, -20, 70, 90), NULL));

    this->LeaveContributingSurface(child1, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    /* Justification for the above occlusion:
                  100
        +---------------------+
        |20                   |       layer1
       10+----------------------------------+
    100 || 30                 |     layer2  |
        |20+----------------------------------+
        || |                  |             | |
        || |                  |             | |
        || |                  |             | |
        +|-|------------------+             | |
         | |                                | | 510
         | |                            510 | |
         | |                                | |
         | |                                | |
         | |                                | |
         | |                                | |
         | |                520             | |
         +----------------------------------+ |
           |                                  |
           +----------------------------------+
                           510
     */
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);

template <class Types>
class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestFilters(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform layer_transform;
    layer_transform.Translate(250.0, 250.0);
    layer_transform.Rotate(90.0);
    layer_transform.Translate(-250.0, -250.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    parent->SetMasksToBounds(true);
    typename Types::ContentLayerType* blur_layer =
        this->CreateDrawingLayer(parent,
                                 layer_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);
    typename Types::ContentLayerType* opaque_layer =
        this->CreateDrawingLayer(parent,
                                 layer_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);
    typename Types::ContentLayerType* opacity_layer =
        this->CreateDrawingLayer(parent,
                                 layer_transform,
                                 gfx::PointF(30.f, 30.f),
                                 gfx::Size(500, 500),
                                 true);

    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(10.f));
    blur_layer->SetFilters(filters);

    filters.Clear();
    filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
    opaque_layer->SetFilters(filters);

    filters.Clear();
    filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
    opacity_layer->SetFilters(filters);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // Opacity layer won't contribute to occlusion.
    this->VisitLayer(opacity_layer, &occlusion);
    this->EnterContributingSurface(opacity_layer, &occlusion, false);

    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());

    // And has nothing to contribute to its parent surface.
    this->LeaveContributingSurface(opacity_layer, &occlusion);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());

    // Opaque layer will contribute to occlusion.
    this->VisitLayer(opaque_layer, &occlusion);
    this->EnterContributingSurface(opaque_layer, &occlusion, false);

    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // And it gets translated to the parent surface.
    this->LeaveContributingSurface(opaque_layer, &occlusion);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The blur layer needs to throw away any occlusion from outside its
    // subtree.
    this->EnterLayer(blur_layer, &occlusion, false);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());

    // And it won't contribute to occlusion.
    this->LeaveLayer(blur_layer, &occlusion);
    this->EnterContributingSurface(blur_layer, &occlusion, false);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());

    // But the opaque layer's occlusion is preserved on the parent.
    this->LeaveContributingSurface(blur_layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);

template <class Types>
class OcclusionTrackerTestReplicaDoesOcclude
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(0.f, 100.f),
                                   gfx::Size(50, 50),
                                   true);
    this->CreateReplicaLayer(
        surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitContributingSurface(surface, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    // The surface and replica should both be occluding the parent.
    EXPECT_EQ(
        UnionRegions(gfx::Rect(0, 100, 50, 50),
                     gfx::Rect(50, 150, 50, 50)).ToString(),
        occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);

template <class Types>
class OcclusionTrackerTestReplicaWithClipping
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(0.f, 100.f),
                                   gfx::Size(50, 50),
                                   true);
    this->CreateReplicaLayer(
        surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitContributingSurface(surface, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    // The surface and replica should both be occluding the parent.
    EXPECT_EQ(
        UnionRegions(gfx::Rect(0, 100, 50, 50),
                     gfx::Rect(50, 150, 50, 20)).ToString(),
        occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);

template <class Types>
class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(0.f, 100.f),
                                   gfx::Size(50, 50),
                                   true);
    typename Types::LayerType* replica = this->CreateReplicaLayer(
        surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
    this->CreateMaskLayer(replica, gfx::Size(10, 10));
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitContributingSurface(surface, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    // The replica should not be occluding the parent, since it has a mask
    // applied to it.
    EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);

template <class Types>
class OcclusionTrackerTestLayerClipRectOutsideChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerClipRectOutsideChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* clip =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(200.f, 100.f),
                                 gfx::Size(100, 100),
                                 false);
    clip->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(clip,
                                 this->identity_matrix,
                                 gfx::PointF(-200.f, -100.f),
                                 gfx::Size(200, 200),
                                 false);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->EnterLayer(clip, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(-100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, -100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));

    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       clip, gfx::Rect(-100, -100, 300, 300)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOutsideChild);

template <class Types>
class OcclusionTrackerTestViewportRectOutsideChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestViewportRectOutsideChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(200, 100, 100, 100));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));

    EXPECT_RECT_EQ(gfx::Rect(200, 100, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOutsideChild);

template <class Types>
class OcclusionTrackerTestLayerClipRectOverChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerClipRectOverChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* clip =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(100, 100),
                                 false);
    clip->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(clip,
                                   this->identity_matrix,
                                   gfx::PointF(-100.f, -100.f),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);

    EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->EnterLayer(clip, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(0, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(100, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(clip, gfx::Rect(200, 200, 100, 100)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        clip, gfx::Rect(0, 0, 300, 300)).IsEmpty());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectOverChild);

template <class Types>
class OcclusionTrackerTestViewportRectOverChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestViewportRectOverChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(100, 100, 100, 100));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverChild);

template <class Types>
class OcclusionTrackerTestLayerClipRectPartlyOverChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerClipRectPartlyOverChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* clip =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(200, 200),
                                 false);
    clip->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(clip,
                                   this->identity_matrix,
                                   gfx::PointF(-50.f, -50.f),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 50)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 50, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 50)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 50, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(clip, &occlusion, false);

    EXPECT_EQ(gfx::Rect(50, 50, 150, 150).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectPartlyOverChild);

template <class Types>
class OcclusionTrackerTestViewportRectPartlyOverChild
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestViewportRectPartlyOverChild(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(50, 50, 200, 200));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));

    EXPECT_RECT_EQ(gfx::Rect(50, 50, 200, 200),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
    EXPECT_RECT_EQ(gfx::Rect(200, 50, 50, 50),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 100)));
    EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 100, 300, 100)));
    EXPECT_RECT_EQ(gfx::Rect(200, 100, 50, 100),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(200, 100, 100, 100)));
    EXPECT_RECT_EQ(gfx::Rect(100, 200, 100, 50),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(100, 200, 100, 100)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectPartlyOverChild);

template <class Types>
class OcclusionTrackerTestViewportRectOverNothing
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestViewportRectOverNothing(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(500, 500, 100, 100));

    this->EnterLayer(layer, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 100, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 0, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(0, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(100, 200, 100, 100)));
    EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));

    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(0, 0, 300, 300)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(0, 0, 300, 100)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(0, 100, 300, 100)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(200, 100, 100, 100)).IsEmpty());
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        parent, gfx::Rect(100, 200, 100, 100)).IsEmpty());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportRectOverNothing);

template <class Types>
class OcclusionTrackerTestLayerClipRectForLayerOffOrigin
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerClipRectForLayerOffOrigin(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->EnterLayer(layer, &occlusion, false);

    // This layer is translated when drawn into its target. So if the clip rect
    // given from the target surface is not in that target space, then after
    // translating these query rects into the target, they will fall outside the
    // clip and be considered occluded.
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipRectForLayerOffOrigin);

template <class Types>
class OcclusionTrackerTestOpaqueContentsRegionEmpty
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   false);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->EnterLayer(layer, &occlusion, false);

    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100)));
    EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100)));

    // Occluded since its outside the surface bounds.
    EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(200, 100, 100, 100)));

    this->LeaveLayer(layer, &occlusion);
    this->VisitContributingSurface(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
  }
};

MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);

template <class Types>
class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(200, 200),
                                 false);
    this->CalcDrawEtc(parent);
    {
      TestOcclusionTrackerWithClip<typename Types::LayerType,
                                   typename Types::RenderSurfaceType> occlusion(
          gfx::Rect(0, 0, 1000, 1000));
      layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));

      this->ResetLayerIterator();
      this->VisitLayer(layer, &occlusion);
      this->EnterLayer(parent, &occlusion, false);

      EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(),
                occlusion.occlusion_from_inside_target().ToString());

      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
      EXPECT_TRUE(
          occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
    }
    {
      TestOcclusionTrackerWithClip<typename Types::LayerType,
                                   typename Types::RenderSurfaceType> occlusion(
          gfx::Rect(0, 0, 1000, 1000));
      layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));

      this->ResetLayerIterator();
      this->VisitLayer(layer, &occlusion);
      this->EnterLayer(parent, &occlusion, false);

      EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(),
                occlusion.occlusion_from_inside_target().ToString());

      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
      EXPECT_TRUE(
          occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
    }
    {
      TestOcclusionTrackerWithClip<typename Types::LayerType,
                                   typename Types::RenderSurfaceType> occlusion(
          gfx::Rect(0, 0, 1000, 1000));
      layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));

      this->ResetLayerIterator();
      this->VisitLayer(layer, &occlusion);
      this->EnterLayer(parent, &occlusion, false);

      EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(),
                occlusion.occlusion_from_inside_target().ToString());

      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100)));
      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100)));
      EXPECT_FALSE(
          occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100)));
    }
  }
};

MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);

template <class Types>
class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTest3dTransform(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform transform;
    transform.RotateAboutYAxis(30.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::LayerType* container = this->CreateLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(container,
                                 transform,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(200, 200),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->EnterLayer(layer, &occlusion, false);

    // The layer is rotated in 3d but without preserving 3d, so it only gets
    // resized.
    EXPECT_RECT_EQ(
        gfx::Rect(0, 0, 200, 200),
        occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
  }
};

MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform);

template <class Types>
class OcclusionTrackerTestUnsorted3dLayers
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // Currently, The main thread layer iterator does not iterate over 3d items
    // in sorted order, because layer sorting is not performed on the main
    // thread.  Because of this, the occlusion tracker cannot assume that a 3d
    // layer occludes other layers that have not yet been iterated over. For
    // now, the expected behavior is that a 3d layer simply does not add any
    // occlusion to the occlusion tracker.

    gfx::Transform translation_to_front;
    translation_to_front.Translate3d(0.0, 0.0, -10.0);
    gfx::Transform translation_to_back;
    translation_to_front.Translate3d(0.0, 0.0, -100.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
        parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
    typename Types::ContentLayerType* child2 =
        this->CreateDrawingLayer(parent,
                                 translation_to_front,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(100, 100),
                                 true);
    parent->SetPreserves3d(true);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->VisitLayer(child2, &occlusion);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());

    this->VisitLayer(child1, &occlusion);
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
  }
};

// This test will have different layer ordering on the impl thread; the test
// will only work on the main thread.
MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);

template <class Types>
class OcclusionTrackerTestPerspectiveTransform
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform transform;
    transform.Translate(150.0, 150.0);
    transform.ApplyPerspectiveDepth(400.0);
    transform.RotateAboutXAxis(-30.0);
    transform.Translate(-150.0, -150.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::LayerType* container = this->CreateLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(container,
                                 transform,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(200, 200),
                                 true);
    container->SetPreserves3d(true);
    layer->SetPreserves3d(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->EnterLayer(layer, &occlusion, false);

    EXPECT_RECT_EQ(
        gfx::Rect(0, 0, 200, 200),
        occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200)));
  }
};

// This test requires accumulating occlusion of 3d layers, which are skipped by
// the occlusion tracker on the main thread. So this test should run on the impl
// thread.
IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform);

template <class Types>
class OcclusionTrackerTestPerspectiveTransformBehindCamera
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestPerspectiveTransformBehindCamera(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // This test is based on the platform/chromium/compositing/3d-corners.html
    // layout test.
    gfx::Transform transform;
    transform.Translate(250.0, 50.0);
    transform.ApplyPerspectiveDepth(10.0);
    transform.Translate(-250.0, -50.0);
    transform.Translate(250.0, 50.0);
    transform.RotateAboutXAxis(-167.0);
    transform.Translate(-250.0, -50.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(500, 100));
    typename Types::LayerType* container = this->CreateLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
    typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
        container, transform, gfx::PointF(), gfx::Size(500, 500), true);
    container->SetPreserves3d(true);
    layer->SetPreserves3d(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    this->EnterLayer(layer, &occlusion, false);

    // The bottom 11 pixel rows of this layer remain visible inside the
    // container, after translation to the target surface. When translated back,
    // this will include many more pixels but must include at least the bottom
    // 11 rows.
    EXPECT_TRUE(occlusion.UnoccludedLayerContentRect(
        layer, gfx::Rect(0, 0, 500, 500)).Contains(gfx::Rect(0, 489, 500, 11)));
  }
};

// This test requires accumulating occlusion of 3d layers, which are skipped by
// the occlusion tracker on the main thread. So this test should run on the impl
// thread.
IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera);

template <class Types>
class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform transform;
    transform.Translate(50.0, 50.0);
    transform.ApplyPerspectiveDepth(100.0);
    transform.Translate3d(0.0, 0.0, 110.0);
    transform.Translate(-50.0, -50.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
        parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
    parent->SetPreserves3d(true);
    layer->SetPreserves3d(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // The |layer| is entirely behind the camera and should not occlude.
    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);
    EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
    EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
  }
};

// This test requires accumulating occlusion of 3d layers, which are skipped by
// the occlusion tracker on the main thread. So this test should run on the impl
// thread.
IMPL_THREAD_TEST(OcclusionTrackerTestLayerBehindCameraDoesNotOcclude);

template <class Types>
class OcclusionTrackerTestLargePixelsOccludeInsideClipRect
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLargePixelsOccludeInsideClipRect(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform transform;
    transform.Translate(50.0, 50.0);
    transform.ApplyPerspectiveDepth(100.0);
    transform.Translate3d(0.0, 0.0, 99.0);
    transform.Translate(-50.0, -50.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
    parent->SetMasksToBounds(true);
    typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
        parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
    parent->SetPreserves3d(true);
    layer->SetPreserves3d(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // This is very close to the camera, so pixels in its visible_content_rect()
    // will actually go outside of the layer's clip rect.  Ensure that those
    // pixels don't occlude things outside the clip rect.
    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
  }
};

// This test requires accumulating occlusion of 3d layers, which are skipped by
// the occlusion tracker on the main thread. So this test should run on the impl
// thread.
IMPL_THREAD_TEST(OcclusionTrackerTestLargePixelsOccludeInsideClipRect);

template <class Types>
class OcclusionTrackerTestAnimationOpacity1OnMainThread
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // parent
    // +--layer
    // +--surface
    // |  +--surface_child
    // |  +--surface_child2
    // +--parent2
    // +--topmost

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(300, 300),
                                 true);
    typename Types::ContentLayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(300, 300),
                                   true);
    typename Types::ContentLayerType* surface_child =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(200, 300),
                                 true);
    typename Types::ContentLayerType* surface_child2 =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(100, 300),
                                 true);
    typename Types::ContentLayerType* parent2 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(300, 300),
                                 false);
    typename Types::ContentLayerType* topmost =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(250.f, 0.f),
                                 gfx::Size(50, 300),
                                 true);

    AddOpacityTransitionToController(
        layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
    AddOpacityTransitionToController(
        surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
    this->CalcDrawEtc(parent);

    EXPECT_TRUE(layer->draw_opacity_is_animating());
    EXPECT_FALSE(surface->draw_opacity_is_animating());
    EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(topmost, &occlusion);
    this->EnterLayer(parent2, &occlusion, false);
    // This occlusion will affect all surfaces.
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(),
              occlusion.UnoccludedLayerContentRect(
                  parent2, gfx::Rect(0, 0, 300, 300)).ToString());
    this->LeaveLayer(parent2, &occlusion);

    this->VisitLayer(surface_child2, &occlusion);
    this->EnterLayer(surface_child, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface_child, gfx::Rect(0, 0, 200, 300)));
    this->LeaveLayer(surface_child, &occlusion);
    this->EnterLayer(surface, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface, gfx::Rect(0, 0, 300, 300)));
    this->LeaveLayer(surface, &occlusion);

    this->EnterContributingSurface(surface, &occlusion, false);
    // Occlusion within the surface is lost when leaving the animating surface.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 300, 300), NULL));
    this->LeaveContributingSurface(surface, &occlusion);

    // Occlusion from outside the animating surface still exists.
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    // Occlusion is not added for the animating |layer|.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
  }
};

MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);

template <class Types>
class OcclusionTrackerTestAnimationOpacity0OnMainThread
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(300, 300),
                                 true);
    typename Types::ContentLayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(300, 300),
                                   true);
    typename Types::ContentLayerType* surface_child =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(200, 300),
                                 true);
    typename Types::ContentLayerType* surface_child2 =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(100, 300),
                                 true);
    typename Types::ContentLayerType* parent2 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(300, 300),
                                 false);
    typename Types::ContentLayerType* topmost =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(250.f, 0.f),
                                 gfx::Size(50, 300),
                                 true);

    AddOpacityTransitionToController(
        layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
    AddOpacityTransitionToController(
        surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
    this->CalcDrawEtc(parent);

    EXPECT_TRUE(layer->draw_opacity_is_animating());
    EXPECT_FALSE(surface->draw_opacity_is_animating());
    EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(topmost, &occlusion);
    this->EnterLayer(parent2, &occlusion, false);
    // This occlusion will affect all surfaces.
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
    this->LeaveLayer(parent2, &occlusion);

    this->VisitLayer(surface_child2, &occlusion);
    this->EnterLayer(surface_child, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface_child, gfx::Rect(0, 0, 200, 300)));
    this->LeaveLayer(surface_child, &occlusion);
    this->EnterLayer(surface, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface, gfx::Rect(0, 0, 300, 300)));
    this->LeaveLayer(surface, &occlusion);

    this->EnterContributingSurface(surface, &occlusion, false);
    // Occlusion within the surface is lost when leaving the animating surface.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 300, 300), NULL));
    this->LeaveContributingSurface(surface, &occlusion);

    // Occlusion from outside the animating surface still exists.
    EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    this->VisitLayer(layer, &occlusion);
    this->EnterLayer(parent, &occlusion, false);

    // Occlusion is not added for the animating |layer|.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
  }
};

MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);

template <class Types>
class OcclusionTrackerTestAnimationTranslateOnMainThread
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    typename Types::ContentLayerType* layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(300, 300),
                                 true);
    typename Types::ContentLayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(300, 300),
                                   true);
    typename Types::ContentLayerType* surface_child =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(200, 300),
                                 true);
    typename Types::ContentLayerType* surface_child2 =
        this->CreateDrawingLayer(surface,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(100, 300),
                                 true);
    typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);

    AddAnimatedTransformToController(
        layer->layer_animation_controller(), 10.0, 30, 0);
    AddAnimatedTransformToController(
        surface->layer_animation_controller(), 10.0, 30, 0);
    AddAnimatedTransformToController(
        surface_child->layer_animation_controller(), 10.0, 30, 0);
    this->CalcDrawEtc(parent);

    EXPECT_TRUE(layer->draw_transform_is_animating());
    EXPECT_TRUE(layer->screen_space_transform_is_animating());
    EXPECT_TRUE(
        surface->render_surface()->target_surface_transforms_are_animating());
    EXPECT_TRUE(
        surface->render_surface()->screen_space_transforms_are_animating());
    // The surface owning layer doesn't animate against its own surface.
    EXPECT_FALSE(surface->draw_transform_is_animating());
    EXPECT_TRUE(surface->screen_space_transform_is_animating());
    EXPECT_TRUE(surface_child->draw_transform_is_animating());
    EXPECT_TRUE(surface_child->screen_space_transform_is_animating());

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface2, &occlusion);
    this->EnterContributingSurface(surface2, &occlusion, false);

    EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->LeaveContributingSurface(surface2, &occlusion);
    this->EnterLayer(surface_child2, &occlusion, false);

    // surface_child2 is moving in screen space but not relative to its target,
    // so occlusion should happen in its target space only.  It also means that
    // things occluding from outside the target (e.g. surface2) cannot occlude
    // this layer.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface_child2, gfx::Rect(0, 0, 100, 300)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));

    this->LeaveLayer(surface_child2, &occlusion);
    this->EnterLayer(surface_child, &occlusion, false);
    EXPECT_FALSE(
        occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 100, 300)));
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface, gfx::Rect(0, 0, 300, 300)));

    // The surface_child is occluded by the surface_child2, but is moving
    // relative its target, so it can't be occluded.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface_child, gfx::Rect(0, 0, 200, 300)));
    EXPECT_FALSE(
        occlusion.OccludedLayer(surface_child, gfx::Rect(0, 0, 50, 300)));

    this->LeaveLayer(surface_child, &occlusion);
    this->EnterLayer(surface, &occlusion, false);
    // The surface_child is moving in screen space but not relative to its
    // target, so occlusion should happen from within the target only.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300),
                   occlusion.UnoccludedLayerContentRect(
                       surface, gfx::Rect(0, 0, 300, 300)));

    this->LeaveLayer(surface, &occlusion);
    // The surface's owning layer is moving in screen space but not relative to
    // its target, so occlusion should happen within the target only.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
                   occlusion.UnoccludedLayerContentRect(
                       surface, gfx::Rect(0, 0, 300, 300)));

    this->EnterContributingSurface(surface, &occlusion, false);
    // The contributing |surface| is animating so it can't be occluded.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 300, 300), NULL));
    this->LeaveContributingSurface(surface, &occlusion);

    this->EnterLayer(layer, &occlusion, false);
    // The |surface| is moving in the screen and in its target, so all occlusion
    // within the surface is lost when leaving it.
    EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
    this->LeaveLayer(layer, &occlusion);

    this->EnterLayer(parent, &occlusion, false);
    // The |layer| is animating in the screen and in its target, so no occlusion
    // is added.
    EXPECT_RECT_EQ(gfx::Rect(50, 0, 250, 300),
                   occlusion.UnoccludedLayerContentRect(
                       parent, gfx::Rect(0, 0, 300, 300)));
  }
};

MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);

template <class Types>
class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform surface_transform;
    surface_transform.Translate(300.0, 300.0);
    surface_transform.Scale(2.0, 2.0);
    surface_transform.Translate(-150.0, -150.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
    typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
        parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
    typename Types::ContentLayerType* surface2 =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(50.f, 50.f),
                                   gfx::Size(300, 300),
                                   false);
    surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
    surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface2, &occlusion);
    this->VisitContributingSurface(surface2, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // Clear any stored occlusion.
    occlusion.set_occlusion_from_outside_target(Region());
    occlusion.set_occlusion_from_inside_target(Region());

    this->VisitLayer(surface, &occlusion);
    this->VisitContributingSurface(surface, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

MAIN_AND_IMPL_THREAD_TEST(
    OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);

template <class Types>
class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
    parent->SetMasksToBounds(true);
    typename Types::ContentLayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(500, 300),
                                   false);
    surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(surface, &occlusion);
    this->VisitContributingSurface(surface, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

MAIN_AND_IMPL_THREAD_TEST(
    OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);

template <class Types>
class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   true);
    this->CreateReplicaLayer(surface,
                             this->identity_matrix,
                             gfx::PointF(0.f, 100.f),
                             gfx::Size(100, 100));
    typename Types::LayerType* topmost =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 100.f),
                                 gfx::Size(100, 100),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // |topmost| occludes the replica, but not the surface itself.
    this->VisitLayer(topmost, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->EnterContributingSurface(surface, &occlusion, false);

    // Surface is not occluded so it shouldn't think it is.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 100, 100), NULL));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded);

template <class Types>
class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   true);
    this->CreateReplicaLayer(surface,
                             this->identity_matrix,
                             gfx::PointF(0.f, 100.f),
                             gfx::Size(100, 100));
    typename Types::LayerType* topmost =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(100, 110),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // |topmost| occludes the surface, but not the entire surface's replica.
    this->VisitLayer(topmost, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->EnterContributingSurface(surface, &occlusion, false);

    // Surface is occluded, but only the top 10px of the replica.
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 100, 100), NULL));
    EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, true, gfx::Rect(0, 0, 100, 100), NULL));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);

template <class Types>
class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   true);
    this->CreateReplicaLayer(surface,
                             this->identity_matrix,
                             gfx::PointF(0.f, 100.f),
                             gfx::Size(100, 100));
    typename Types::LayerType* over_surface = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true);
    typename Types::LayerType* over_replica =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 100.f),
                                 gfx::Size(50, 100),
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // These occlude the surface and replica differently, so we can test each
    // one.
    this->VisitLayer(over_replica, &occlusion);
    this->VisitLayer(over_surface, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
                  .ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(surface, &occlusion);

    EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100))
                  .ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->EnterContributingSurface(surface, &occlusion, false);

    // Surface and replica are occluded different amounts.
    EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 100, 100), NULL));
    EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, true, gfx::Rect(0, 0, 100, 100), NULL));
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently);

template <class Types>
class OcclusionTrackerTestSurfaceChildOfSurface
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // This test verifies that the surface cliprect does not end up empty and
    // clip away the entire unoccluded rect.

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   true);
    typename Types::LayerType* surface_child =
        this->CreateDrawingSurface(surface,
                                   this->identity_matrix,
                                   gfx::PointF(0.f, 10.f),
                                   gfx::Size(100, 50),
                                   true);
    typename Types::LayerType* topmost = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(-100, -100, 1000, 1000));

    // |topmost| occludes everything partially so we know occlusion is happening
    // at all.
    this->VisitLayer(topmost, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(surface_child, &occlusion);

    // surface_child increases the occlusion in the screen by a narrow sliver.
    EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    // In its own surface, surface_child is at 0,0 as is its occlusion.
    EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The root layer always has a clip rect. So the parent of |surface| has a
    // clip rect. However, the owning layer for |surface| does not mask to
    // bounds, so it doesn't have a clip rect of its own. Thus the parent of
    // |surface_child| exercises different code paths as its parent does not
    // have a clip rect.

    this->EnterContributingSurface(surface_child, &occlusion, false);
    // The surface_child's parent does not have a clip rect as it owns a render
    // surface. Make sure the unoccluded rect does not get clipped away
    // inappropriately.
    EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface_child, false, gfx::Rect(0, 0, 100, 50), NULL));
    this->LeaveContributingSurface(surface_child, &occlusion);

    // When the surface_child's occlusion is transformed up to its parent, make
    // sure it is not clipped away inappropriately also.
    this->EnterLayer(surface, &occlusion, false);
    EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    this->LeaveLayer(surface, &occlusion);

    this->EnterContributingSurface(surface, &occlusion, false);
    // The surface's parent does have a clip rect as it is the root layer.
    EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       surface, false, gfx::Rect(0, 0, 100, 100), NULL));
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);

template <class Types>
class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestTopmostSurfaceIsClippedToViewport(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // This test verifies that the top-most surface is considered occluded
    // outside of its target's clip rect and outside the viewport rect.

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 300),
                                   true);
    this->CalcDrawEtc(parent);
    {
      // Make a viewport rect that is larger than the root layer.
      TestOcclusionTrackerWithClip<typename Types::LayerType,
                                   typename Types::RenderSurfaceType> occlusion(
          gfx::Rect(0, 0, 1000, 1000));

      this->VisitLayer(surface, &occlusion);

      // The root layer always has a clip rect. So the parent of |surface| has a
      // clip rect giving the surface itself a clip rect.
      this->EnterContributingSurface(surface, &occlusion, false);
      // Make sure the parent's clip rect clips the unoccluded region of the
      // child surface.
      EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200),
                     occlusion.UnoccludedContributingSurfaceContentRect(
                         surface, false, gfx::Rect(0, 0, 100, 300), NULL));
    }
    this->ResetLayerIterator();
    {
      // Make a viewport rect that is smaller than the root layer.
      TestOcclusionTrackerWithClip<typename Types::LayerType,
                                   typename Types::RenderSurfaceType> occlusion(
          gfx::Rect(0, 0, 100, 100));

      this->VisitLayer(surface, &occlusion);

      // The root layer always has a clip rect. So the parent of |surface| has a
      // clip rect giving the surface itself a clip rect.
      this->EnterContributingSurface(surface, &occlusion, false);
      // Make sure the viewport rect clips the unoccluded region of the child
      // surface.
      EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                     occlusion.UnoccludedContributingSurfaceContentRect(
                         surface, false, gfx::Rect(0, 0, 100, 300), NULL));
    }
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestTopmostSurfaceIsClippedToViewport);

template <class Types>
class OcclusionTrackerTestSurfaceChildOfClippingSurface
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestSurfaceChildOfClippingSurface(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // This test verifies that the surface cliprect does not end up empty and
    // clip away the entire unoccluded rect.

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(80, 200));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   true);
    typename Types::LayerType* surface_child =
        this->CreateDrawingSurface(surface,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   false);
    typename Types::LayerType* topmost = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // |topmost| occludes everything partially so we know occlusion is happening
    // at all.
    this->VisitLayer(topmost, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // surface_child is not opaque and does not occlude, so we have a non-empty
    // unoccluded area on surface.
    this->VisitLayer(surface_child, &occlusion);

    EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The root layer always has a clip rect. So the parent of |surface| has a
    // clip rect. However, the owning layer for |surface| does not mask to
    // bounds, so it doesn't have a clip rect of its own. Thus the parent of
    // |surface_child| exercises different code paths as its parent does not
    // have a clip rect.

    this->EnterContributingSurface(surface_child, &occlusion, false);
    // The surface_child's parent does not have a clip rect as it owns a render
    // surface.
    EXPECT_EQ(
        gfx::Rect(0, 50, 80, 50).ToString(),
        occlusion.UnoccludedContributingSurfaceContentRect(
            surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
    this->LeaveContributingSurface(surface_child, &occlusion);

    this->VisitLayer(surface, &occlusion);
    this->EnterContributingSurface(surface, &occlusion, false);
    // The surface's parent does have a clip rect as it is the root layer.
    EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(),
              occlusion.UnoccludedContributingSurfaceContentRect(
                  surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfClippingSurface);

template <class Types>
class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_by_half;
    scale_by_half.Scale(0.5, 0.5);

    // Make a surface and its replica, each 50x50, that are completely
    // surrounded by opaque layers which are above them in the z-order.  The
    // surface is scaled to test that the pixel moving is done in the target
    // space, where the background filter is applied, but the surface appears at
    // 50, 50 and the replica at 200, 50.
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
    typename Types::LayerType* filtered_surface =
        this->CreateDrawingLayer(parent,
                                 scale_by_half,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(100, 100),
                                 false);
    this->CreateReplicaLayer(filtered_surface,
                             this->identity_matrix,
                             gfx::PointF(300.f, 0.f),
                             gfx::Size());
    typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
    typename Types::LayerType* occluding_layer2 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 100.f),
                                 gfx::Size(300, 50),
                                 true);
    typename Types::LayerType* occluding_layer3 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);
    typename Types::LayerType* occluding_layer4 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 50.f),
                                 gfx::Size(100, 50),
                                 true);
    typename Types::LayerType* occluding_layer5 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(250.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);

    // Filters make the layer own a surface.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(10.f));
    filtered_surface->SetBackgroundFilters(filters);

    // Save the distance of influence for the blur effect.
    int outset_top, outset_right, outset_bottom, outset_left;
    filters.GetOutsets(
        &outset_top, &outset_right, &outset_bottom, &outset_left);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // These layers occlude pixels directly beside the filtered_surface. Because
    // filtered surface blends pixels in a radius, it will need to see some of
    // the pixels (up to radius far) underneath the occluding layers.
    this->VisitLayer(occluding_layer5, &occlusion);
    this->VisitLayer(occluding_layer4, &occlusion);
    this->VisitLayer(occluding_layer3, &occlusion);
    this->VisitLayer(occluding_layer2, &occlusion);
    this->VisitLayer(occluding_layer1, &occlusion);

    Region expected_occlusion;
    expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
    expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
    expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
    expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
    expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));

    EXPECT_EQ(expected_occlusion.ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    this->VisitLayer(filtered_surface, &occlusion);

    // The filtered layer/replica does not occlude.
    Region expected_occlusion_outside_surface;
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));

    EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The surface has a background blur, so it needs pixels that are currently
    // considered occluded in order to be drawn. So the pixels it needs should
    // be removed some the occluded area so that when we get to the parent they
    // are drawn.
    this->VisitContributingSurface(filtered_surface, &occlusion);

    this->EnterLayer(parent, &occlusion, false);

    Region expected_blurred_occlusion;
    expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
    expected_blurred_occlusion.Union(gfx::Rect(
        0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(
        gfx::Rect(100 + outset_right,
                  50 - outset_top,
                  100 - outset_right - outset_left,
                  50 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(
        gfx::Rect(250 + outset_right,
                  50 - outset_top,
                  50 - outset_right,
                  50 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(
        gfx::Rect(0, 100 + outset_bottom, 300, 50 - outset_bottom));

    EXPECT_EQ(expected_blurred_occlusion.ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    gfx::Rect outset_rect;
    gfx::Rect test_rect;

    // Nothing in the blur outsets for the filtered_surface is occluded.
    outset_rect = gfx::Rect(50 - outset_left,
                            50 - outset_top,
                            50 + outset_left + outset_right,
                            50 + outset_top + outset_bottom);
    test_rect = outset_rect;
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());

    // Stuff outside the blur outsets is still occluded though.
    test_rect = outset_rect;
    test_rect.Inset(0, 0, -1, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(0, 0, 0, -1);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(-1, 0, 0, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(0, -1, 0, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());

    // Nothing in the blur outsets for the filtered_surface's replica is
    // occluded.
    outset_rect = gfx::Rect(200 - outset_left,
                            50 - outset_top,
                            50 + outset_left + outset_right,
                            50 + outset_top + outset_bottom);
    test_rect = outset_rect;
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());

    // Stuff outside the blur outsets is still occluded though.
    test_rect = outset_rect;
    test_rect.Inset(0, 0, -1, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(0, 0, 0, -1);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(-1, 0, 0, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
    test_rect = outset_rect;
    test_rect.Inset(0, -1, 0, 0);
    EXPECT_EQ(
        outset_rect.ToString(),
        occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);

template <class Types>
class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_by_half;
    scale_by_half.Scale(0.5, 0.5);

    // Makes two surfaces that completely cover |parent|. The occlusion both
    // above and below the filters will be reduced by each of them.
    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
    typename Types::LayerType* parent = this->CreateSurface(
        root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
    parent->SetMasksToBounds(true);
    typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
        parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
    typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
        parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
    typename Types::LayerType* occluding_layer_above =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 100.f),
                                 gfx::Size(50, 50),
                                 true);

    // Filters make the layers own surfaces.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(1.f));
    filtered_surface1->SetBackgroundFilters(filters);
    filtered_surface2->SetBackgroundFilters(filters);

    // Save the distance of influence for the blur effect.
    int outset_top, outset_right, outset_bottom, outset_left;
    filters.GetOutsets(
        &outset_top, &outset_right, &outset_bottom, &outset_left);

    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(occluding_layer_above, &occlusion);
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    this->VisitLayer(filtered_surface2, &occlusion);
    this->VisitContributingSurface(filtered_surface2, &occlusion);
    this->VisitLayer(filtered_surface1, &occlusion);
    this->VisitContributingSurface(filtered_surface1, &occlusion);

    // Test expectations in the target.
    gfx::Rect expected_occlusion =
        gfx::Rect(100 / 2 + outset_right * 2,
                  100 / 2 + outset_bottom * 2,
                  50 / 2 - (outset_left + outset_right) * 2,
                  50 / 2 - (outset_top + outset_bottom) * 2);
    EXPECT_EQ(expected_occlusion.ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // Test expectations in the screen are the same as in the target, as the
    // render surface is 1:1 with the screen.
    EXPECT_EQ(expected_occlusion.ToString(),
              occlusion.occlusion_from_outside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);

template <class Types>
class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit
  OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    // Make a surface and its replica, Each 50x50, that are completely
    // surrounded by opaque layers which are above them in the z-order.
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
    // We stick the filtered surface inside a clipping surface so that we can
    // make sure the clip is honored when exposing pixels for
    // the background filter.
    typename Types::LayerType* clipping_surface =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(300, 70),
                                   false);
    clipping_surface->SetMasksToBounds(true);
    typename Types::LayerType* filtered_surface =
        this->CreateDrawingLayer(clipping_surface,
                                 this->identity_matrix,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(50, 50),
                                 false);
    this->CreateReplicaLayer(filtered_surface,
                             this->identity_matrix,
                             gfx::PointF(150.f, 0.f),
                             gfx::Size());
    typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 50), true);
    typename Types::LayerType* occluding_layer2 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 100.f),
                                 gfx::Size(300, 50),
                                 true);
    typename Types::LayerType* occluding_layer3 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(0.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);
    typename Types::LayerType* occluding_layer4 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(100.f, 50.f),
                                 gfx::Size(100, 50),
                                 true);
    typename Types::LayerType* occluding_layer5 =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(250.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);

    // Filters make the layer own a surface. This filter is large enough that it
    // goes outside the bottom of the clipping_surface.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(12.f));
    filtered_surface->SetBackgroundFilters(filters);

    // Save the distance of influence for the blur effect.
    int outset_top, outset_right, outset_bottom, outset_left;
    filters.GetOutsets(
        &outset_top, &outset_right, &outset_bottom, &outset_left);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // These layers occlude pixels directly beside the filtered_surface. Because
    // filtered surface blends pixels in a radius, it will need to see some of
    // the pixels (up to radius far) underneath the occluding layers.
    this->VisitLayer(occluding_layer5, &occlusion);
    this->VisitLayer(occluding_layer4, &occlusion);
    this->VisitLayer(occluding_layer3, &occlusion);
    this->VisitLayer(occluding_layer2, &occlusion);
    this->VisitLayer(occluding_layer1, &occlusion);

    Region expected_occlusion;
    expected_occlusion.Union(gfx::Rect(0, 0, 300, 50));
    expected_occlusion.Union(gfx::Rect(0, 50, 50, 50));
    expected_occlusion.Union(gfx::Rect(100, 50, 100, 50));
    expected_occlusion.Union(gfx::Rect(250, 50, 50, 50));
    expected_occlusion.Union(gfx::Rect(0, 100, 300, 50));

    EXPECT_EQ(expected_occlusion.ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    // Everything outside the surface/replica is occluded but the
    // surface/replica itself is not.
    this->VisitLayer(filtered_surface, &occlusion);

    // The filtered layer/replica does not occlude.
    Region expected_occlusion_outside_surface;
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 300, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(200, 0, 50, 50));
    expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 300, 50));

    EXPECT_EQ(expected_occlusion_outside_surface.ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The surface has a background blur, so it needs pixels that are currently
    // considered occluded in order to be drawn. So the pixels it needs should
    // be removed some the occluded area so that when we get to the parent they
    // are drawn.
    this->VisitContributingSurface(filtered_surface, &occlusion);

    this->VisitLayer(clipping_surface, &occlusion);
    this->EnterContributingSurface(clipping_surface, &occlusion, false);

    Region expected_blurred_occlusion;
    expected_blurred_occlusion.Union(gfx::Rect(0, 0, 300, 50 - outset_top));
    expected_blurred_occlusion.Union(gfx::Rect(
        0, 50 - outset_top, 50 - outset_left, 20 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(
        gfx::Rect(100 + outset_right,
                  50 - outset_top,
                  100 - outset_right - outset_left,
                  20 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(
        gfx::Rect(250 + outset_right,
                  50 - outset_top,
                  50 - outset_right,
                  20 + outset_top + outset_bottom));
    expected_blurred_occlusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5));

    EXPECT_EQ(expected_blurred_occlusion.ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    gfx::Rect outset_rect;
    gfx::Rect clipped_outset_rect;
    gfx::Rect test_rect;

    // Nothing in the (clipped) blur outsets for the filtered_surface is
    // occluded.
    outset_rect = gfx::Rect(50 - outset_left,
                            50 - outset_top,
                            50 + outset_left + outset_right,
                            50 + outset_top + outset_bottom);
    clipped_outset_rect = outset_rect;
    clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
                                            0 - outset_top,
                                            300 + outset_left + outset_right,
                                            70 + outset_top + outset_bottom));
    clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
    test_rect = outset_rect;
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));

    // Stuff outside the (clipped) blur outsets is still occluded though.
    test_rect = outset_rect;
    test_rect.Inset(0, 0, -1, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(0, 0, 0, -1);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(-1, 0, 0, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(0, -1, 0, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));

    // Nothing in the (clipped) blur outsets for the filtered_surface's replica
    // is occluded.
    outset_rect = gfx::Rect(200 - outset_left,
                            50 - outset_top,
                            50 + outset_left + outset_right,
                            50 + outset_top + outset_bottom);
    clipped_outset_rect = outset_rect;
    clipped_outset_rect.Intersect(gfx::Rect(0 - outset_left,
                                            0 - outset_top,
                                            300 + outset_left + outset_right,
                                            70 + outset_top + outset_bottom));
    clipped_outset_rect.Intersect(gfx::Rect(0, 0, 300, 70));
    test_rect = outset_rect;
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));

    // Stuff outside the (clipped) blur outsets is still occluded though.
    test_rect = outset_rect;
    test_rect.Inset(0, 0, -1, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(0, 0, 0, -1);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(-1, 0, 0, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
    test_rect = outset_rect;
    test_rect.Inset(0, -1, 0, 0);
    EXPECT_RECT_EQ(
        clipped_outset_rect,
        occlusion.UnoccludedLayerContentRect(clipping_surface, test_rect));
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip);

template <class Types>
class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_by_half;
    scale_by_half.Scale(0.5, 0.5);

    // Make a surface and its replica, each 50x50, with a smaller 30x30 layer
    // centered below each.  The surface is scaled to test that the pixel moving
    // is done in the target space, where the background filter is applied, but
    // the surface appears at 50, 50 and the replica at 200, 50.
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
    typename Types::LayerType* behind_surface_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(60.f, 60.f),
                                 gfx::Size(30, 30),
                                 true);
    typename Types::LayerType* behind_replica_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(210.f, 60.f),
                                 gfx::Size(30, 30),
                                 true);
    typename Types::LayerType* filtered_surface =
        this->CreateDrawingLayer(parent,
                                 scale_by_half,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(100, 100),
                                 false);
    this->CreateReplicaLayer(filtered_surface,
                             this->identity_matrix,
                             gfx::PointF(300.f, 0.f),
                             gfx::Size());

    // Filters make the layer own a surface.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(3.f));
    filtered_surface->SetBackgroundFilters(filters);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    // The surface has a background blur, so it blurs non-opaque pixels below
    // it.
    this->VisitLayer(filtered_surface, &occlusion);
    this->VisitContributingSurface(filtered_surface, &occlusion);

    this->VisitLayer(behind_replica_layer, &occlusion);
    this->VisitLayer(behind_surface_layer, &occlusion);

    // The layers behind the surface are not blurred, and their occlusion does
    // not change, until we leave the surface.  So it should not be modified by
    // the filter here.
    gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30);
    gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30);

    Region expected_opaque_bounds =
        UnionRegions(occlusion_behind_surface, occlusion_behind_replica);
    EXPECT_EQ(expected_opaque_bounds.ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);

template <class Types>
class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_by_half;
    scale_by_half.Scale(0.5, 0.5);

    // Make a surface and its replica, each 50x50, that are completely occluded
    // by opaque layers which are above them in the z-order.  The surface is
    // scaled to test that the pixel moving is done in the target space, where
    // the background filter is applied, but the surface appears at 50, 50 and
    // the replica at 200, 50.
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
    typename Types::LayerType* filtered_surface =
        this->CreateDrawingLayer(parent,
                                 scale_by_half,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(100, 100),
                                 false);
    this->CreateReplicaLayer(filtered_surface,
                             this->identity_matrix,
                             gfx::PointF(300.f, 0.f),
                             gfx::Size());
    typename Types::LayerType* above_surface_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);
    typename Types::LayerType* above_replica_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(200.f, 50.f),
                                 gfx::Size(50, 50),
                                 true);

    // Filters make the layer own a surface.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(3.f));
    filtered_surface->SetBackgroundFilters(filters);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(above_replica_layer, &occlusion);
    this->VisitLayer(above_surface_layer, &occlusion);

    this->VisitLayer(filtered_surface, &occlusion);
    {
      // The layers above the filtered surface occlude from outside.
      gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50);
      gfx::Rect occlusion_above_replica = gfx::Rect(150, 0, 50, 50);
      Region expected_opaque_region =
          UnionRegions(occlusion_above_surface, occlusion_above_replica);

      EXPECT_EQ(gfx::Rect().ToString(),
                occlusion.occlusion_from_inside_target().ToString());
      EXPECT_EQ(expected_opaque_region.ToString(),
                occlusion.occlusion_from_outside_target().ToString());
    }

    // The surface has a background blur, so it blurs non-opaque pixels below
    // it.
    this->VisitContributingSurface(filtered_surface, &occlusion);
    {
      // The filter is completely occluded, so it should not blur anything and
      // reduce any occlusion.
      gfx::Rect occlusion_above_surface = gfx::Rect(50, 50, 50, 50);
      gfx::Rect occlusion_above_replica = gfx::Rect(200, 50, 50, 50);
      Region expected_opaque_region =
          UnionRegions(occlusion_above_surface, occlusion_above_replica);

      EXPECT_EQ(expected_opaque_region.ToString(),
                occlusion.occlusion_from_inside_target().ToString());
      EXPECT_EQ(gfx::Rect().ToString(),
                occlusion.occlusion_from_outside_target().ToString());
    }
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);

template <class Types>
class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit
  OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_by_half;
    scale_by_half.Scale(0.5, 0.5);

    // Make a surface and its replica, each 50x50, that are partially occluded
    // by opaque layers which are above them in the z-order.  The surface is
    // scaled to test that the pixel moving is done in the target space, where
    // the background filter is applied, but the surface appears at 50, 50 and
    // the replica at 200, 50.
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
    typename Types::LayerType* filtered_surface =
        this->CreateDrawingLayer(parent,
                                 scale_by_half,
                                 gfx::PointF(50.f, 50.f),
                                 gfx::Size(100, 100),
                                 false);
    this->CreateReplicaLayer(filtered_surface,
                             this->identity_matrix,
                             gfx::PointF(300.f, 0.f),
                             gfx::Size());
    typename Types::LayerType* above_surface_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(70.f, 50.f),
                                 gfx::Size(30, 50),
                                 true);
    typename Types::LayerType* above_replica_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(200.f, 50.f),
                                 gfx::Size(30, 50),
                                 true);
    typename Types::LayerType* beside_surface_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(90.f, 40.f),
                                 gfx::Size(10, 10),
                                 true);
    typename Types::LayerType* beside_replica_layer =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(200.f, 40.f),
                                 gfx::Size(10, 10),
                                 true);

    // Filters make the layer own a surface.
    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(3.f));
    filtered_surface->SetBackgroundFilters(filters);

    // Save the distance of influence for the blur effect.
    int outset_top, outset_right, outset_bottom, outset_left;
    filters.GetOutsets(
        &outset_top, &outset_right, &outset_bottom, &outset_left);

    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(beside_replica_layer, &occlusion);
    this->VisitLayer(beside_surface_layer, &occlusion);
    this->VisitLayer(above_replica_layer, &occlusion);
    this->VisitLayer(above_surface_layer, &occlusion);

    // The surface has a background blur, so it blurs non-opaque pixels below
    // it.
    this->VisitLayer(filtered_surface, &occlusion);
    this->VisitContributingSurface(filtered_surface, &occlusion);

    // The filter in the surface and replica are partially unoccluded. Only the
    // unoccluded parts should reduce occlusion.  This means it will push back
    // the occlusion that touches the unoccluded part (occlusion_above___), but
    // it will not touch occlusion_beside____ since that is not beside the
    // unoccluded part of the surface, even though it is beside the occluded
    // part of the surface.
    gfx::Rect occlusion_above_surface =
        gfx::Rect(70 + outset_right, 50, 30 - outset_right, 50);
    gfx::Rect occlusion_above_replica =
        gfx::Rect(200, 50, 30 - outset_left, 50);
    gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10);
    gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10);

    Region expected_occlusion;
    expected_occlusion.Union(occlusion_above_surface);
    expected_occlusion.Union(occlusion_above_replica);
    expected_occlusion.Union(occlusion_beside_surface);
    expected_occlusion.Union(occlusion_beside_replica);

    ASSERT_EQ(expected_occlusion.ToString(),
              occlusion.occlusion_from_inside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());

    Region::Iterator expected_rects(expected_occlusion);
    Region::Iterator target_surface_rects(
        occlusion.occlusion_from_inside_target());
    for (; expected_rects.has_rect();
         expected_rects.next(), target_surface_rects.next()) {
      ASSERT_TRUE(target_surface_rects.has_rect());
      EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect());
    }
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);

template <class Types>
class OcclusionTrackerTestMinimumTrackingSize
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Size tracking_size(100, 100);
    gfx::Size below_tracking_size(99, 99);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* large = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
    typename Types::LayerType* small =
        this->CreateDrawingLayer(parent,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 below_tracking_size,
                                 true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    occlusion.set_minimum_tracking_size(tracking_size);

    // The small layer is not tracked because it is too small.
    this->VisitLayer(small, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // The large layer is tracked as it is large enough.
    this->VisitLayer(large, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(tracking_size).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);

template <class Types>
class OcclusionTrackerTestViewportClipIsExternalOcclusion
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestViewportClipIsExternalOcclusion(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* small =
        this->CreateDrawingSurface(parent,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   false);
    typename Types::LayerType* large =
        this->CreateDrawingLayer(small,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(400, 400),
                                 false);
    small->SetMasksToBounds(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 100, 100));

    this->EnterLayer(large, &occlusion, false);

    bool has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       large,
                       gfx::Rect(0, 0, 400, 400),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_FALSE(
        occlusion.OccludedLayer(large,
                                gfx::Rect(0, 0, 400, 400),
                                &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    this->LeaveLayer(large, &occlusion);
    this->VisitLayer(small, &occlusion);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       small,
                       gfx::Rect(0, 0, 200, 200),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_FALSE(
        occlusion.OccludedLayer(small,
                                gfx::Rect(0, 0, 200, 200),
                                &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    this->EnterContributingSurface(small, &occlusion, false);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       small,
                       false,
                       gfx::Rect(0, 0, 200, 200),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestViewportClipIsExternalOcclusion)

template <class Types>
class OcclusionTrackerTestLayerClipIsExternalOcclusion
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* smallest = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* smaller =
        this->CreateDrawingSurface(smallest,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(100, 100),
                                   false);
    typename Types::LayerType* small =
        this->CreateDrawingSurface(smaller,
                                   this->identity_matrix,
                                   gfx::PointF(),
                                   gfx::Size(200, 200),
                                   false);
    typename Types::LayerType* large =
        this->CreateDrawingLayer(small,
                                 this->identity_matrix,
                                 gfx::PointF(),
                                 gfx::Size(400, 400),
                                 false);
    smallest->SetMasksToBounds(true);
    smaller->SetMasksToBounds(true);
    small->SetMasksToBounds(true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->EnterLayer(large, &occlusion, false);

    // Clipping from the smaller layer is from outside the target surface.
    bool has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       large,
                       gfx::Rect(0, 0, 400, 400),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_FALSE(
        occlusion.OccludedLayer(large,
                                gfx::Rect(0, 0, 400, 400),
                                &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    this->LeaveLayer(large, &occlusion);
    this->VisitLayer(small, &occlusion);

    // Clipping from the smaller layer is from outside the target surface.
    has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
                   occlusion.UnoccludedLayerContentRect(
                       small,
                       gfx::Rect(0, 0, 200, 200),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    has_occlusion_from_outside_target_surface = false;
    EXPECT_FALSE(
        occlusion.OccludedLayer(small,
                                gfx::Rect(0, 0, 200, 200),
                                &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    this->EnterContributingSurface(small, &occlusion, false);

    // The |small| surface is clipped from outside its target by |smallest|.
    has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       small,
                       false,
                       gfx::Rect(0, 0, 200, 200),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_TRUE(has_occlusion_from_outside_target_surface);

    this->LeaveContributingSurface(small, &occlusion);
    this->VisitLayer(smaller, &occlusion);
    this->EnterContributingSurface(smaller, &occlusion, false);

    // The |smaller| surface is clipped from inside its target by |smallest|.
    has_occlusion_from_outside_target_surface = false;
    EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50),
                   occlusion.UnoccludedContributingSurfaceContentRect(
                       smaller,
                       false,
                       gfx::Rect(0, 0, 100, 100),
                       &has_occlusion_from_outside_target_surface));
    EXPECT_FALSE(has_occlusion_from_outside_target_surface);
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion)

template <class Types>
class OcclusionTrackerTestPreventOcclusionOnLayer
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestPreventOcclusionOnLayer(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* unprevented = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* prevented = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* occluding = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    bool external_occlusion = false;

    this->VisitLayer(occluding, &occlusion);
    this->EnterLayer(prevented, &occlusion, true);

    // This layer is not occluded because it is prevented.
    EXPECT_FALSE(occlusion.OccludedLayer(prevented,
                                         gfx::Rect(50, 50),
                                         &external_occlusion));
    EXPECT_FALSE(external_occlusion);

    EXPECT_EQ(gfx::Rect(50, 50).ToString(),
              occlusion.UnoccludedLayerContentRect(
                  prevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveLayer(prevented, &occlusion);
    this->EnterLayer(unprevented, &occlusion, false);

    // This layer is fully occluded.
    EXPECT_TRUE(occlusion.OccludedLayer(unprevented,
                                        gfx::Rect(50, 50),
                                        &external_occlusion));
    EXPECT_FALSE(external_occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.UnoccludedLayerContentRect(
                  unprevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveLayer(unprevented, &occlusion);
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionOnLayer)

template <class Types>
class OcclusionTrackerTestPreventOcclusionOnContributingSurface
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestPreventOcclusionOnContributingSurface(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* unprevented = this->CreateDrawingSurface(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* prevented = this->CreateDrawingSurface(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* occluding = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));
    bool external_occlusion = false;

    this->VisitLayer(occluding, &occlusion);
    this->EnterLayer(prevented, &occlusion, true);

    // This layer is not occluded because it is prevented.
    EXPECT_EQ(gfx::Rect(50, 50).ToString(),
              occlusion.UnoccludedLayerContentRect(
                  prevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveLayer(prevented, &occlusion);
    this->EnterContributingSurface(prevented, &occlusion, true);

    // This contributing surface is not occluded because it is prevented.
    EXPECT_EQ(gfx::Rect(50, 50).ToString(),
              occlusion.UnoccludedContributingSurfaceContentRect(
                  prevented,
                  false,  // is_replica
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveContributingSurface(prevented, &occlusion);
    this->EnterLayer(unprevented, &occlusion, false);

    // This layer is fully occluded from outside its surface.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.UnoccludedLayerContentRect(
                  unprevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_TRUE(external_occlusion);

    this->LeaveLayer(unprevented, &occlusion);
    this->EnterContributingSurface(unprevented, &occlusion, false);

    // This contributing surface is fully occluded.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.UnoccludedContributingSurfaceContentRect(
                  unprevented,
                  false,  // is_replica
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveContributingSurface(unprevented, &occlusion);
  }
};

ALL_OCCLUSIONTRACKER_TEST(
    OcclusionTrackerTestPreventOcclusionOnContributingSurface)

template <class Types>
class OcclusionTrackerTestPreventOcclusionByClipping
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestPreventOcclusionByClipping(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* unprevented = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    typename Types::LayerType* prevented = this->CreateDrawingLayer(
        parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 10, 10));
    bool external_occlusion = false;

    this->EnterLayer(prevented, &occlusion, true);

    // This layer is not occluded because it is prevented.
    EXPECT_FALSE(occlusion.OccludedLayer(prevented,
                                         gfx::Rect(50, 50),
                                         &external_occlusion));
    EXPECT_FALSE(external_occlusion);

    EXPECT_EQ(gfx::Rect(50, 50).ToString(),
              occlusion.UnoccludedLayerContentRect(
                  prevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_FALSE(external_occlusion);

    this->LeaveLayer(prevented, &occlusion);
    this->EnterLayer(unprevented, &occlusion, false);

    // This layer is clipped by the screen space clip rect.
    EXPECT_EQ(gfx::Rect(10, 10).ToString(),
              occlusion.UnoccludedLayerContentRect(
                  unprevented,
                  gfx::Rect(50, 50),
                  &external_occlusion).ToString());
    EXPECT_TRUE(external_occlusion);

    this->LeaveLayer(unprevented, &occlusion);
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestPreventOcclusionByClipping)

template <class Types>
class OcclusionTrackerTestScaledLayerIsClipped
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_transform;
    scale_transform.Scale(512.0, 512.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* clip = this->CreateLayer(parent,
                                                        this->identity_matrix,
                                                        gfx::PointF(10.f, 10.f),
                                                        gfx::Size(50, 50));
    clip->SetMasksToBounds(true);
    typename Types::LayerType* scale = this->CreateLayer(
        clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
    typename Types::LayerType* scaled = this->CreateDrawingLayer(
        scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(scaled, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)

template <class Types>
class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    gfx::Transform scale_transform;
    scale_transform.Scale(512.0, 512.0);

    typename Types::ContentLayerType* parent = this->CreateRoot(
        this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
    typename Types::LayerType* clip = this->CreateLayer(parent,
                                                        this->identity_matrix,
                                                        gfx::PointF(10.f, 10.f),
                                                        gfx::Size(50, 50));
    clip->SetMasksToBounds(true);
    typename Types::LayerType* surface = this->CreateDrawingSurface(
        clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
    typename Types::LayerType* scale = this->CreateLayer(
        surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
    typename Types::LayerType* scaled = this->CreateDrawingLayer(
        scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
    this->CalcDrawEtc(parent);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(scaled, &occlusion);
    this->VisitLayer(surface, &occlusion);
    this->VisitContributingSurface(surface, &occlusion);

    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)

template <class Types>
class OcclusionTrackerTestCopyRequestDoesOcclude
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
    typename Types::LayerType* copy = this->CreateLayer(parent,
                                                        this->identity_matrix,
                                                        gfx::Point(100, 0),
                                                        gfx::Size(200, 400));
    this->AddCopyRequest(copy);
    typename Types::LayerType* copy_child = this->CreateDrawingLayer(
        copy,
        this->identity_matrix,
        gfx::PointF(),
        gfx::Size(200, 400),
        true);
    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(copy_child, &occlusion);
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(200, 400).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // CopyRequests cause the layer to own a surface.
    this->VisitContributingSurface(copy, &occlusion);

    // The occlusion from the copy should be kept.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(100, 0, 200, 400).ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)

template <class Types>
class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
    : public OcclusionTrackerTest<Types> {
 protected:
  explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
      bool opaque_layers)
      : OcclusionTrackerTest<Types>(opaque_layers) {}
  void RunMyTest() {
    typename Types::ContentLayerType* root = this->CreateRoot(
        this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
    typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
        root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
    typename Types::LayerType* hide = this->CreateLayer(
        parent, this->identity_matrix, gfx::Point(), gfx::Size());
    typename Types::LayerType* copy = this->CreateLayer(
        hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
    this->AddCopyRequest(copy);
    typename Types::LayerType* copy_child = this->CreateDrawingLayer(
        copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);

    // The |copy| layer is hidden but since it is being copied, it will be
    // drawn.
    hide->SetHideLayerAndSubtree(true);

    this->CalcDrawEtc(root);

    TestOcclusionTrackerWithClip<typename Types::LayerType,
                                 typename Types::RenderSurfaceType> occlusion(
        gfx::Rect(0, 0, 1000, 1000));

    this->VisitLayer(copy_child, &occlusion);
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect(200, 400).ToString(),
              occlusion.occlusion_from_inside_target().ToString());

    // CopyRequests cause the layer to own a surface.
    this->VisitContributingSurface(copy, &occlusion);

    // The occlusion from the copy should be dropped since it is hidden.
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_outside_target().ToString());
    EXPECT_EQ(gfx::Rect().ToString(),
              occlusion.occlusion_from_inside_target().ToString());
  }
};

ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)

}  // namespace
}  // namespace cc
