delegated_renderer_layer_impl_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/layers/delegated_renderer_layer_impl.h"
6
7#include "cc/base/scoped_ptr_vector.h"
8#include "cc/layers/quad_sink.h"
9#include "cc/layers/solid_color_layer_impl.h"
10#include "cc/quads/render_pass_draw_quad.h"
11#include "cc/quads/solid_color_draw_quad.h"
12#include "cc/test/fake_delegated_renderer_layer_impl.h"
13#include "cc/test/fake_layer_tree_host_impl.h"
14#include "cc/test/fake_layer_tree_host_impl_client.h"
15#include "cc/test/fake_output_surface.h"
16#include "cc/test/fake_proxy.h"
17#include "cc/test/fake_rendering_stats_instrumentation.h"
18#include "cc/test/geometry_test_utils.h"
19#include "cc/test/layer_test_common.h"
20#include "cc/test/mock_quad_culler.h"
21#include "cc/test/render_pass_test_common.h"
22#include "cc/test/render_pass_test_utils.h"
23#include "cc/test/test_shared_bitmap_manager.h"
24#include "cc/test/test_web_graphics_context_3d.h"
25#include "cc/trees/layer_tree_host_impl.h"
26#include "cc/trees/layer_tree_impl.h"
27#include "cc/trees/single_thread_proxy.h"
28#include "testing/gtest/include/gtest/gtest.h"
29#include "ui/gfx/frame_time.h"
30#include "ui/gfx/transform.h"
31
32namespace cc {
33namespace {
34
35class DelegatedRendererLayerImplTest : public testing::Test {
36 public:
37  DelegatedRendererLayerImplTest()
38      : proxy_(),
39        always_impl_thread_and_main_thread_blocked_(&proxy_) {
40    LayerTreeSettings settings;
41    settings.minimum_occlusion_tracking_size = gfx::Size();
42
43    host_impl_.reset(
44        new FakeLayerTreeHostImpl(settings, &proxy_, &shared_bitmap_manager_));
45    host_impl_->InitializeRenderer(
46        FakeOutputSurface::Create3d().PassAs<OutputSurface>());
47    host_impl_->SetViewportSize(gfx::Size(10, 10));
48  }
49
50 protected:
51  FakeProxy proxy_;
52  DebugScopedSetImplThreadAndMainThreadBlocked
53      always_impl_thread_and_main_thread_blocked_;
54  TestSharedBitmapManager shared_bitmap_manager_;
55  scoped_ptr<LayerTreeHostImpl> host_impl_;
56};
57
58class DelegatedRendererLayerImplTestSimple
59    : public DelegatedRendererLayerImplTest {
60 public:
61  DelegatedRendererLayerImplTestSimple()
62      : DelegatedRendererLayerImplTest() {
63    scoped_ptr<LayerImpl> root_layer = SolidColorLayerImpl::Create(
64        host_impl_->active_tree(), 1).PassAs<LayerImpl>();
65    scoped_ptr<LayerImpl> layer_before = SolidColorLayerImpl::Create(
66        host_impl_->active_tree(), 2).PassAs<LayerImpl>();
67    scoped_ptr<LayerImpl> layer_after = SolidColorLayerImpl::Create(
68        host_impl_->active_tree(), 3).PassAs<LayerImpl>();
69    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
70        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 4);
71
72    host_impl_->SetViewportSize(gfx::Size(100, 100));
73    root_layer->SetBounds(gfx::Size(100, 100));
74
75    layer_before->SetPosition(gfx::Point(20, 20));
76    layer_before->SetBounds(gfx::Size(14, 14));
77    layer_before->SetContentBounds(gfx::Size(14, 14));
78    layer_before->SetDrawsContent(true);
79    layer_before->SetForceRenderSurface(true);
80
81    layer_after->SetPosition(gfx::Point(5, 5));
82    layer_after->SetBounds(gfx::Size(15, 15));
83    layer_after->SetContentBounds(gfx::Size(15, 15));
84    layer_after->SetDrawsContent(true);
85    layer_after->SetForceRenderSurface(true);
86
87    delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
88    delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
89    delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
90    delegated_renderer_layer->SetDrawsContent(true);
91    gfx::Transform transform;
92    transform.Translate(1.0, 1.0);
93    delegated_renderer_layer->SetTransform(transform);
94
95    ScopedPtrVector<RenderPass> delegated_render_passes;
96    TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
97                                          RenderPass::Id(9, 6),
98                                          gfx::Rect(6, 6, 6, 6),
99                                          gfx::Transform(1, 0, 0, 1, 5, 6));
100    AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
101    TestRenderPass* pass2 = AddRenderPass(&delegated_render_passes,
102                                          RenderPass::Id(9, 7),
103                                          gfx::Rect(7, 7, 7, 7),
104                                          gfx::Transform(1, 0, 0, 1, 7, 8));
105    AddQuad(pass2, gfx::Rect(0, 0, 7, 7), 22u);
106    AddRenderPassQuad(pass2, pass1);
107    TestRenderPass* pass3 = AddRenderPass(&delegated_render_passes,
108                                          RenderPass::Id(9, 8),
109                                          gfx::Rect(0, 0, 8, 8),
110                                          gfx::Transform(1, 0, 0, 1, 9, 10));
111    AddRenderPassQuad(pass3, pass2);
112    delegated_renderer_layer->SetFrameDataForRenderPasses(
113        &delegated_render_passes);
114
115    // The RenderPasses should be taken by the layer.
116    EXPECT_EQ(0u, delegated_render_passes.size());
117
118    root_layer_ = root_layer.get();
119    layer_before_ = layer_before.get();
120    layer_after_ = layer_after.get();
121    delegated_renderer_layer_ = delegated_renderer_layer.get();
122
123    // Force the delegated RenderPasses to come before the RenderPass from
124    // layer_after.
125    layer_after->AddChild(delegated_renderer_layer.PassAs<LayerImpl>());
126    root_layer->AddChild(layer_after.Pass());
127
128    // Get the RenderPass generated by layer_before to come before the delegated
129    // RenderPasses.
130    root_layer->AddChild(layer_before.Pass());
131    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
132  }
133
134 protected:
135  LayerImpl* root_layer_;
136  LayerImpl* layer_before_;
137  LayerImpl* layer_after_;
138  DelegatedRendererLayerImpl* delegated_renderer_layer_;
139};
140
141TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
142  LayerTreeHostImpl::FrameData frame;
143  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
144            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
145
146  // Each non-DelegatedRendererLayer added one RenderPass. The
147  // DelegatedRendererLayer added two contributing passes.
148  ASSERT_EQ(5u, frame.render_passes.size());
149
150  // The DelegatedRendererLayer should have added its contributing RenderPasses
151  // to the frame.
152  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
153  EXPECT_EQ(1, frame.render_passes[1]->id.index);
154  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
155  EXPECT_EQ(2, frame.render_passes[2]->id.index);
156  // And all other RenderPasses should be non-delegated.
157  EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
158  EXPECT_EQ(0, frame.render_passes[0]->id.index);
159  EXPECT_NE(4, frame.render_passes[3]->id.layer_id);
160  EXPECT_EQ(0, frame.render_passes[3]->id.index);
161  EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
162  EXPECT_EQ(0, frame.render_passes[4]->id.index);
163
164  // The DelegatedRendererLayer should have added its RenderPasses to the frame
165  // in order.
166  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
167            frame.render_passes[1]->output_rect.ToString());
168  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
169            frame.render_passes[2]->output_rect.ToString());
170
171  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
172  host_impl_->DidDrawAllLayers(frame);
173}
174
175TEST_F(DelegatedRendererLayerImplTestSimple,
176       AddsQuadsToContributingRenderPasses) {
177  LayerTreeHostImpl::FrameData frame;
178  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
179            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
180
181  // Each non-DelegatedRendererLayer added one RenderPass. The
182  // DelegatedRendererLayer added two contributing passes.
183  ASSERT_EQ(5u, frame.render_passes.size());
184
185  // The DelegatedRendererLayer should have added its contributing RenderPasses
186  // to the frame.
187  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
188  EXPECT_EQ(1, frame.render_passes[1]->id.index);
189  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
190  EXPECT_EQ(2, frame.render_passes[2]->id.index);
191
192  // The DelegatedRendererLayer should have added copies of its quads to
193  // contributing RenderPasses.
194  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
195  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
196            frame.render_passes[1]->quad_list[0]->rect.ToString());
197
198  // Verify it added the right quads.
199  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
200  EXPECT_EQ(gfx::Rect(0, 0, 7, 7).ToString(),
201            frame.render_passes[2]->quad_list[0]->rect.ToString());
202  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
203            frame.render_passes[2]->quad_list[1]->rect.ToString());
204  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
205  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
206            frame.render_passes[1]->quad_list[0]->rect.ToString());
207
208  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
209  host_impl_->DidDrawAllLayers(frame);
210}
211
212TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
213  LayerTreeHostImpl::FrameData frame;
214  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
215            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
216
217  // Each non-DelegatedRendererLayer added one RenderPass. The
218  // DelegatedRendererLayer added two contributing passes.
219  ASSERT_EQ(5u, frame.render_passes.size());
220
221  // The layer's target is the RenderPass from layer_after_.
222  EXPECT_EQ(RenderPass::Id(3, 0), frame.render_passes[3]->id);
223
224  // The DelegatedRendererLayer should have added copies of quads in its root
225  // RenderPass to its target RenderPass. The layer_after_ also adds one quad.
226  ASSERT_EQ(2u, frame.render_passes[3]->quad_list.size());
227
228  // Verify it added the right quads.
229  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
230            frame.render_passes[3]->quad_list[0]->rect.ToString());
231
232  // Its target layer should have a quad as well.
233  EXPECT_EQ(gfx::Rect(0, 0, 15, 15).ToString(),
234            frame.render_passes[3]->quad_list[1]->rect.ToString());
235
236  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
237  host_impl_->DidDrawAllLayers(frame);
238}
239
240TEST_F(DelegatedRendererLayerImplTestSimple,
241       QuadsFromRootRenderPassAreModifiedForTheTarget) {
242  LayerTreeHostImpl::FrameData frame;
243  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
244            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
245
246  // Each non-DelegatedRendererLayer added one RenderPass. The
247  // DelegatedRendererLayer added two contributing passes.
248  ASSERT_EQ(5u, frame.render_passes.size());
249
250  // The DelegatedRendererLayer is at position 3,3 compared to its target, and
251  // has a translation transform of 1,1. So its root RenderPass' quads should
252  // all be transformed by that combined amount.
253  // The DelegatedRendererLayer has a size of 10x10, but the root delegated
254  // RenderPass has a size of 8x8, so any quads should be scaled by 10/8.
255  gfx::Transform transform;
256  transform.Translate(4.0, 4.0);
257  transform.Scale(10.0 / 8.0, 10.0 / 8.0);
258  EXPECT_TRANSFORMATION_MATRIX_EQ(
259      transform, frame.render_passes[3]->quad_list[0]->quadTransform());
260
261  // Quads from non-root RenderPasses should not be shifted though.
262  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
263  EXPECT_TRANSFORMATION_MATRIX_EQ(
264      gfx::Transform(), frame.render_passes[2]->quad_list[0]->quadTransform());
265  EXPECT_TRANSFORMATION_MATRIX_EQ(
266      gfx::Transform(), frame.render_passes[2]->quad_list[1]->quadTransform());
267  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
268  EXPECT_TRANSFORMATION_MATRIX_EQ(
269      gfx::Transform(), frame.render_passes[1]->quad_list[0]->quadTransform());
270
271  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
272  host_impl_->DidDrawAllLayers(frame);
273}
274
275TEST_F(DelegatedRendererLayerImplTestSimple, RenderPassTransformIsModified) {
276  LayerTreeHostImpl::FrameData frame;
277  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
278            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
279
280  // The delegated layer has a surface between it and the root.
281  EXPECT_TRUE(delegated_renderer_layer_->render_target()->parent());
282
283  // Each non-DelegatedRendererLayer added one RenderPass. The
284  // DelegatedRendererLayer added two contributing passes.
285  ASSERT_EQ(5u, frame.render_passes.size());
286
287  // The DelegatedRendererLayer is at position 9,9 compared to the root, so all
288  // render pass' transforms to the root should be shifted by this amount.
289  // The DelegatedRendererLayer has a size of 10x10, but the root delegated
290  // RenderPass has a size of 8x8, so any render passes should be scaled by
291  // 10/8.
292  gfx::Transform transform;
293  transform.Translate(9.0, 9.0);
294  transform.Scale(10.0 / 8.0, 10.0 / 8.0);
295
296  // The first contributing surface has a translation of 5, 6.
297  gfx::Transform five_six(1, 0, 0, 1, 5, 6);
298
299  // The second contributing surface has a translation of 7, 8.
300  gfx::Transform seven_eight(1, 0, 0, 1, 7, 8);
301
302  EXPECT_TRANSFORMATION_MATRIX_EQ(
303      transform * five_six, frame.render_passes[1]->transform_to_root_target);
304  EXPECT_TRANSFORMATION_MATRIX_EQ(
305      transform * seven_eight,
306      frame.render_passes[2]->transform_to_root_target);
307
308  host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
309  host_impl_->DidDrawAllLayers(frame);
310}
311
312TEST_F(DelegatedRendererLayerImplTestSimple, DoesNotOwnARenderSurface) {
313  LayerTreeHostImpl::FrameData frame;
314  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
315            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
316
317  // If the DelegatedRendererLayer is axis aligned and has opacity 1, then it
318  // has no need to be a RenderSurface for the quads it carries.
319  EXPECT_FALSE(delegated_renderer_layer_->render_surface());
320
321  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
322  host_impl_->DidDrawAllLayers(frame);
323}
324
325TEST_F(DelegatedRendererLayerImplTestSimple, DoesOwnARenderSurfaceForOpacity) {
326  delegated_renderer_layer_->SetOpacity(0.5f);
327
328  LayerTreeHostImpl::FrameData frame;
329  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
330            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
331
332  // This test case has quads from multiple layers in the delegated renderer, so
333  // if the DelegatedRendererLayer has opacity < 1, it should end up with a
334  // render surface.
335  EXPECT_TRUE(delegated_renderer_layer_->render_surface());
336
337  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
338  host_impl_->DidDrawAllLayers(frame);
339}
340
341TEST_F(DelegatedRendererLayerImplTestSimple,
342       DoesOwnARenderSurfaceForTransform) {
343  gfx::Transform rotation;
344  rotation.RotateAboutZAxis(30.0);
345  delegated_renderer_layer_->SetTransform(rotation);
346
347  LayerTreeHostImpl::FrameData frame;
348  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
349            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
350
351  // This test case has quads from multiple layers in the delegated renderer, so
352  // if the DelegatedRendererLayer has opacity < 1, it should end up with a
353  // render surface.
354  EXPECT_TRUE(delegated_renderer_layer_->render_surface());
355
356  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
357  host_impl_->DidDrawAllLayers(frame);
358}
359
360class DelegatedRendererLayerImplTestOwnSurface
361    : public DelegatedRendererLayerImplTestSimple {
362 public:
363  DelegatedRendererLayerImplTestOwnSurface()
364      : DelegatedRendererLayerImplTestSimple() {
365    delegated_renderer_layer_->SetForceRenderSurface(true);
366  }
367};
368
369TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
370  LayerTreeHostImpl::FrameData frame;
371  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
372            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
373
374  // Each non-DelegatedRendererLayer added one RenderPass. The
375  // DelegatedRendererLayer added two contributing passes and its owned surface
376  // added one pass.
377  ASSERT_EQ(6u, frame.render_passes.size());
378
379  // The DelegatedRendererLayer should have added its contributing RenderPasses
380  // to the frame.
381  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
382  EXPECT_EQ(1, frame.render_passes[1]->id.index);
383  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
384  EXPECT_EQ(2, frame.render_passes[2]->id.index);
385  // The DelegatedRendererLayer should have added a RenderPass for its surface
386  // to the frame.
387  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
388  EXPECT_EQ(0, frame.render_passes[3]->id.index);
389  // And all other RenderPasses should be non-delegated.
390  EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
391  EXPECT_EQ(0, frame.render_passes[0]->id.index);
392  EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
393  EXPECT_EQ(0, frame.render_passes[4]->id.index);
394  EXPECT_NE(4, frame.render_passes[5]->id.layer_id);
395  EXPECT_EQ(0, frame.render_passes[5]->id.index);
396
397  // The DelegatedRendererLayer should have added its RenderPasses to the frame
398  // in order.
399  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
400            frame.render_passes[1]->output_rect.ToString());
401  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
402            frame.render_passes[2]->output_rect.ToString());
403
404  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
405  host_impl_->DidDrawAllLayers(frame);
406}
407
408TEST_F(DelegatedRendererLayerImplTestOwnSurface,
409       AddsQuadsToContributingRenderPasses) {
410  LayerTreeHostImpl::FrameData frame;
411  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
412            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
413
414  // Each non-DelegatedRendererLayer added one RenderPass. The
415  // DelegatedRendererLayer added two contributing passes and its owned surface
416  // added one pass.
417  ASSERT_EQ(6u, frame.render_passes.size());
418
419  // The DelegatedRendererLayer should have added its contributing RenderPasses
420  // to the frame.
421  EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
422  EXPECT_EQ(1, frame.render_passes[1]->id.index);
423  EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
424  EXPECT_EQ(2, frame.render_passes[2]->id.index);
425
426  // The DelegatedRendererLayer should have added copies of its quads to
427  // contributing RenderPasses.
428  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
429  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
430            frame.render_passes[1]->quad_list[0]->rect.ToString());
431
432  // Verify it added the right quads.
433  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
434  EXPECT_EQ(gfx::Rect(0, 0, 7, 7).ToString(),
435            frame.render_passes[2]->quad_list[0]->rect.ToString());
436  EXPECT_EQ(gfx::Rect(6, 6, 6, 6).ToString(),
437            frame.render_passes[2]->quad_list[1]->rect.ToString());
438  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
439  EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
440            frame.render_passes[1]->quad_list[0]->rect.ToString());
441
442  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
443  host_impl_->DidDrawAllLayers(frame);
444}
445
446TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
447  LayerTreeHostImpl::FrameData frame;
448  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
449            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
450
451  // Each non-DelegatedRendererLayer added one RenderPass. The
452  // DelegatedRendererLayer added two contributing passes and its owned surface
453  // added one pass.
454  ASSERT_EQ(6u, frame.render_passes.size());
455
456  // The layer's target is the RenderPass owned by itself.
457  EXPECT_EQ(RenderPass::Id(4, 0), frame.render_passes[3]->id);
458
459  // The DelegatedRendererLayer should have added copies of quads in its root
460  // RenderPass to its target RenderPass.
461  // The layer_after also adds one quad.
462  ASSERT_EQ(1u, frame.render_passes[3]->quad_list.size());
463
464  // Verify it added the right quads.
465  EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
466            frame.render_passes[3]->quad_list[0]->rect.ToString());
467
468  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
469  host_impl_->DidDrawAllLayers(frame);
470}
471
472TEST_F(DelegatedRendererLayerImplTestOwnSurface,
473       QuadsFromRootRenderPassAreNotModifiedForTheTarget) {
474  LayerTreeHostImpl::FrameData frame;
475  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
476            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
477
478  // Each non-DelegatedRendererLayer added one RenderPass. The
479  // DelegatedRendererLayer added two contributing passes and its owned surface
480  // added one pass.
481  ASSERT_EQ(6u, frame.render_passes.size());
482
483  // Because the DelegatedRendererLayer owns a RenderSurfaceImpl, its root
484  // RenderPass' quads do not need to be translated at all. However, they are
485  // scaled from the frame's size (8x8) to the layer's bounds (10x10).
486  gfx::Transform transform;
487  transform.Scale(10.0 / 8.0, 10.0 / 8.0);
488  EXPECT_TRANSFORMATION_MATRIX_EQ(
489      transform, frame.render_passes[3]->quad_list[0]->quadTransform());
490
491  // Quads from non-root RenderPasses should not be shifted either.
492  ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
493  EXPECT_TRANSFORMATION_MATRIX_EQ(
494      gfx::Transform(), frame.render_passes[2]->quad_list[0]->quadTransform());
495  EXPECT_TRANSFORMATION_MATRIX_EQ(
496      gfx::Transform(), frame.render_passes[2]->quad_list[1]->quadTransform());
497  ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
498  EXPECT_TRANSFORMATION_MATRIX_EQ(
499      gfx::Transform(), frame.render_passes[1]->quad_list[0]->quadTransform());
500
501  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
502  host_impl_->DidDrawAllLayers(frame);
503}
504
505class DelegatedRendererLayerImplTestTransform
506    : public DelegatedRendererLayerImplTest {
507 public:
508  void SetUpTest() {
509    host_impl_->SetDeviceScaleFactor(2.f);
510
511    scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(
512        host_impl_->active_tree(), 1);
513    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
514        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 2);
515
516    host_impl_->SetViewportSize(gfx::Size(200, 200));
517    root_layer->SetBounds(gfx::Size(100, 100));
518
519    delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
520    delegated_renderer_layer->SetBounds(gfx::Size(75, 75));
521    delegated_renderer_layer->SetContentBounds(gfx::Size(75, 75));
522    delegated_renderer_layer->SetDrawsContent(true);
523    gfx::Transform transform;
524    transform.Scale(2.0, 2.0);
525    transform.Translate(8.0, 8.0);
526    delegated_renderer_layer->SetTransform(transform);
527
528    ScopedPtrVector<RenderPass> delegated_render_passes;
529
530    gfx::Size child_pass_content_bounds(7, 7);
531    gfx::Rect child_pass_rect(20, 20, 7, 7);
532    gfx::Transform child_pass_transform;
533    child_pass_transform.Scale(0.8f, 0.8f);
534    child_pass_transform.Translate(9.0, 9.0);
535    gfx::Rect child_pass_clip_rect(21, 21, 3, 3);
536    bool child_pass_clipped = false;
537
538    {
539      TestRenderPass* pass = AddRenderPass(
540          &delegated_render_passes,
541          RenderPass::Id(10, 7),
542          child_pass_rect,
543          gfx::Transform());
544      MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
545      SharedQuadState* shared_quad_state = quad_sink.UseSharedQuadState(
546          SharedQuadState::Create());
547      shared_quad_state->SetAll(child_pass_transform,
548                                child_pass_content_bounds,
549                                child_pass_rect,
550                                child_pass_clip_rect,
551                                child_pass_clipped,
552                                1.f,
553                                SkXfermode::kSrcOver_Mode);
554
555      scoped_ptr<SolidColorDrawQuad> color_quad;
556      color_quad = SolidColorDrawQuad::Create();
557      color_quad->SetNew(shared_quad_state,
558                         gfx::Rect(20, 20, 3, 7),
559                         gfx::Rect(20, 20, 3, 7),
560                         1u,
561                         false);
562      quad_sink.Append(color_quad.PassAs<DrawQuad>());
563
564      color_quad = SolidColorDrawQuad::Create();
565      color_quad->SetNew(shared_quad_state,
566                         gfx::Rect(23, 20, 4, 7),
567                         gfx::Rect(23, 20, 4, 7),
568                         1u,
569                         false);
570      quad_sink.Append(color_quad.PassAs<DrawQuad>());
571    }
572
573    gfx::Size root_pass_content_bounds(100, 100);
574    gfx::Rect root_pass_rect(0, 0, 100, 100);
575    gfx::Transform root_pass_transform;
576    root_pass_transform.Scale(1.5, 1.5);
577    root_pass_transform.Translate(7.0, 7.0);
578    gfx::Rect root_pass_clip_rect(10, 10, 35, 35);
579    bool root_pass_clipped = root_delegated_render_pass_is_clipped_;
580
581    TestRenderPass* pass = AddRenderPass(
582        &delegated_render_passes,
583        RenderPass::Id(9, 6),
584        root_pass_rect,
585        gfx::Transform());
586    MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
587    SharedQuadState* shared_quad_state =
588        quad_sink.UseSharedQuadState(SharedQuadState::Create());
589    shared_quad_state->SetAll(root_pass_transform,
590                              root_pass_content_bounds,
591                              root_pass_rect,
592                              root_pass_clip_rect,
593                              root_pass_clipped,
594                              1.f,
595                              SkXfermode::kSrcOver_Mode);
596
597    scoped_ptr<RenderPassDrawQuad> render_pass_quad =
598        RenderPassDrawQuad::Create();
599    render_pass_quad->SetNew(
600        shared_quad_state,
601        gfx::Rect(5, 5, 7, 7),  // quad_rect
602        gfx::Rect(5, 5, 7, 7),  // visible_rect
603        RenderPass::Id(10, 7),  // render_pass_id
604        false,                  // is_replica
605        0,                      // mask_resource_id
606        child_pass_rect,        // contents_changed_since_last_frame
607        gfx::RectF(),           // mask_uv_rect
608        FilterOperations(),     // filters
609        FilterOperations());    // background_filters
610    quad_sink.Append(render_pass_quad.PassAs<DrawQuad>());
611
612    scoped_ptr<SolidColorDrawQuad> color_quad;
613    color_quad = SolidColorDrawQuad::Create();
614    color_quad->SetNew(shared_quad_state,
615                       gfx::Rect(0, 0, 10, 10),
616                       gfx::Rect(0, 0, 10, 10),
617                       1u,
618                       false);
619    quad_sink.Append(color_quad.PassAs<DrawQuad>());
620
621    color_quad = SolidColorDrawQuad::Create();
622    color_quad->SetNew(shared_quad_state,
623                       gfx::Rect(0, 10, 10, 10),
624                       gfx::Rect(0, 10, 10, 10),
625                       2u,
626                       false);
627    quad_sink.Append(color_quad.PassAs<DrawQuad>());
628
629    color_quad = SolidColorDrawQuad::Create();
630    color_quad->SetNew(shared_quad_state,
631                       gfx::Rect(10, 0, 10, 10),
632                       gfx::Rect(10, 0, 10, 10),
633                       3u,
634                       false);
635    quad_sink.Append(color_quad.PassAs<DrawQuad>());
636
637    color_quad = SolidColorDrawQuad::Create();
638    color_quad->SetNew(shared_quad_state,
639                       gfx::Rect(10, 10, 10, 10),
640                       gfx::Rect(10, 10, 10, 10),
641                       4u,
642                       false);
643    quad_sink.Append(color_quad.PassAs<DrawQuad>());
644
645    delegated_renderer_layer->SetFrameDataForRenderPasses(
646        &delegated_render_passes);
647
648    // The RenderPasses should be taken by the layer.
649    EXPECT_EQ(0u, delegated_render_passes.size());
650
651    root_layer_ = root_layer.get();
652    delegated_renderer_layer_ = delegated_renderer_layer.get();
653
654    root_layer->AddChild(delegated_renderer_layer.PassAs<LayerImpl>());
655    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
656  }
657
658  void VerifyRenderPasses(
659      const LayerTreeHostImpl::FrameData& frame,
660      size_t num_render_passes,
661      const SharedQuadState** root_delegated_shared_quad_state,
662      const SharedQuadState** contrib_delegated_shared_quad_state) {
663    ASSERT_EQ(num_render_passes, frame.render_passes.size());
664    // The contributing render pass in the DelegatedRendererLayer.
665    EXPECT_EQ(2, frame.render_passes[0]->id.layer_id);
666    EXPECT_EQ(1, frame.render_passes[0]->id.index);
667    // The root render pass.
668    EXPECT_EQ(1, frame.render_passes.back()->id.layer_id);
669    EXPECT_EQ(0, frame.render_passes.back()->id.index);
670
671    const QuadList& contrib_delegated_quad_list =
672        frame.render_passes[0]->quad_list;
673    ASSERT_EQ(2u, contrib_delegated_quad_list.size());
674
675    const QuadList& root_delegated_quad_list =
676        frame.render_passes[1]->quad_list;
677    ASSERT_EQ(5u, root_delegated_quad_list.size());
678
679    // All quads in a render pass should share the same state.
680    *contrib_delegated_shared_quad_state =
681        contrib_delegated_quad_list[0]->shared_quad_state;
682    EXPECT_EQ(*contrib_delegated_shared_quad_state,
683              contrib_delegated_quad_list[1]->shared_quad_state);
684
685    *root_delegated_shared_quad_state =
686        root_delegated_quad_list[0]->shared_quad_state;
687    EXPECT_EQ(*root_delegated_shared_quad_state,
688              root_delegated_quad_list[1]->shared_quad_state);
689    EXPECT_EQ(*root_delegated_shared_quad_state,
690              root_delegated_quad_list[2]->shared_quad_state);
691    EXPECT_EQ(*root_delegated_shared_quad_state,
692              root_delegated_quad_list[3]->shared_quad_state);
693    EXPECT_EQ(*root_delegated_shared_quad_state,
694              root_delegated_quad_list[4]->shared_quad_state);
695
696    EXPECT_NE(*contrib_delegated_shared_quad_state,
697              *root_delegated_shared_quad_state);
698  }
699
700 protected:
701  LayerImpl* root_layer_;
702  DelegatedRendererLayerImpl* delegated_renderer_layer_;
703  bool root_delegated_render_pass_is_clipped_;
704};
705
706TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
707  root_delegated_render_pass_is_clipped_ = false;
708  SetUpTest();
709
710  LayerTreeHostImpl::FrameData frame;
711  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
712            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
713
714  const SharedQuadState* root_delegated_shared_quad_state = NULL;
715  const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
716  VerifyRenderPasses(
717      frame,
718      2,
719      &root_delegated_shared_quad_state,
720      &contrib_delegated_shared_quad_state);
721
722  // When the quads don't have a clip of their own, the clip rect is set to
723  // the drawable_content_rect of the delegated renderer layer.
724  EXPECT_EQ(delegated_renderer_layer_->drawable_content_rect().ToString(),
725            root_delegated_shared_quad_state->clip_rect.ToString());
726
727  // Even though the quads in the root pass have no clip of their own, they
728  // inherit the clip rect from the delegated renderer layer if it does not
729  // own a surface.
730  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
731
732  gfx::Transform expected;
733  // Device scale factor is 2.
734  expected.Scale(2.0, 2.0);
735  // This is the transform from the layer's space to its target.
736  // The position (20) - the width / scale (75 / 2) = 20 - 37.5 = -17.5
737  expected.Translate(-17.5, -17.5);
738  expected.Scale(2.0, 2.0);
739  expected.Translate(8.0, 8.0);
740  // The frame has size 100x100 but the layer's bounds are 75x75.
741  expected.Scale(75.0 / 100.0, 75.0 / 100.0);
742  // This is the transform within the source frame.
743  expected.Scale(1.5, 1.5);
744  expected.Translate(7.0, 7.0);
745  EXPECT_TRANSFORMATION_MATRIX_EQ(
746      expected, root_delegated_shared_quad_state->content_to_target_transform);
747
748  // The contributing render pass should not be transformed from its input.
749  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
750            contrib_delegated_shared_quad_state->clip_rect.ToString());
751  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
752  expected.MakeIdentity();
753  expected.Scale(0.8f, 0.8f);
754  expected.Translate(9.0, 9.0);
755  EXPECT_TRANSFORMATION_MATRIX_EQ(
756      expected,
757      contrib_delegated_shared_quad_state->content_to_target_transform);
758
759  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
760  host_impl_->DidDrawAllLayers(frame);
761}
762
763TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
764  root_delegated_render_pass_is_clipped_ = true;
765  SetUpTest();
766
767  LayerTreeHostImpl::FrameData frame;
768  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
769            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
770
771  const SharedQuadState* root_delegated_shared_quad_state = NULL;
772  const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
773  VerifyRenderPasses(
774      frame,
775      2,
776      &root_delegated_shared_quad_state,
777      &contrib_delegated_shared_quad_state);
778
779  // Since the quads have a clip_rect it should be modified by delegated
780  // renderer layer's draw_transform.
781  // The position of the resulting clip_rect is:
782  // (clip rect position (10) * scale to layer (75/100) + translate (8)) *
783  //     layer scale (2) + layer position (20) = 51
784  // But the layer is centered, so: 51 - (75 / 2) = 51 - 75 / 2 = 13.5
785  // The device scale is 2, so everything gets doubled, giving 27.
786  //
787  // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from
788  // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5. The device
789  // scale doubles this to 105.
790  EXPECT_EQ(gfx::Rect(27, 27, 105, 105).ToString(),
791            root_delegated_shared_quad_state->clip_rect.ToString());
792
793  // The quads had a clip and it should be preserved.
794  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
795
796  gfx::Transform expected;
797  // Device scale factor is 2.
798  expected.Scale(2.0, 2.0);
799  // This is the transform from the layer's space to its target.
800  // The position (20) - the width / scale (75 / 2) = 20 - 37.5 = -17.5
801  expected.Translate(-17.5, -17.5);
802  expected.Scale(2.0, 2.0);
803  expected.Translate(8.0, 8.0);
804  // The frame has size 100x100 but the layer's bounds are 75x75.
805  expected.Scale(75.0 / 100.0, 75.0 / 100.0);
806  // This is the transform within the source frame.
807  expected.Scale(1.5, 1.5);
808  expected.Translate(7.0, 7.0);
809  EXPECT_TRANSFORMATION_MATRIX_EQ(
810      expected, root_delegated_shared_quad_state->content_to_target_transform);
811
812  // The contributing render pass should not be transformed from its input.
813  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
814            contrib_delegated_shared_quad_state->clip_rect.ToString());
815  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
816  expected.MakeIdentity();
817  expected.Scale(0.8f, 0.8f);
818  expected.Translate(9.0, 9.0);
819  EXPECT_TRANSFORMATION_MATRIX_EQ(
820      expected,
821      contrib_delegated_shared_quad_state->content_to_target_transform);
822
823  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
824  host_impl_->DidDrawAllLayers(frame);
825}
826
827TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
828  root_delegated_render_pass_is_clipped_ = false;
829  SetUpTest();
830
831  delegated_renderer_layer_->SetForceRenderSurface(true);
832
833  LayerTreeHostImpl::FrameData frame;
834  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
835            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
836
837  const SharedQuadState* root_delegated_shared_quad_state = NULL;
838  const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
839  VerifyRenderPasses(
840      frame,
841      3,
842      &root_delegated_shared_quad_state,
843      &contrib_delegated_shared_quad_state);
844
845  // When the layer owns a surface, then its position and translation are not
846  // a part of its draw transform.
847  // The position of the resulting clip_rect is:
848  // (clip rect position (10) * scale to layer (75/100)) * device scale (2) = 15
849  // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from
850  // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5.
851  EXPECT_EQ(gfx::Rect(15, 15, 53, 53).ToString(),
852            root_delegated_shared_quad_state->clip_rect.ToString());
853
854  // Since the layer owns a surface it doesn't need to clip its quads, so
855  // unclipped quads remain unclipped.
856  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);
857
858  gfx::Transform expected;
859  // Device scale factor is 2.
860  expected.Scale(2.0, 2.0);
861  // The frame has size 100x100 but the layer's bounds are 75x75.
862  expected.Scale(75.0 / 100.0, 75.0 / 100.0);
863  // This is the transform within the source frame.
864  expected.Scale(1.5, 1.5);
865  expected.Translate(7.0, 7.0);
866  EXPECT_TRANSFORMATION_MATRIX_EQ(
867      expected, root_delegated_shared_quad_state->content_to_target_transform);
868
869  // The contributing render pass should not be transformed from its input.
870  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
871            contrib_delegated_shared_quad_state->clip_rect.ToString());
872  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
873  expected.MakeIdentity();
874  expected.Scale(0.8f, 0.8f);
875  expected.Translate(9.0, 9.0);
876  EXPECT_TRANSFORMATION_MATRIX_EQ(
877      expected,
878      contrib_delegated_shared_quad_state->content_to_target_transform);
879
880  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
881  host_impl_->DidDrawAllLayers(frame);
882}
883
884TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
885  root_delegated_render_pass_is_clipped_ = true;
886  SetUpTest();
887
888  delegated_renderer_layer_->SetForceRenderSurface(true);
889
890  LayerTreeHostImpl::FrameData frame;
891  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
892            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
893
894  const SharedQuadState* root_delegated_shared_quad_state = NULL;
895  const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
896  VerifyRenderPasses(
897      frame,
898      3,
899      &root_delegated_shared_quad_state,
900      &contrib_delegated_shared_quad_state);
901
902  // When the layer owns a surface, then its position and translation are not
903  // a part of its draw transform.
904  // The position of the resulting clip_rect is:
905  // (clip rect position (10) * scale to layer (75/100)) * device scale (2) = 15
906  // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from
907  // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5.
908  EXPECT_EQ(gfx::Rect(15, 15, 53, 53).ToString(),
909            root_delegated_shared_quad_state->clip_rect.ToString());
910
911  // The quads had a clip and it should be preserved.
912  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
913
914  gfx::Transform expected;
915  // Device scale factor is 2.
916  expected.Scale(2.0, 2.0);
917  // The frame has size 100x100 but the layer's bounds are 75x75.
918  expected.Scale(75.0 / 100.0, 75.0 / 100.0);
919  // This is the transform within the source frame.
920  expected.Scale(1.5, 1.5);
921  expected.Translate(7.0, 7.0);
922  EXPECT_TRANSFORMATION_MATRIX_EQ(
923      expected, root_delegated_shared_quad_state->content_to_target_transform);
924
925  // The contributing render pass should not be transformed from its input.
926  EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
927            contrib_delegated_shared_quad_state->clip_rect.ToString());
928  EXPECT_FALSE(contrib_delegated_shared_quad_state->is_clipped);
929  expected.MakeIdentity();
930  expected.Scale(0.8f, 0.8f);
931  expected.Translate(9.0, 9.0);
932  EXPECT_TRANSFORMATION_MATRIX_EQ(
933      expected,
934      contrib_delegated_shared_quad_state->content_to_target_transform);
935
936  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
937  host_impl_->DidDrawAllLayers(frame);
938}
939
940class DelegatedRendererLayerImplTestClip
941    : public DelegatedRendererLayerImplTest {
942 public:
943  void SetUpTest() {
944    scoped_ptr<LayerImpl> root_layer =
945        LayerImpl::Create(host_impl_->active_tree(), 1);
946    scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
947        FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 2);
948    scoped_ptr<LayerImpl> clip_layer =
949        LayerImpl::Create(host_impl_->active_tree(), 3);
950    scoped_ptr<LayerImpl> origin_layer =
951        LayerImpl::Create(host_impl_->active_tree(), 4);
952
953    host_impl_->SetViewportSize(gfx::Size(100, 100));
954    root_layer->SetBounds(gfx::Size(100, 100));
955
956    delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
957    delegated_renderer_layer->SetBounds(gfx::Size(50, 50));
958    delegated_renderer_layer->SetContentBounds(gfx::Size(50, 50));
959    delegated_renderer_layer->SetDrawsContent(true);
960
961    ScopedPtrVector<RenderPass> delegated_render_passes;
962
963    gfx::Size child_pass_content_bounds(7, 7);
964    gfx::Rect child_pass_rect(20, 20, 7, 7);
965    gfx::Transform child_pass_transform;
966    gfx::Rect child_pass_clip_rect(21, 21, 3, 3);
967    bool child_pass_clipped = false;
968
969    {
970      TestRenderPass* pass = AddRenderPass(
971          &delegated_render_passes,
972          RenderPass::Id(10, 7),
973          child_pass_rect,
974          gfx::Transform());
975      MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
976      SharedQuadState* shared_quad_state =
977          quad_sink.UseSharedQuadState(SharedQuadState::Create());
978      shared_quad_state->SetAll(child_pass_transform,
979                                child_pass_content_bounds,
980                                child_pass_rect,
981                                child_pass_clip_rect,
982                                child_pass_clipped,
983                                1.f,
984                                SkXfermode::kSrcOver_Mode);
985
986      scoped_ptr<SolidColorDrawQuad> color_quad;
987      color_quad = SolidColorDrawQuad::Create();
988      color_quad->SetNew(shared_quad_state,
989                         gfx::Rect(20, 20, 3, 7),
990                         gfx::Rect(20, 20, 3, 7),
991                         1u,
992                         false);
993      quad_sink.Append(color_quad.PassAs<DrawQuad>());
994
995      color_quad = SolidColorDrawQuad::Create();
996      color_quad->SetNew(shared_quad_state,
997                         gfx::Rect(23, 20, 4, 7),
998                         gfx::Rect(23, 20, 4, 7),
999                         1u,
1000                         false);
1001      quad_sink.Append(color_quad.PassAs<DrawQuad>());
1002    }
1003
1004    gfx::Size root_pass_content_bounds(50, 50);
1005    gfx::Rect root_pass_rect(0, 0, 50, 50);
1006    gfx::Transform root_pass_transform;
1007    gfx::Rect root_pass_clip_rect(5, 5, 40, 40);
1008    bool root_pass_clipped = root_delegated_render_pass_is_clipped_;
1009
1010    TestRenderPass* pass = AddRenderPass(
1011        &delegated_render_passes,
1012        RenderPass::Id(9, 6),
1013        root_pass_rect,
1014        gfx::Transform());
1015    MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
1016    SharedQuadState* shared_quad_state =
1017        quad_sink.UseSharedQuadState(SharedQuadState::Create());
1018    shared_quad_state->SetAll(root_pass_transform,
1019                              root_pass_content_bounds,
1020                              root_pass_rect,
1021                              root_pass_clip_rect,
1022                              root_pass_clipped,
1023                              1.f,
1024                              SkXfermode::kSrcOver_Mode);
1025
1026    scoped_ptr<RenderPassDrawQuad> render_pass_quad =
1027        RenderPassDrawQuad::Create();
1028    render_pass_quad->SetNew(
1029        shared_quad_state,
1030        gfx::Rect(5, 5, 7, 7),  // quad_rect
1031        gfx::Rect(5, 5, 7, 7),  // visible_quad_rect
1032        RenderPass::Id(10, 7),  // render_pass_id
1033        false,                  // is_replica
1034        0,                      // mask_resource_id
1035        child_pass_rect,        // contents_changed_since_last_frame
1036        gfx::RectF(),           // mask_uv_rect
1037        FilterOperations(),     // filters
1038        FilterOperations());    // background_filters
1039    quad_sink.Append(render_pass_quad.PassAs<DrawQuad>());
1040
1041    scoped_ptr<SolidColorDrawQuad> color_quad;
1042    color_quad = SolidColorDrawQuad::Create();
1043    color_quad->SetNew(shared_quad_state,
1044                       gfx::Rect(0, 0, 10, 10),
1045                       gfx::Rect(0, 0, 10, 10),
1046                       1u,
1047                       false);
1048    quad_sink.Append(color_quad.PassAs<DrawQuad>());
1049
1050    color_quad = SolidColorDrawQuad::Create();
1051    color_quad->SetNew(shared_quad_state,
1052                       gfx::Rect(0, 10, 10, 10),
1053                       gfx::Rect(0, 10, 10, 10),
1054                       2u,
1055                       false);
1056    quad_sink.Append(color_quad.PassAs<DrawQuad>());
1057
1058    color_quad = SolidColorDrawQuad::Create();
1059    color_quad->SetNew(shared_quad_state,
1060                       gfx::Rect(10, 0, 10, 10),
1061                       gfx::Rect(10, 0, 10, 10),
1062                       3u,
1063                       false);
1064    quad_sink.Append(color_quad.PassAs<DrawQuad>());
1065
1066    color_quad = SolidColorDrawQuad::Create();
1067    color_quad->SetNew(shared_quad_state,
1068                       gfx::Rect(10, 10, 10, 10),
1069                       gfx::Rect(10, 10, 10, 10),
1070                       4u,
1071                       false);
1072    quad_sink.Append(color_quad.PassAs<DrawQuad>());
1073
1074    delegated_renderer_layer->SetFrameDataForRenderPasses(
1075        &delegated_render_passes);
1076
1077    // The RenderPasses should be taken by the layer.
1078    EXPECT_EQ(0u, delegated_render_passes.size());
1079
1080    root_layer_ = root_layer.get();
1081    delegated_renderer_layer_ = delegated_renderer_layer.get();
1082
1083    if (clip_delegated_renderer_layer_) {
1084      gfx::Rect clip_rect(21, 27, 23, 21);
1085
1086      clip_layer->SetPosition(clip_rect.origin());
1087      clip_layer->SetBounds(clip_rect.size());
1088      clip_layer->SetContentBounds(clip_rect.size());
1089      clip_layer->SetMasksToBounds(true);
1090
1091      origin_layer->SetPosition(
1092          gfx::PointAtOffsetFromOrigin(-clip_rect.OffsetFromOrigin()));
1093
1094      origin_layer->AddChild(delegated_renderer_layer.PassAs<LayerImpl>());
1095      clip_layer->AddChild(origin_layer.Pass());
1096      root_layer->AddChild(clip_layer.Pass());
1097    } else {
1098      root_layer->AddChild(delegated_renderer_layer.PassAs<LayerImpl>());
1099    }
1100
1101    host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
1102  }
1103
1104 protected:
1105  LayerImpl* root_layer_;
1106  DelegatedRendererLayerImpl* delegated_renderer_layer_;
1107  bool root_delegated_render_pass_is_clipped_;
1108  bool clip_delegated_renderer_layer_;
1109};
1110
1111TEST_F(DelegatedRendererLayerImplTestClip,
1112       QuadsUnclipped_LayerUnclipped_NoSurface) {
1113  root_delegated_render_pass_is_clipped_ = false;
1114  clip_delegated_renderer_layer_ = false;
1115  SetUpTest();
1116
1117  LayerTreeHostImpl::FrameData frame;
1118  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1119            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1120
1121  ASSERT_EQ(2u, frame.render_passes.size());
1122  const QuadList& contrib_delegated_quad_list =
1123      frame.render_passes[0]->quad_list;
1124  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1125  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1126  ASSERT_EQ(5u, root_delegated_quad_list.size());
1127  const SharedQuadState* root_delegated_shared_quad_state =
1128      root_delegated_quad_list[0]->shared_quad_state;
1129
1130  // When the quads don't have a clip of their own, the clip rect is set to
1131  // the drawable_content_rect of the delegated renderer layer.
1132  EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(),
1133            root_delegated_shared_quad_state->clip_rect.ToString());
1134  // Quads are clipped to the delegated renderer layer.
1135  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1136
1137  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1138  host_impl_->DidDrawAllLayers(frame);
1139}
1140
1141TEST_F(DelegatedRendererLayerImplTestClip,
1142       QuadsClipped_LayerUnclipped_NoSurface) {
1143  root_delegated_render_pass_is_clipped_ = true;
1144  clip_delegated_renderer_layer_ = false;
1145  SetUpTest();
1146
1147  LayerTreeHostImpl::FrameData frame;
1148  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1149            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1150
1151  ASSERT_EQ(2u, frame.render_passes.size());
1152  const QuadList& contrib_delegated_quad_list =
1153      frame.render_passes[0]->quad_list;
1154  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1155  const QuadList& root_delegated_quad_list =
1156      frame.render_passes[1]->quad_list;
1157  ASSERT_EQ(5u, root_delegated_quad_list.size());
1158  const SharedQuadState* root_delegated_shared_quad_state =
1159      root_delegated_quad_list[0]->shared_quad_state;
1160
1161  // When the quads have a clip of their own, it is used.
1162  EXPECT_EQ(gfx::Rect(25, 25, 40, 40).ToString(),
1163            root_delegated_shared_quad_state->clip_rect.ToString());
1164  // Quads came with a clip rect.
1165  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1166
1167  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1168  host_impl_->DidDrawAllLayers(frame);
1169}
1170
1171TEST_F(DelegatedRendererLayerImplTestClip,
1172       QuadsUnclipped_LayerClipped_NoSurface) {
1173  root_delegated_render_pass_is_clipped_ = false;
1174  clip_delegated_renderer_layer_ = true;
1175  SetUpTest();
1176
1177  LayerTreeHostImpl::FrameData frame;
1178  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1179            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1180
1181  ASSERT_EQ(2u, frame.render_passes.size());
1182  const QuadList& contrib_delegated_quad_list =
1183      frame.render_passes[0]->quad_list;
1184  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1185  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1186  ASSERT_EQ(5u, root_delegated_quad_list.size());
1187  const SharedQuadState* root_delegated_shared_quad_state =
1188      root_delegated_quad_list[0]->shared_quad_state;
1189
1190  // When the quads don't have a clip of their own, the clip rect is set to
1191  // the drawable_content_rect of the delegated renderer layer. When the layer
1192  // is clipped, that should be seen in the quads' clip_rect.
1193  EXPECT_EQ(gfx::Rect(21, 27, 23, 21).ToString(),
1194            root_delegated_shared_quad_state->clip_rect.ToString());
1195  // Quads are clipped to the delegated renderer layer.
1196  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1197
1198  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1199  host_impl_->DidDrawAllLayers(frame);
1200}
1201
1202TEST_F(DelegatedRendererLayerImplTestClip,
1203       QuadsClipped_LayerClipped_NoSurface) {
1204  root_delegated_render_pass_is_clipped_ = true;
1205  clip_delegated_renderer_layer_ = true;
1206  SetUpTest();
1207
1208  LayerTreeHostImpl::FrameData frame;
1209  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1210            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1211
1212  ASSERT_EQ(2u, frame.render_passes.size());
1213  const QuadList& contrib_delegated_quad_list =
1214      frame.render_passes[0]->quad_list;
1215  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1216  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1217  ASSERT_EQ(5u, root_delegated_quad_list.size());
1218  const SharedQuadState* root_delegated_shared_quad_state =
1219      root_delegated_quad_list[0]->shared_quad_state;
1220
1221  // When the quads have a clip of their own, it is used, but it is
1222  // combined with the clip rect of the delegated renderer layer.
1223  EXPECT_EQ(gfx::Rect(25, 27, 19, 21).ToString(),
1224            root_delegated_shared_quad_state->clip_rect.ToString());
1225  // Quads came with a clip rect.
1226  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1227
1228  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1229  host_impl_->DidDrawAllLayers(frame);
1230}
1231
1232TEST_F(DelegatedRendererLayerImplTestClip,
1233       QuadsUnclipped_LayerUnclipped_Surface) {
1234  root_delegated_render_pass_is_clipped_ = false;
1235  clip_delegated_renderer_layer_ = false;
1236  SetUpTest();
1237
1238  delegated_renderer_layer_->SetForceRenderSurface(true);
1239
1240  LayerTreeHostImpl::FrameData frame;
1241  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1242            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1243
1244  ASSERT_EQ(3u, frame.render_passes.size());
1245  const QuadList& contrib_delegated_quad_list =
1246      frame.render_passes[0]->quad_list;
1247  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1248  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1249  ASSERT_EQ(5u, root_delegated_quad_list.size());
1250  const SharedQuadState* root_delegated_shared_quad_state =
1251      root_delegated_quad_list[0]->shared_quad_state;
1252
1253  // When the layer owns a surface, the quads don't need to be clipped
1254  // further than they already specify. If they aren't clipped, then their
1255  // clip rect is ignored, and they are not set as clipped.
1256  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);
1257
1258  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1259  host_impl_->DidDrawAllLayers(frame);
1260}
1261
1262TEST_F(DelegatedRendererLayerImplTestClip,
1263       QuadsClipped_LayerUnclipped_Surface) {
1264  root_delegated_render_pass_is_clipped_ = true;
1265  clip_delegated_renderer_layer_ = false;
1266  SetUpTest();
1267
1268  delegated_renderer_layer_->SetForceRenderSurface(true);
1269
1270  LayerTreeHostImpl::FrameData frame;
1271  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1272            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1273
1274  ASSERT_EQ(3u, frame.render_passes.size());
1275  const QuadList& contrib_delegated_quad_list =
1276      frame.render_passes[0]->quad_list;
1277  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1278  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1279  ASSERT_EQ(5u, root_delegated_quad_list.size());
1280  const SharedQuadState* root_delegated_shared_quad_state =
1281      root_delegated_quad_list[0]->shared_quad_state;
1282
1283  // When the quads have a clip of their own, it is used.
1284  EXPECT_EQ(gfx::Rect(5, 5, 40, 40).ToString(),
1285            root_delegated_shared_quad_state->clip_rect.ToString());
1286  // Quads came with a clip rect.
1287  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1288
1289  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1290  host_impl_->DidDrawAllLayers(frame);
1291}
1292
1293TEST_F(DelegatedRendererLayerImplTestClip,
1294       QuadsUnclipped_LayerClipped_Surface) {
1295  root_delegated_render_pass_is_clipped_ = false;
1296  clip_delegated_renderer_layer_ = true;
1297  SetUpTest();
1298
1299  delegated_renderer_layer_->SetForceRenderSurface(true);
1300
1301  LayerTreeHostImpl::FrameData frame;
1302  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1303            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1304
1305  ASSERT_EQ(3u, frame.render_passes.size());
1306  const QuadList& contrib_delegated_quad_list =
1307      frame.render_passes[0]->quad_list;
1308  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1309  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1310  ASSERT_EQ(5u, root_delegated_quad_list.size());
1311  const SharedQuadState* root_delegated_shared_quad_state =
1312      root_delegated_quad_list[0]->shared_quad_state;
1313
1314  // When the layer owns a surface, the quads don't need to be clipped
1315  // further than they already specify. If they aren't clipped, then their
1316  // clip rect is ignored, and they are not set as clipped.
1317  EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);
1318
1319  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1320  host_impl_->DidDrawAllLayers(frame);
1321}
1322
1323TEST_F(DelegatedRendererLayerImplTestClip, QuadsClipped_LayerClipped_Surface) {
1324  root_delegated_render_pass_is_clipped_ = true;
1325  clip_delegated_renderer_layer_ = true;
1326  SetUpTest();
1327
1328  delegated_renderer_layer_->SetForceRenderSurface(true);
1329
1330  LayerTreeHostImpl::FrameData frame;
1331  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1332            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1333
1334  ASSERT_EQ(3u, frame.render_passes.size());
1335  const QuadList& contrib_delegated_quad_list =
1336      frame.render_passes[0]->quad_list;
1337  ASSERT_EQ(2u, contrib_delegated_quad_list.size());
1338  const QuadList& root_delegated_quad_list = frame.render_passes[1]->quad_list;
1339  ASSERT_EQ(5u, root_delegated_quad_list.size());
1340  const SharedQuadState* root_delegated_shared_quad_state =
1341      root_delegated_quad_list[0]->shared_quad_state;
1342
1343  // When the quads have a clip of their own, it is used, but it is
1344  // combined with the clip rect of the delegated renderer layer. If the
1345  // layer owns a surface, then it does not have a clip rect of its own.
1346  EXPECT_EQ(gfx::Rect(5, 5, 40, 40).ToString(),
1347            root_delegated_shared_quad_state->clip_rect.ToString());
1348  // Quads came with a clip rect.
1349  EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
1350
1351  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1352  host_impl_->DidDrawAllLayers(frame);
1353}
1354
1355TEST_F(DelegatedRendererLayerImplTest, InvalidRenderPassDrawQuad) {
1356  scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(
1357      host_impl_->active_tree(), 1).PassAs<LayerImpl>();
1358  scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer =
1359      FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 4);
1360
1361  host_impl_->SetViewportSize(gfx::Size(100, 100));
1362
1363  delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
1364  delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
1365  delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
1366  delegated_renderer_layer->SetDrawsContent(true);
1367
1368  ScopedPtrVector<RenderPass> delegated_render_passes;
1369  TestRenderPass* pass1 = AddRenderPass(
1370      &delegated_render_passes,
1371      RenderPass::Id(9, 6),
1372      gfx::Rect(0, 0, 10, 10),
1373      gfx::Transform());
1374  AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
1375
1376  // This render pass isn't part of the frame.
1377  scoped_ptr<TestRenderPass> missing_pass(TestRenderPass::Create());
1378  missing_pass->SetNew(RenderPass::Id(9, 7),
1379                       gfx::Rect(7, 7, 7, 7),
1380                       gfx::Rect(7, 7, 7, 7),
1381                       gfx::Transform());
1382
1383  // But a render pass quad refers to it.
1384  AddRenderPassQuad(pass1, missing_pass.get());
1385
1386  delegated_renderer_layer->SetFrameDataForRenderPasses(
1387      &delegated_render_passes);
1388
1389  // The RenderPasses should be taken by the layer.
1390  EXPECT_EQ(0u, delegated_render_passes.size());
1391
1392  root_layer->AddChild(delegated_renderer_layer.PassAs<LayerImpl>());
1393  host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
1394
1395  LayerTreeHostImpl::FrameData frame;
1396  EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS,
1397            host_impl_->PrepareToDraw(&frame, gfx::Rect()));
1398
1399  // The DelegatedRendererLayerImpl should drop the bad RenderPassDrawQuad.
1400  ASSERT_EQ(1u, frame.render_passes.size());
1401  ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
1402  EXPECT_EQ(DrawQuad::SOLID_COLOR,
1403            frame.render_passes[0]->quad_list[0]->material);
1404
1405  host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1406  host_impl_->DidDrawAllLayers(frame);
1407}
1408
1409TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
1410  gfx::Size layer_size(1000, 1000);
1411  gfx::Size viewport_size(1000, 1000);
1412  gfx::Rect quad_rect(200, 300, 400, 500);
1413
1414  gfx::Transform transform;
1415  transform.Translate(11.0, 0.0);
1416
1417  LayerTestCommon::LayerImplTest impl;
1418
1419  FakeDelegatedRendererLayerImpl* delegated_renderer_layer_impl =
1420      impl.AddChildToRoot<FakeDelegatedRendererLayerImpl>();
1421  delegated_renderer_layer_impl->SetAnchorPoint(gfx::PointF());
1422  delegated_renderer_layer_impl->SetBounds(layer_size);
1423  delegated_renderer_layer_impl->SetContentBounds(layer_size);
1424  delegated_renderer_layer_impl->SetDrawsContent(true);
1425
1426  ScopedPtrVector<RenderPass> delegated_render_passes;
1427  // pass2 is just the size of the quad. It contributes to |pass1| with a
1428  // translation of (11,0).
1429  RenderPass::Id pass2_id =
1430      delegated_renderer_layer_impl->FirstContributingRenderPassId();
1431  TestRenderPass* pass2 =
1432      AddRenderPass(&delegated_render_passes, pass2_id, quad_rect, transform);
1433  AddQuad(pass2, gfx::Rect(quad_rect.size()), SK_ColorRED);
1434  // |pass1| covers the whole layer.
1435  RenderPass::Id pass1_id = RenderPass::Id(impl.root_layer()->id(), 0);
1436  TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
1437                                        pass1_id,
1438                                        gfx::Rect(layer_size),
1439                                        gfx::Transform());
1440  AddRenderPassQuad(pass1, pass2, 0, FilterOperations(), transform);
1441  delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
1442      &delegated_render_passes);
1443
1444  impl.CalcDrawProps(viewport_size);
1445
1446  // The |quad_rect| translated by the |transform|.
1447  gfx::Rect quad_screen_rect = quad_rect + gfx::Vector2d(11, 0);
1448
1449  {
1450    SCOPED_TRACE("No occlusion");
1451    gfx::Rect occluded;
1452
1453    {
1454      SCOPED_TRACE("Root render pass");
1455      impl.AppendQuadsForPassWithOcclusion(
1456          delegated_renderer_layer_impl, pass1_id, occluded);
1457      LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
1458                                                   quad_screen_rect);
1459      ASSERT_EQ(1u, impl.quad_list().size());
1460      EXPECT_EQ(DrawQuad::RENDER_PASS, impl.quad_list()[0]->material);
1461    }
1462    {
1463      SCOPED_TRACE("Contributing render pass");
1464      impl.AppendQuadsForPassWithOcclusion(
1465          delegated_renderer_layer_impl, pass2_id, occluded);
1466      LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
1467                                                   gfx::Rect(quad_rect.size()));
1468      ASSERT_EQ(1u, impl.quad_list().size());
1469      EXPECT_EQ(DrawQuad::SOLID_COLOR, impl.quad_list()[0]->material);
1470    }
1471  }
1472
1473  {
1474    SCOPED_TRACE("Full occlusion");
1475    {
1476      gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());
1477
1478      SCOPED_TRACE("Root render pass");
1479      impl.AppendQuadsForPassWithOcclusion(
1480          delegated_renderer_layer_impl, pass1_id, occluded);
1481      LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
1482                                                   gfx::Rect());
1483      EXPECT_EQ(impl.quad_list().size(), 0u);
1484    }
1485    {
1486      gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());
1487      // Move the occlusion to where it is in the contributing surface.
1488      occluded -= quad_rect.OffsetFromOrigin();
1489
1490      SCOPED_TRACE("Contributing render pass");
1491      impl.AppendQuadsForPassWithOcclusion(
1492          delegated_renderer_layer_impl, pass2_id, occluded);
1493      LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
1494                                                   gfx::Rect());
1495      EXPECT_EQ(impl.quad_list().size(), 0u);
1496    }
1497  }
1498
1499  {
1500    SCOPED_TRACE("Partial occlusion");
1501    {
1502      gfx::Rect occluded(0, 0, 500, 1000);
1503
1504      SCOPED_TRACE("Root render pass");
1505      impl.AppendQuadsForPassWithOcclusion(
1506          delegated_renderer_layer_impl, pass1_id, occluded);
1507      size_t partially_occluded_count = 0;
1508      LayerTestCommon::VerifyQuadsCoverRectWithOcclusion(
1509          impl.quad_list(),
1510          quad_screen_rect,
1511          occluded,
1512          &partially_occluded_count);
1513      // The layer outputs one quad, which is partially occluded.
1514      EXPECT_EQ(1u, impl.quad_list().size());
1515      EXPECT_EQ(1u, partially_occluded_count);
1516    }
1517    {
1518      gfx::Rect occluded(0, 0, 500, 1000);
1519      // Move the occlusion to where it is in the contributing surface.
1520      occluded -= quad_rect.OffsetFromOrigin() + gfx::Vector2d(11, 0);
1521
1522      SCOPED_TRACE("Contributing render pass");
1523      impl.AppendQuadsForPassWithOcclusion(
1524          delegated_renderer_layer_impl, pass2_id, occluded);
1525      size_t partially_occluded_count = 0;
1526      LayerTestCommon::VerifyQuadsCoverRectWithOcclusion(
1527          impl.quad_list(),
1528          gfx::Rect(quad_rect.size()),
1529          occluded,
1530          &partially_occluded_count);
1531      // The layer outputs one quad, which is partially occluded.
1532      EXPECT_EQ(1u, impl.quad_list().size());
1533      EXPECT_EQ(1u, partially_occluded_count);
1534      // The quad in the contributing surface is at (211,300) in the root.
1535      // The occlusion extends to 500 in the x-axis, pushing the left of the
1536      // visible part of the quad to 500 - 211 = 300 - 11 inside the quad.
1537      EXPECT_EQ(gfx::Rect(300 - 11, 0, 100 + 11, 500).ToString(),
1538                impl.quad_list()[0]->visible_rect.ToString());
1539    }
1540  }
1541}
1542
1543}  // namespace
1544}  // namespace cc
1545