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