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