Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / trees / damage_tracker_unittest.cc
1 // Copyright 2011 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/trees/damage_tracker.h"
6
7 #include "cc/base/math_util.h"
8 #include "cc/layers/layer_impl.h"
9 #include "cc/output/filter_operation.h"
10 #include "cc/output/filter_operations.h"
11 #include "cc/test/fake_impl_proxy.h"
12 #include "cc/test/fake_layer_tree_host_impl.h"
13 #include "cc/test/geometry_test_utils.h"
14 #include "cc/test/test_shared_bitmap_manager.h"
15 #include "cc/trees/layer_tree_host_common.h"
16 #include "cc/trees/single_thread_proxy.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
19 #include "ui/gfx/geometry/quad_f.h"
20 #include "ui/gfx/geometry/rect_conversions.h"
21
22 namespace cc {
23 namespace {
24
25 void ExecuteCalculateDrawProperties(LayerImpl* root,
26                                     LayerImplList* render_surface_layer_list) {
27   // Sanity check: The test itself should create the root layer's render
28   //               surface, so that the surface (and its damage tracker) can
29   //               persist across multiple calls to this function.
30   ASSERT_TRUE(root->render_surface());
31   ASSERT_FALSE(render_surface_layer_list->size());
32
33   FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
34   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
35       root, root->bounds(), render_surface_layer_list);
36   LayerTreeHostCommon::CalculateDrawProperties(&inputs);
37 }
38
39 void ClearDamageForAllSurfaces(LayerImpl* layer) {
40   if (layer->render_surface())
41     layer->render_surface()->damage_tracker()->DidDrawDamagedArea();
42
43   // Recursively clear damage for any existing surface.
44   for (size_t i = 0; i < layer->children().size(); ++i)
45     ClearDamageForAllSurfaces(layer->children()[i]);
46 }
47
48 void EmulateDrawingOneFrame(LayerImpl* root) {
49   // This emulates only steps that are relevant to testing the damage tracker:
50   //   1. computing the render passes and layerlists
51   //   2. updating all damage trackers in the correct order
52   //   3. resetting all update_rects and property_changed flags for all layers
53   //      and surfaces.
54
55   LayerImplList render_surface_layer_list;
56   ExecuteCalculateDrawProperties(root, &render_surface_layer_list);
57
58   // Iterate back-to-front, so that damage correctly propagates from descendant
59   // surfaces to ancestors.
60   for (int i = render_surface_layer_list.size() - 1; i >= 0; --i) {
61     RenderSurfaceImpl* target_surface =
62             render_surface_layer_list[i]->render_surface();
63     target_surface->damage_tracker()->UpdateDamageTrackingState(
64         target_surface->layer_list(),
65         target_surface->OwningLayerId(),
66         target_surface->SurfacePropertyChangedOnlyFromDescendant(),
67         target_surface->content_rect(),
68         render_surface_layer_list[i]->mask_layer(),
69         render_surface_layer_list[i]->filters());
70   }
71
72   root->ResetAllChangeTrackingForSubtree();
73 }
74
75 class DamageTrackerTest : public testing::Test {
76  public:
77   DamageTrackerTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {}
78
79   scoped_ptr<LayerImpl> CreateTestTreeWithOneSurface() {
80     scoped_ptr<LayerImpl> root =
81             LayerImpl::Create(host_impl_.active_tree(), 1);
82     scoped_ptr<LayerImpl> child =
83             LayerImpl::Create(host_impl_.active_tree(), 2);
84
85     root->SetPosition(gfx::PointF());
86     root->SetBounds(gfx::Size(500, 500));
87     root->SetContentBounds(gfx::Size(500, 500));
88     root->SetDrawsContent(true);
89     root->CreateRenderSurface();
90     root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
91
92     child->SetPosition(gfx::PointF(100.f, 100.f));
93     child->SetBounds(gfx::Size(30, 30));
94     child->SetContentBounds(gfx::Size(30, 30));
95     child->SetDrawsContent(true);
96     root->AddChild(child.Pass());
97
98     return root.Pass();
99   }
100
101   scoped_ptr<LayerImpl> CreateTestTreeWithTwoSurfaces() {
102     // This test tree has two render surfaces: one for the root, and one for
103     // child1. Additionally, the root has a second child layer, and child1 has
104     // two children of its own.
105
106     scoped_ptr<LayerImpl> root =
107             LayerImpl::Create(host_impl_.active_tree(), 1);
108     scoped_ptr<LayerImpl> child1 =
109             LayerImpl::Create(host_impl_.active_tree(), 2);
110     scoped_ptr<LayerImpl> child2 =
111             LayerImpl::Create(host_impl_.active_tree(), 3);
112     scoped_ptr<LayerImpl> grand_child1 =
113             LayerImpl::Create(host_impl_.active_tree(), 4);
114     scoped_ptr<LayerImpl> grand_child2 =
115             LayerImpl::Create(host_impl_.active_tree(), 5);
116
117     root->SetPosition(gfx::PointF());
118     root->SetBounds(gfx::Size(500, 500));
119     root->SetContentBounds(gfx::Size(500, 500));
120     root->SetDrawsContent(true);
121     root->CreateRenderSurface();
122     root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
123
124     child1->SetPosition(gfx::PointF(100.f, 100.f));
125     child1->SetBounds(gfx::Size(30, 30));
126     child1->SetContentBounds(gfx::Size(30, 30));
127     // With a child that draws_content, opacity will cause the layer to create
128     // its own RenderSurface. This layer does not draw, but is intended to
129     // create its own RenderSurface. TODO: setting opacity and
130     // ForceRenderSurface may be redundant here.
131     child1->SetOpacity(0.5f);
132     child1->SetDrawsContent(false);
133     child1->SetForceRenderSurface(true);
134
135     child2->SetPosition(gfx::PointF(11.f, 11.f));
136     child2->SetBounds(gfx::Size(18, 18));
137     child2->SetContentBounds(gfx::Size(18, 18));
138     child2->SetDrawsContent(true);
139
140     grand_child1->SetPosition(gfx::PointF(200.f, 200.f));
141     grand_child1->SetBounds(gfx::Size(6, 8));
142     grand_child1->SetContentBounds(gfx::Size(6, 8));
143     grand_child1->SetDrawsContent(true);
144
145     grand_child2->SetPosition(gfx::PointF(190.f, 190.f));
146     grand_child2->SetBounds(gfx::Size(6, 8));
147     grand_child2->SetContentBounds(gfx::Size(6, 8));
148     grand_child2->SetDrawsContent(true);
149
150     child1->AddChild(grand_child1.Pass());
151     child1->AddChild(grand_child2.Pass());
152     root->AddChild(child1.Pass());
153     root->AddChild(child2.Pass());
154
155     return root.Pass();
156   }
157
158   scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithOneSurface() {
159     scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();
160
161     // Setup includes going past the first frame which always damages
162     // everything, so that we can actually perform specific tests.
163     EmulateDrawingOneFrame(root.get());
164
165     return root.Pass();
166   }
167
168   scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithTwoSurfaces() {
169     scoped_ptr<LayerImpl> root = CreateTestTreeWithTwoSurfaces();
170
171     // Setup includes going past the first frame which always damages
172     // everything, so that we can actually perform specific tests.
173     EmulateDrawingOneFrame(root.get());
174
175     return root.Pass();
176   }
177
178  protected:
179   FakeImplProxy proxy_;
180   TestSharedBitmapManager shared_bitmap_manager_;
181   FakeLayerTreeHostImpl host_impl_;
182 };
183
184 TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) {
185   // Sanity check that the simple test tree will actually produce the expected
186   // render surfaces and layer lists.
187
188   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
189
190   EXPECT_EQ(2u, root->render_surface()->layer_list().size());
191   EXPECT_EQ(1, root->render_surface()->layer_list()[0]->id());
192   EXPECT_EQ(2, root->render_surface()->layer_list()[1]->id());
193
194   gfx::Rect root_damage_rect =
195       root->render_surface()->damage_tracker()->current_damage_rect();
196
197   EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
198 }
199
200 TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) {
201   // Sanity check that the complex test tree will actually produce the expected
202   // render surfaces and layer lists.
203
204   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
205
206   LayerImpl* child1 = root->children()[0];
207   LayerImpl* child2 = root->children()[1];
208   gfx::Rect child_damage_rect =
209       child1->render_surface()->damage_tracker()->current_damage_rect();
210   gfx::Rect root_damage_rect =
211       root->render_surface()->damage_tracker()->current_damage_rect();
212
213   ASSERT_TRUE(child1->render_surface());
214   EXPECT_FALSE(child2->render_surface());
215   EXPECT_EQ(3u, root->render_surface()->layer_list().size());
216   EXPECT_EQ(2u, child1->render_surface()->layer_list().size());
217
218   // The render surface for child1 only has a content_rect that encloses
219   // grand_child1 and grand_child2, because child1 does not draw content.
220   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
221             child_damage_rect.ToString());
222   EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString());
223 }
224
225 TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
226   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
227   LayerImpl* child = root->children()[0];
228
229   // CASE 1: Setting the update rect should cause the corresponding damage to
230   //         the surface.
231   ClearDamageForAllSurfaces(root.get());
232   child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
233   EmulateDrawingOneFrame(root.get());
234
235   // Damage position on the surface should be: position of update_rect (10, 11)
236   // relative to the child (100, 100).
237   gfx::Rect root_damage_rect =
238       root->render_surface()->damage_tracker()->current_damage_rect();
239   EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
240             root_damage_rect.ToString());
241
242   // CASE 2: The same update rect twice in a row still produces the same
243   //         damage.
244   ClearDamageForAllSurfaces(root.get());
245   child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
246   EmulateDrawingOneFrame(root.get());
247   root_damage_rect =
248           root->render_surface()->damage_tracker()->current_damage_rect();
249   EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(),
250             root_damage_rect.ToString());
251
252   // CASE 3: Setting a different update rect should cause damage on the new
253   //         update region, but no additional exposed old region.
254   ClearDamageForAllSurfaces(root.get());
255   child->SetUpdateRect(gfx::Rect(20, 25, 1, 2));
256   EmulateDrawingOneFrame(root.get());
257
258   // Damage position on the surface should be: position of update_rect (20, 25)
259   // relative to the child (100, 100).
260   root_damage_rect =
261           root->render_surface()->damage_tracker()->current_damage_rect();
262   EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString());
263 }
264
265 TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
266   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
267   LayerImpl* child = root->children()[0];
268
269   // CASE 1: Adding the layer damage rect should cause the corresponding damage
270   // to the surface.
271   ClearDamageForAllSurfaces(root.get());
272   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
273   EmulateDrawingOneFrame(root.get());
274
275   // Damage position on the surface should be: position of layer damage_rect
276   // (10, 11) relative to the child (100, 100).
277   gfx::Rect root_damage_rect =
278       root->render_surface()->damage_tracker()->current_damage_rect();
279   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
280
281   // CASE 2: The same layer damage rect twice in a row still produces the same
282   // damage.
283   ClearDamageForAllSurfaces(root.get());
284   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
285   EmulateDrawingOneFrame(root.get());
286   root_damage_rect =
287       root->render_surface()->damage_tracker()->current_damage_rect();
288   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
289
290   // CASE 3: Adding a different layer damage rect should cause damage on the
291   // new damaged region, but no additional exposed old region.
292   ClearDamageForAllSurfaces(root.get());
293   child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
294   EmulateDrawingOneFrame(root.get());
295
296   // Damage position on the surface should be: position of layer damage_rect
297   // (20, 25) relative to the child (100, 100).
298   root_damage_rect =
299       root->render_surface()->damage_tracker()->current_damage_rect();
300   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
301
302   // CASE 4: Adding multiple layer damage rects should cause a unified
303   // damage on root damage rect.
304   ClearDamageForAllSurfaces(root.get());
305   child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
306   child->AddDamageRect(gfx::RectF(10.f, 15.f, 3.f, 4.f));
307   EmulateDrawingOneFrame(root.get());
308
309   // Damage position on the surface should be: position of layer damage_rect
310   // (20, 25) relative to the child (100, 100).
311   root_damage_rect =
312       root->render_surface()->damage_tracker()->current_damage_rect();
313   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
314   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4)));
315 }
316
317 TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
318   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
319   LayerImpl* child = root->children()[0];
320
321   // CASE 1: Adding the layer damage rect and update rect should cause the
322   // corresponding damage to the surface.
323   ClearDamageForAllSurfaces(root.get());
324   child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f));
325   child->SetUpdateRect(gfx::Rect(15, 16, 14, 10));
326   EmulateDrawingOneFrame(root.get());
327
328   // Damage position on the surface should be: position of unified layer
329   // damage_rect and update rect (5, 6)
330   // relative to the child (100, 100).
331   gfx::Rect root_damage_rect =
332       root->render_surface()->damage_tracker()->current_damage_rect();
333   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20)));
334
335   // CASE 2: The same layer damage rect and update rect twice in a row still
336   // produces the same damage.
337   ClearDamageForAllSurfaces(root.get());
338   child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
339   child->SetUpdateRect(gfx::Rect(10, 11, 14, 15));
340   EmulateDrawingOneFrame(root.get());
341   root_damage_rect =
342       root->render_surface()->damage_tracker()->current_damage_rect();
343   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15)));
344
345   // CASE 3: Adding a different layer damage rect and update rect should cause
346   // damage on the new damaged region, but no additional exposed old region.
347   ClearDamageForAllSurfaces(root.get());
348   child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f));
349   child->SetUpdateRect(gfx::Rect(5, 10, 7, 8));
350   EmulateDrawingOneFrame(root.get());
351
352   // Damage position on the surface should be: position of unified layer damage
353   // rect and update rect (5, 10) relative to the child (100, 100).
354   root_damage_rect =
355       root->render_surface()->damage_tracker()->current_damage_rect();
356   EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18)));
357 }
358
359 TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
360   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
361   LayerImpl* child = root->children()[0];
362
363   // CASE 1: The layer's property changed flag takes priority over update rect.
364   //
365   ClearDamageForAllSurfaces(root.get());
366   child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
367   child->SetOpacity(0.5f);
368   EmulateDrawingOneFrame(root.get());
369
370   // Sanity check - we should not have accidentally created a separate render
371   // surface for the translucent layer.
372   ASSERT_FALSE(child->render_surface());
373   ASSERT_EQ(2u, root->render_surface()->layer_list().size());
374
375   // Damage should be the entire child layer in target_surface space.
376   gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30);
377   gfx::Rect root_damage_rect =
378       root->render_surface()->damage_tracker()->current_damage_rect();
379   EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());
380
381   // CASE 2: If a layer moves due to property change, it damages both the new
382   //         location and the old (exposed) location. The old location is the
383   //         entire old layer, not just the update_rect.
384
385   // Cycle one frame of no change, just to sanity check that the next rect is
386   // not because of the old damage state.
387   ClearDamageForAllSurfaces(root.get());
388   EmulateDrawingOneFrame(root.get());
389   root_damage_rect =
390           root->render_surface()->damage_tracker()->current_damage_rect();
391   EXPECT_TRUE(root_damage_rect.IsEmpty());
392
393   // Then, test the actual layer movement.
394   ClearDamageForAllSurfaces(root.get());
395   child->SetPosition(gfx::PointF(200.f, 230.f));
396   EmulateDrawingOneFrame(root.get());
397
398   // Expect damage to be the combination of the previous one and the new one.
399   expected_rect.Union(gfx::Rect(200, 230, 30, 30));
400   root_damage_rect =
401           root->render_surface()->damage_tracker()->current_damage_rect();
402   EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect);
403 }
404
405 TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) {
406   // If a layer is transformed, the damage rect should still enclose the entire
407   // transformed layer.
408
409   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
410   LayerImpl* child = root->children()[0];
411
412   gfx::Transform rotation;
413   rotation.Rotate(45.0);
414
415   ClearDamageForAllSurfaces(root.get());
416   child->SetTransformOrigin(gfx::Point3F(
417       child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f));
418   child->SetPosition(gfx::PointF(85.f, 85.f));
419   EmulateDrawingOneFrame(root.get());
420
421   // Sanity check that the layer actually moved to (85, 85), damaging its old
422   // location and new location.
423   gfx::Rect root_damage_rect =
424       root->render_surface()->damage_tracker()->current_damage_rect();
425   EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString());
426
427   // With the anchor on the layer's center, now we can test the rotation more
428   // intuitively, since it applies about the layer's anchor.
429   ClearDamageForAllSurfaces(root.get());
430   child->SetTransform(rotation);
431   EmulateDrawingOneFrame(root.get());
432
433   // Since the child layer is square, rotation by 45 degrees about the center
434   // should increase the size of the expected rect by sqrt(2), centered around
435   // (100, 100). The old exposed region should be fully contained in the new
436   // region.
437   float expected_width = 30.f * sqrt(2.f);
438   float expected_position = 100.f - 0.5f * expected_width;
439   gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF(
440       expected_position, expected_position, expected_width, expected_width));
441   root_damage_rect =
442       root->render_surface()->damage_tracker()->current_damage_rect();
443   EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString());
444 }
445
446 TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
447   // If a layer has a perspective transform that causes w < 0, then not
448   // clipping the layer can cause an invalid damage rect. This test checks that
449   // the w < 0 case is tracked properly.
450   //
451   // The transform is constructed so that if w < 0 clipping is not performed,
452   // the incorrect rect will be very small, specifically: position (500.972504,
453   // 498.544617) and size 0.056610 x 2.910767.  Instead, the correctly
454   // transformed rect should actually be very huge (i.e. in theory, -infinity
455   // on the left), and positioned so that the right-most bound rect will be
456   // approximately 501 units in root surface space.
457   //
458
459   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
460   LayerImpl* child = root->children()[0];
461
462   gfx::Transform transform;
463   transform.Translate3d(500.0, 500.0, 0.0);
464   transform.ApplyPerspectiveDepth(1.0);
465   transform.RotateAboutYAxis(45.0);
466   transform.Translate3d(-50.0, -50.0, 0.0);
467
468   // Set up the child
469   child->SetPosition(gfx::PointF(0.f, 0.f));
470   child->SetBounds(gfx::Size(100, 100));
471   child->SetContentBounds(gfx::Size(100, 100));
472   child->SetTransform(transform);
473   EmulateDrawingOneFrame(root.get());
474
475   // Sanity check that the child layer's bounds would actually get clipped by
476   // w < 0, otherwise this test is not actually testing the intended scenario.
477   gfx::QuadF test_quad(gfx::RectF(gfx::PointF(), gfx::SizeF(100.f, 100.f)));
478   bool clipped = false;
479   MathUtil::MapQuad(transform, test_quad, &clipped);
480   EXPECT_TRUE(clipped);
481
482   // Damage the child without moving it.
483   ClearDamageForAllSurfaces(root.get());
484   child->SetOpacity(0.5f);
485   EmulateDrawingOneFrame(root.get());
486
487   // The expected damage should cover the entire root surface (500x500), but we
488   // don't care whether the damage rect was clamped or is larger than the
489   // surface for this test.
490   gfx::Rect root_damage_rect =
491       root->render_surface()->damage_tracker()->current_damage_rect();
492   gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500));
493   EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about));
494 }
495
496 TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) {
497   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
498   LayerImpl* surface = root->children()[0];
499   LayerImpl* child = surface->children()[0];
500
501   FilterOperations filters;
502   filters.Append(FilterOperation::CreateBlurFilter(5.f));
503   int outset_top, outset_right, outset_bottom, outset_left;
504   filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);
505
506   // Setting the filter will damage the whole surface.
507   ClearDamageForAllSurfaces(root.get());
508   surface->SetFilters(filters);
509   EmulateDrawingOneFrame(root.get());
510
511   // Setting the update rect should cause the corresponding damage to the
512   // surface, blurred based on the size of the blur filter.
513   ClearDamageForAllSurfaces(root.get());
514   child->SetUpdateRect(gfx::Rect(1, 2, 3, 4));
515   EmulateDrawingOneFrame(root.get());
516
517   // Damage position on the surface should be: position of update_rect (1, 2)
518   // relative to the child (300, 300), but expanded by the blur outsets.
519   gfx::Rect root_damage_rect =
520       root->render_surface()->damage_tracker()->current_damage_rect();
521   gfx::Rect expected_damage_rect = gfx::Rect(301, 302, 3, 4);
522
523   expected_damage_rect.Inset(-outset_left,
524                              -outset_top,
525                              -outset_right,
526                              -outset_bottom);
527   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
528 }
529
530 TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) {
531   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
532   LayerImpl* child = root->children()[0];
533   gfx::Rect root_damage_rect, child_damage_rect;
534
535   // Allow us to set damage on child too.
536   child->SetDrawsContent(true);
537
538   skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
539       SkBlurImageFilter::Create(SkIntToScalar(2), SkIntToScalar(2)));
540   FilterOperations filters;
541   filters.Append(FilterOperation::CreateReferenceFilter(filter));
542
543   // Setting the filter will damage the whole surface.
544   ClearDamageForAllSurfaces(root.get());
545   child->SetFilters(filters);
546   EmulateDrawingOneFrame(root.get());
547   root_damage_rect =
548           root->render_surface()->damage_tracker()->current_damage_rect();
549   child_damage_rect =
550           child->render_surface()->damage_tracker()->current_damage_rect();
551   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
552             root_damage_rect.ToString());
553   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
554
555   // CASE 1: Setting the update rect should damage the whole surface (for now)
556   ClearDamageForAllSurfaces(root.get());
557   child->SetUpdateRect(gfx::Rect(1, 1));
558   EmulateDrawingOneFrame(root.get());
559
560   root_damage_rect =
561           root->render_surface()->damage_tracker()->current_damage_rect();
562   child_damage_rect =
563           child->render_surface()->damage_tracker()->current_damage_rect();
564   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
565             root_damage_rect.ToString());
566   EXPECT_EQ(gfx::Rect(30.f, 30.f).ToString(), child_damage_rect.ToString());
567 }
568
569 TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) {
570   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
571   LayerImpl* child1 = root->children()[0];
572   LayerImpl* child2 = root->children()[1];
573
574   // Allow us to set damage on child1 too.
575   child1->SetDrawsContent(true);
576
577   FilterOperations filters;
578   filters.Append(FilterOperation::CreateBlurFilter(2.f));
579   int outset_top, outset_right, outset_bottom, outset_left;
580   filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left);
581
582   // Setting the filter will damage the whole surface.
583   ClearDamageForAllSurfaces(root.get());
584   child1->SetBackgroundFilters(filters);
585   EmulateDrawingOneFrame(root.get());
586
587   // CASE 1: Setting the update rect should cause the corresponding damage to
588   //         the surface, blurred based on the size of the child's background
589   //         blur filter.
590   ClearDamageForAllSurfaces(root.get());
591   root->SetUpdateRect(gfx::Rect(297, 297, 2, 2));
592   EmulateDrawingOneFrame(root.get());
593
594   gfx::Rect root_damage_rect =
595       root->render_surface()->damage_tracker()->current_damage_rect();
596   // Damage position on the surface should be a composition of the damage on
597   // the root and on child2.  Damage on the root should be: position of
598   // update_rect (297, 297), but expanded by the blur outsets.
599   gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2);
600
601   expected_damage_rect.Inset(-outset_left,
602                              -outset_top,
603                              -outset_right,
604                              -outset_bottom);
605   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
606
607   // CASE 2: Setting the update rect should cause the corresponding damage to
608   //         the surface, blurred based on the size of the child's background
609   //         blur filter. Since the damage extends to the right/bottom outside
610   //         of the blurred layer, only the left/top should end up expanded.
611   ClearDamageForAllSurfaces(root.get());
612   root->SetUpdateRect(gfx::Rect(297, 297, 30, 30));
613   EmulateDrawingOneFrame(root.get());
614
615   root_damage_rect =
616           root->render_surface()->damage_tracker()->current_damage_rect();
617   // Damage position on the surface should be a composition of the damage on
618   // the root and on child2.  Damage on the root should be: position of
619   // update_rect (297, 297), but expanded on the left/top by the blur outsets.
620   expected_damage_rect = gfx::Rect(297, 297, 30, 30);
621
622   expected_damage_rect.Inset(-outset_left,
623                              -outset_top,
624                              0,
625                              0);
626   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
627
628   // CASE 3: Setting this update rect outside the blurred content_bounds of the
629   //         blurred child1 will not cause it to be expanded.
630   ClearDamageForAllSurfaces(root.get());
631   root->SetUpdateRect(gfx::Rect(30, 30, 2, 2));
632   EmulateDrawingOneFrame(root.get());
633
634   root_damage_rect =
635           root->render_surface()->damage_tracker()->current_damage_rect();
636   // Damage on the root should be: position of update_rect (30, 30), not
637   // expanded.
638   expected_damage_rect = gfx::Rect(30, 30, 2, 2);
639
640   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
641
642   // CASE 4: Setting this update rect inside the blurred content_bounds but
643   //         outside the original content_bounds of the blurred child1 will
644   //         cause it to be expanded.
645   ClearDamageForAllSurfaces(root.get());
646   root->SetUpdateRect(gfx::Rect(99, 99, 1, 1));
647   EmulateDrawingOneFrame(root.get());
648
649   root_damage_rect =
650           root->render_surface()->damage_tracker()->current_damage_rect();
651   // Damage on the root should be: position of update_rect (99, 99), expanded by
652   // the blurring on child1, but since it is 1 pixel outside the layer, the
653   // expanding should be reduced by 1.
654   expected_damage_rect = gfx::Rect(99, 99, 1, 1);
655
656   expected_damage_rect.Inset(-outset_left + 1,
657                              -outset_top + 1,
658                              -outset_right,
659                              -outset_bottom);
660   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
661
662   // CASE 5: Setting the update rect on child2, which is above child1, will
663   // not get blurred by child1, so it does not need to get expanded.
664   ClearDamageForAllSurfaces(root.get());
665   child2->SetUpdateRect(gfx::Rect(1, 1));
666   EmulateDrawingOneFrame(root.get());
667
668   root_damage_rect =
669           root->render_surface()->damage_tracker()->current_damage_rect();
670   // Damage on child2 should be: position of update_rect offset by the child's
671   // position (11, 11), and not expanded by anything.
672   expected_damage_rect = gfx::Rect(11, 11, 1, 1);
673
674   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
675
676   // CASE 6: Setting the update rect on child1 will also blur the damage, so
677   //         that any pixels needed for the blur are redrawn in the current
678   //         frame.
679   ClearDamageForAllSurfaces(root.get());
680   child1->SetUpdateRect(gfx::Rect(1, 1));
681   EmulateDrawingOneFrame(root.get());
682
683   root_damage_rect =
684           root->render_surface()->damage_tracker()->current_damage_rect();
685   // Damage on child1 should be: position of update_rect offset by the child's
686   // position (100, 100), and expanded by the damage.
687   expected_damage_rect = gfx::Rect(100, 100, 1, 1);
688
689   expected_damage_rect.Inset(-outset_left,
690                              -outset_top,
691                              -outset_right,
692                              -outset_bottom);
693   EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString());
694 }
695
696 TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) {
697   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
698   LayerImpl* child1 = root->children()[0];
699
700   // CASE 1: Adding a new layer should cause the appropriate damage.
701   //
702   ClearDamageForAllSurfaces(root.get());
703   {
704     scoped_ptr<LayerImpl> child2 =
705             LayerImpl::Create(host_impl_.active_tree(), 3);
706     child2->SetPosition(gfx::PointF(400.f, 380.f));
707     child2->SetBounds(gfx::Size(6, 8));
708     child2->SetContentBounds(gfx::Size(6, 8));
709     child2->SetDrawsContent(true);
710     root->AddChild(child2.Pass());
711   }
712   EmulateDrawingOneFrame(root.get());
713
714   // Sanity check - all 3 layers should be on the same render surface; render
715   // surfaces are tested elsewhere.
716   ASSERT_EQ(3u, root->render_surface()->layer_list().size());
717
718   gfx::Rect root_damage_rect =
719       root->render_surface()->damage_tracker()->current_damage_rect();
720   EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());
721
722   // CASE 2: If the layer is removed, its entire old layer becomes exposed, not
723   //         just the last update rect.
724
725   // Advance one frame without damage so that we know the damage rect is not
726   // leftover from the previous case.
727   ClearDamageForAllSurfaces(root.get());
728   EmulateDrawingOneFrame(root.get());
729
730   root_damage_rect =
731           root->render_surface()->damage_tracker()->current_damage_rect();
732   EXPECT_TRUE(root_damage_rect.IsEmpty());
733
734   // Then, test removing child1.
735   root->RemoveChild(child1);
736   child1 = NULL;
737   EmulateDrawingOneFrame(root.get());
738
739   root_damage_rect =
740           root->render_surface()->damage_tracker()->current_damage_rect();
741   EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(),
742             root_damage_rect.ToString());
743 }
744
745 TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) {
746   // If child2 is added to the layer tree, but it doesn't have any explicit
747   // damage of its own, it should still indeed damage the target surface.
748
749   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
750
751   ClearDamageForAllSurfaces(root.get());
752   {
753     scoped_ptr<LayerImpl> child2 =
754             LayerImpl::Create(host_impl_.active_tree(), 3);
755     child2->SetPosition(gfx::PointF(400.f, 380.f));
756     child2->SetBounds(gfx::Size(6, 8));
757     child2->SetContentBounds(gfx::Size(6, 8));
758     child2->SetDrawsContent(true);
759     child2->ResetAllChangeTrackingForSubtree();
760     // Sanity check the initial conditions of the test, if these asserts
761     // trigger, it means the test no longer actually covers the intended
762     // scenario.
763     ASSERT_FALSE(child2->LayerPropertyChanged());
764     ASSERT_TRUE(child2->update_rect().IsEmpty());
765     root->AddChild(child2.Pass());
766   }
767   EmulateDrawingOneFrame(root.get());
768
769   // Sanity check - all 3 layers should be on the same render surface; render
770   // surfaces are tested elsewhere.
771   ASSERT_EQ(3u, root->render_surface()->layer_list().size());
772
773   gfx::Rect root_damage_rect =
774       root->render_surface()->damage_tracker()->current_damage_rect();
775   EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString());
776 }
777
778 TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
779   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
780   LayerImpl* child1 = root->children()[0];
781
782   // In this test we don't want the above tree manipulation to be considered
783   // part of the same frame.
784   ClearDamageForAllSurfaces(root.get());
785   {
786     scoped_ptr<LayerImpl> child2 =
787             LayerImpl::Create(host_impl_.active_tree(), 3);
788     child2->SetPosition(gfx::PointF(400.f, 380.f));
789     child2->SetBounds(gfx::Size(6, 8));
790     child2->SetContentBounds(gfx::Size(6, 8));
791     child2->SetDrawsContent(true);
792     root->AddChild(child2.Pass());
793   }
794   LayerImpl* child2 = root->children()[1];
795   EmulateDrawingOneFrame(root.get());
796
797   // Damaging two layers simultaneously should cause combined damage.
798   // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2);
799   // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4);
800   ClearDamageForAllSurfaces(root.get());
801   child1->SetUpdateRect(gfx::Rect(1, 2));
802   child2->SetUpdateRect(gfx::Rect(3, 4));
803   EmulateDrawingOneFrame(root.get());
804   gfx::Rect root_damage_rect =
805       root->render_surface()->damage_tracker()->current_damage_rect();
806   EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(),
807             root_damage_rect.ToString());
808 }
809
810 TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) {
811   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
812   LayerImpl* child1 = root->children()[0];
813   LayerImpl* child2 = root->children()[1];
814   LayerImpl* grand_child1 = root->children()[0]->children()[0];
815   gfx::Rect child_damage_rect;
816   gfx::Rect root_damage_rect;
817
818   // CASE 1: Damage to a descendant surface should propagate properly to
819   //         ancestor surface.
820   ClearDamageForAllSurfaces(root.get());
821   grand_child1->SetOpacity(0.5f);
822   EmulateDrawingOneFrame(root.get());
823   child_damage_rect =
824           child1->render_surface()->damage_tracker()->current_damage_rect();
825   root_damage_rect =
826           root->render_surface()->damage_tracker()->current_damage_rect();
827   EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
828   EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString());
829
830   // CASE 2: Same as previous case, but with additional damage elsewhere that
831   //         should be properly unioned.
832   // - child1 surface damage in root surface space:
833   //   gfx::Rect(300, 300, 6, 8);
834   // - child2 damage in root surface space:
835   //   gfx::Rect(11, 11, 18, 18);
836   ClearDamageForAllSurfaces(root.get());
837   grand_child1->SetOpacity(0.7f);
838   child2->SetOpacity(0.7f);
839   EmulateDrawingOneFrame(root.get());
840   child_damage_rect =
841           child1->render_surface()->damage_tracker()->current_damage_rect();
842   root_damage_rect =
843           root->render_surface()->damage_tracker()->current_damage_rect();
844   EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString());
845   EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(),
846             root_damage_rect.ToString());
847 }
848
849 TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) {
850   // If descendant layer changes and affects the content bounds of the render
851   // surface, then the entire descendant surface should be damaged, and it
852   // should damage its ancestor surface with the old and new surface regions.
853
854   // This is a tricky case, since only the first grand_child changes, but the
855   // entire surface should be marked dirty.
856
857   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
858   LayerImpl* child1 = root->children()[0];
859   LayerImpl* grand_child1 = root->children()[0]->children()[0];
860   gfx::Rect child_damage_rect;
861   gfx::Rect root_damage_rect;
862
863   ClearDamageForAllSurfaces(root.get());
864   grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
865   EmulateDrawingOneFrame(root.get());
866   child_damage_rect =
867           child1->render_surface()->damage_tracker()->current_damage_rect();
868   root_damage_rect =
869           root->render_surface()->damage_tracker()->current_damage_rect();
870
871   // The new surface bounds should be damaged entirely, even though only one of
872   // the layers changed.
873   EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(),
874             child_damage_rect.ToString());
875
876   // Damage to the root surface should be the union of child1's *entire* render
877   // surface (in target space), and its old exposed area (also in target
878   // space).
879   EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(),
880             root_damage_rect.ToString());
881 }
882
883 TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) {
884   // An ancestor/owning layer changes that affects the position/transform of
885   // the render surface. Note that in this case, the layer_property_changed flag
886   // already propagates to the subtree (tested in LayerImpltest), which damages
887   // the entire child1 surface, but the damage tracker still needs the correct
888   // logic to compute the exposed region on the root surface.
889
890   // TODO(shawnsingh): the expectations of this test case should change when we
891   // add support for a unique scissor_rect per RenderSurface. In that case, the
892   // child1 surface should be completely unchanged, since we are only
893   // transforming it, while the root surface would be damaged appropriately.
894
895   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
896   LayerImpl* child1 = root->children()[0];
897   gfx::Rect child_damage_rect;
898   gfx::Rect root_damage_rect;
899
900   ClearDamageForAllSurfaces(root.get());
901   child1->SetPosition(gfx::PointF(50.f, 50.f));
902   EmulateDrawingOneFrame(root.get());
903   child_damage_rect =
904           child1->render_surface()->damage_tracker()->current_damage_rect();
905   root_damage_rect =
906           root->render_surface()->damage_tracker()->current_damage_rect();
907
908   // The new surface bounds should be damaged entirely.
909   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
910             child_damage_rect.ToString());
911
912   // The entire child1 surface and the old exposed child1 surface should damage
913   // the root surface.
914   //  - old child1 surface in target space: gfx::Rect(290, 290, 16, 18)
915   //  - new child1 surface in target space: gfx::Rect(240, 240, 16, 18)
916   EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(),
917             root_damage_rect.ToString());
918 }
919
920 TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) {
921   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
922   LayerImpl* child1 = root->children()[0];
923   gfx::Rect child_damage_rect;
924   gfx::Rect root_damage_rect;
925
926   // CASE 1: If a descendant surface disappears, its entire old area becomes
927   //         exposed.
928   ClearDamageForAllSurfaces(root.get());
929   child1->SetOpacity(1.f);
930   child1->SetForceRenderSurface(false);
931   EmulateDrawingOneFrame(root.get());
932
933   // Sanity check that there is only one surface now.
934   ASSERT_FALSE(child1->render_surface());
935   ASSERT_EQ(4u, root->render_surface()->layer_list().size());
936
937   root_damage_rect =
938           root->render_surface()->damage_tracker()->current_damage_rect();
939   EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
940             root_damage_rect.ToString());
941
942   // CASE 2: If a descendant surface appears, its entire old area becomes
943   //         exposed.
944
945   // Cycle one frame of no change, just to sanity check that the next rect is
946   // not because of the old damage state.
947   ClearDamageForAllSurfaces(root.get());
948   EmulateDrawingOneFrame(root.get());
949   root_damage_rect =
950           root->render_surface()->damage_tracker()->current_damage_rect();
951   EXPECT_TRUE(root_damage_rect.IsEmpty());
952
953   // Then change the tree so that the render surface is added back.
954   ClearDamageForAllSurfaces(root.get());
955   child1->SetOpacity(0.5f);
956   child1->SetForceRenderSurface(true);
957   EmulateDrawingOneFrame(root.get());
958
959   // Sanity check that there is a new surface now.
960   ASSERT_TRUE(child1->render_surface());
961   EXPECT_EQ(3u, root->render_surface()->layer_list().size());
962   EXPECT_EQ(2u, child1->render_surface()->layer_list().size());
963
964   child_damage_rect =
965           child1->render_surface()->damage_tracker()->current_damage_rect();
966   root_damage_rect =
967           root->render_surface()->damage_tracker()->current_damage_rect();
968   EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(),
969             child_damage_rect.ToString());
970   EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(),
971             root_damage_rect.ToString());
972 }
973
974 TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) {
975   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
976   LayerImpl* child1 = root->children()[0];
977   gfx::Rect child_damage_rect;
978   gfx::Rect root_damage_rect;
979
980   // CASE 1: If nothing changes, the damage rect should be empty.
981   //
982   ClearDamageForAllSurfaces(root.get());
983   EmulateDrawingOneFrame(root.get());
984   child_damage_rect =
985           child1->render_surface()->damage_tracker()->current_damage_rect();
986   root_damage_rect =
987           root->render_surface()->damage_tracker()->current_damage_rect();
988   EXPECT_TRUE(child_damage_rect.IsEmpty());
989   EXPECT_TRUE(root_damage_rect.IsEmpty());
990
991   // CASE 2: If nothing changes twice in a row, the damage rect should still be
992   //         empty.
993   //
994   ClearDamageForAllSurfaces(root.get());
995   EmulateDrawingOneFrame(root.get());
996   child_damage_rect =
997           child1->render_surface()->damage_tracker()->current_damage_rect();
998   root_damage_rect =
999           root->render_surface()->damage_tracker()->current_damage_rect();
1000   EXPECT_TRUE(child_damage_rect.IsEmpty());
1001   EXPECT_TRUE(root_damage_rect.IsEmpty());
1002 }
1003
1004 TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) {
1005   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
1006   LayerImpl* child1 = root->children()[0];
1007   gfx::Rect child_damage_rect;
1008   gfx::Rect root_damage_rect;
1009
1010   // In our specific tree, the update rect of child1 should not cause any
1011   // damage to any surface because it does not actually draw content.
1012   ClearDamageForAllSurfaces(root.get());
1013   child1->SetUpdateRect(gfx::Rect(1, 2));
1014   EmulateDrawingOneFrame(root.get());
1015   child_damage_rect =
1016           child1->render_surface()->damage_tracker()->current_damage_rect();
1017   root_damage_rect =
1018           root->render_surface()->damage_tracker()->current_damage_rect();
1019   EXPECT_TRUE(child_damage_rect.IsEmpty());
1020   EXPECT_TRUE(root_damage_rect.IsEmpty());
1021 }
1022
1023 TEST_F(DamageTrackerTest, VerifyDamageForReplica) {
1024   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
1025   LayerImpl* child1 = root->children()[0];
1026   LayerImpl* grand_child1 = child1->children()[0];
1027   LayerImpl* grand_child2 = child1->children()[1];
1028
1029   // Damage on a surface that has a reflection should cause the target surface
1030   // to receive the surface's damage and the surface's reflected damage.
1031
1032   // For this test case, we modify grand_child2, and add grand_child3 to extend
1033   // the bounds of child1's surface. This way, we can test reflection changes
1034   // without changing content_bounds of the surface.
1035   grand_child2->SetPosition(gfx::PointF(180.f, 180.f));
1036   {
1037     scoped_ptr<LayerImpl> grand_child3 =
1038             LayerImpl::Create(host_impl_.active_tree(), 6);
1039     grand_child3->SetPosition(gfx::PointF(240.f, 240.f));
1040     grand_child3->SetBounds(gfx::Size(10, 10));
1041     grand_child3->SetContentBounds(gfx::Size(10, 10));
1042     grand_child3->SetDrawsContent(true);
1043     child1->AddChild(grand_child3.Pass());
1044   }
1045   child1->SetOpacity(0.5f);
1046   EmulateDrawingOneFrame(root.get());
1047
1048   // CASE 1: adding a reflection about the left edge of grand_child1.
1049   //
1050   ClearDamageForAllSurfaces(root.get());
1051   {
1052     scoped_ptr<LayerImpl> grand_child1_replica =
1053             LayerImpl::Create(host_impl_.active_tree(), 7);
1054     grand_child1_replica->SetPosition(gfx::PointF());
1055     gfx::Transform reflection;
1056     reflection.Scale3d(-1.0, 1.0, 1.0);
1057     grand_child1_replica->SetTransform(reflection);
1058     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
1059   }
1060   EmulateDrawingOneFrame(root.get());
1061
1062   gfx::Rect grand_child_damage_rect =
1063       grand_child1->render_surface()->damage_tracker()->current_damage_rect();
1064   gfx::Rect child_damage_rect =
1065       child1->render_surface()->damage_tracker()->current_damage_rect();
1066   gfx::Rect root_damage_rect =
1067       root->render_surface()->damage_tracker()->current_damage_rect();
1068
1069   // The grand_child surface damage should not include its own replica. The
1070   // child surface damage should include the normal and replica surfaces.
1071   EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
1072   EXPECT_EQ(gfx::Rect(194, 200, 12, 8).ToString(),
1073             child_damage_rect.ToString());
1074   EXPECT_EQ(gfx::Rect(294, 300, 12, 8).ToString(), root_damage_rect.ToString());
1075
1076   // CASE 2: moving the descendant surface should cause both the original and
1077   //         reflected areas to be damaged on the target.
1078   ClearDamageForAllSurfaces(root.get());
1079   gfx::Rect old_content_rect = child1->render_surface()->content_rect();
1080   grand_child1->SetPosition(gfx::PointF(195.f, 205.f));
1081   EmulateDrawingOneFrame(root.get());
1082   ASSERT_EQ(old_content_rect.width(),
1083             child1->render_surface()->content_rect().width());
1084   ASSERT_EQ(old_content_rect.height(),
1085             child1->render_surface()->content_rect().height());
1086
1087   grand_child_damage_rect =
1088           grand_child1->render_surface()->
1089               damage_tracker()->current_damage_rect();
1090   child_damage_rect =
1091           child1->render_surface()->damage_tracker()->current_damage_rect();
1092   root_damage_rect =
1093           root->render_surface()->damage_tracker()->current_damage_rect();
1094
1095   // The child surface damage should include normal and replica surfaces for
1096   // both old and new locations.
1097   //  - old location in target space: gfx::Rect(194, 200, 12, 8)
1098   //  - new location in target space: gfx::Rect(189, 205, 12, 8)
1099   EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString());
1100   EXPECT_EQ(gfx::Rect(189, 200, 17, 13).ToString(),
1101             child_damage_rect.ToString());
1102   EXPECT_EQ(gfx::Rect(289, 300, 17, 13).ToString(),
1103             root_damage_rect.ToString());
1104
1105   // CASE 3: removing the reflection should cause the entire region including
1106   //         reflection to damage the target surface.
1107   ClearDamageForAllSurfaces(root.get());
1108   grand_child1->SetReplicaLayer(nullptr);
1109   EmulateDrawingOneFrame(root.get());
1110   ASSERT_EQ(old_content_rect.width(),
1111             child1->render_surface()->content_rect().width());
1112   ASSERT_EQ(old_content_rect.height(),
1113             child1->render_surface()->content_rect().height());
1114
1115   EXPECT_FALSE(grand_child1->render_surface());
1116   child_damage_rect =
1117           child1->render_surface()->damage_tracker()->current_damage_rect();
1118   root_damage_rect =
1119           root->render_surface()->damage_tracker()->current_damage_rect();
1120
1121   EXPECT_EQ(gfx::Rect(189, 205, 12, 8).ToString(),
1122             child_damage_rect.ToString());
1123   EXPECT_EQ(gfx::Rect(289, 305, 12, 8).ToString(), root_damage_rect.ToString());
1124 }
1125
1126 TEST_F(DamageTrackerTest, VerifyDamageForMask) {
1127   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
1128   LayerImpl* child = root->children()[0];
1129
1130   // In the current implementation of the damage tracker, changes to mask
1131   // layers should damage the entire corresponding surface.
1132
1133   ClearDamageForAllSurfaces(root.get());
1134
1135   // Set up the mask layer.
1136   {
1137     scoped_ptr<LayerImpl> mask_layer =
1138             LayerImpl::Create(host_impl_.active_tree(), 3);
1139     mask_layer->SetPosition(child->position());
1140     mask_layer->SetBounds(child->bounds());
1141     mask_layer->SetContentBounds(child->bounds());
1142     child->SetMaskLayer(mask_layer.Pass());
1143   }
1144   LayerImpl* mask_layer = child->mask_layer();
1145
1146   // Add opacity and a grand_child so that the render surface persists even
1147   // after we remove the mask.
1148   child->SetOpacity(0.5f);
1149   {
1150     scoped_ptr<LayerImpl> grand_child =
1151             LayerImpl::Create(host_impl_.active_tree(), 4);
1152     grand_child->SetPosition(gfx::PointF(2.f, 2.f));
1153     grand_child->SetBounds(gfx::Size(2, 2));
1154     grand_child->SetContentBounds(gfx::Size(2, 2));
1155     grand_child->SetDrawsContent(true);
1156     child->AddChild(grand_child.Pass());
1157   }
1158   EmulateDrawingOneFrame(root.get());
1159
1160   // Sanity check that a new surface was created for the child.
1161   ASSERT_TRUE(child->render_surface());
1162
1163   // CASE 1: the update_rect on a mask layer should damage the entire target
1164   //         surface.
1165   ClearDamageForAllSurfaces(root.get());
1166   mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4));
1167   EmulateDrawingOneFrame(root.get());
1168   gfx::Rect child_damage_rect =
1169       child->render_surface()->damage_tracker()->current_damage_rect();
1170   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
1171
1172   // CASE 2: a property change on the mask layer should damage the entire
1173   //         target surface.
1174
1175   // Advance one frame without damage so that we know the damage rect is not
1176   // leftover from the previous case.
1177   ClearDamageForAllSurfaces(root.get());
1178   EmulateDrawingOneFrame(root.get());
1179   child_damage_rect =
1180           child->render_surface()->damage_tracker()->current_damage_rect();
1181   EXPECT_TRUE(child_damage_rect.IsEmpty());
1182
1183   // Then test the property change.
1184   ClearDamageForAllSurfaces(root.get());
1185   mask_layer->SetStackingOrderChanged(true);
1186
1187   EmulateDrawingOneFrame(root.get());
1188   child_damage_rect =
1189           child->render_surface()->damage_tracker()->current_damage_rect();
1190   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
1191
1192   // CASE 3: removing the mask also damages the entire target surface.
1193   //
1194
1195   // Advance one frame without damage so that we know the damage rect is not
1196   // leftover from the previous case.
1197   ClearDamageForAllSurfaces(root.get());
1198   EmulateDrawingOneFrame(root.get());
1199   child_damage_rect =
1200           child->render_surface()->damage_tracker()->current_damage_rect();
1201   EXPECT_TRUE(child_damage_rect.IsEmpty());
1202
1203   // Then test mask removal.
1204   ClearDamageForAllSurfaces(root.get());
1205   child->SetMaskLayer(nullptr);
1206   ASSERT_TRUE(child->LayerPropertyChanged());
1207   EmulateDrawingOneFrame(root.get());
1208
1209   // Sanity check that a render surface still exists.
1210   ASSERT_TRUE(child->render_surface());
1211
1212   child_damage_rect =
1213           child->render_surface()->damage_tracker()->current_damage_rect();
1214   EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString());
1215 }
1216
1217 TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) {
1218   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
1219   LayerImpl* child1 = root->children()[0];
1220   LayerImpl* grand_child1 = child1->children()[0];
1221
1222   // Changes to a replica's mask should not damage the original surface,
1223   // because it is not masked. But it does damage the ancestor target surface.
1224
1225   ClearDamageForAllSurfaces(root.get());
1226
1227   // Create a reflection about the left edge of grand_child1.
1228   {
1229     scoped_ptr<LayerImpl> grand_child1_replica =
1230             LayerImpl::Create(host_impl_.active_tree(), 6);
1231     grand_child1_replica->SetPosition(gfx::PointF());
1232     gfx::Transform reflection;
1233     reflection.Scale3d(-1.0, 1.0, 1.0);
1234     grand_child1_replica->SetTransform(reflection);
1235     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
1236   }
1237   LayerImpl* grand_child1_replica = grand_child1->replica_layer();
1238
1239   // Set up the mask layer on the replica layer
1240   {
1241     scoped_ptr<LayerImpl> replica_mask_layer =
1242             LayerImpl::Create(host_impl_.active_tree(), 7);
1243     replica_mask_layer->SetPosition(gfx::PointF());
1244     replica_mask_layer->SetBounds(grand_child1->bounds());
1245     replica_mask_layer->SetContentBounds(grand_child1->bounds());
1246     grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
1247   }
1248   LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
1249
1250   EmulateDrawingOneFrame(root.get());
1251
1252   // Sanity check that the appropriate render surfaces were created
1253   ASSERT_TRUE(grand_child1->render_surface());
1254
1255   // CASE 1: a property change on the mask should damage only the reflected
1256   //         region on the target surface.
1257   ClearDamageForAllSurfaces(root.get());
1258   replica_mask_layer->SetStackingOrderChanged(true);
1259   EmulateDrawingOneFrame(root.get());
1260
1261   gfx::Rect grand_child_damage_rect =
1262       grand_child1->render_surface()->damage_tracker()->current_damage_rect();
1263   gfx::Rect child_damage_rect =
1264       child1->render_surface()->damage_tracker()->current_damage_rect();
1265
1266   EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
1267   EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());
1268
1269   // CASE 2: removing the replica mask damages only the reflected region on the
1270   //         target surface.
1271   //
1272   ClearDamageForAllSurfaces(root.get());
1273   grand_child1_replica->SetMaskLayer(nullptr);
1274   EmulateDrawingOneFrame(root.get());
1275
1276   grand_child_damage_rect =
1277           grand_child1->render_surface()->damage_tracker()->
1278               current_damage_rect();
1279   child_damage_rect =
1280           child1->render_surface()->damage_tracker()->current_damage_rect();
1281
1282   EXPECT_TRUE(grand_child_damage_rect.IsEmpty());
1283   EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString());
1284 }
1285
1286 TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) {
1287   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces();
1288   LayerImpl* child1 = root->children()[0];
1289   LayerImpl* grand_child1 = child1->children()[0];
1290
1291   // Verify that the correct replica_origin_transform is used for the
1292   // replica_mask.
1293   ClearDamageForAllSurfaces(root.get());
1294
1295   // This is not actually the transform origin point being tested, but by
1296   // convention its
1297   // expected to be the same as the replica's anchor point.
1298   grand_child1->SetTransformOrigin(
1299       gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));
1300
1301   {
1302     scoped_ptr<LayerImpl> grand_child1_replica =
1303             LayerImpl::Create(host_impl_.active_tree(), 6);
1304     grand_child1_replica->SetPosition(gfx::PointF());
1305
1306     // This is the anchor being tested.
1307     grand_child1_replica->SetTransformOrigin(
1308         gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f));
1309     gfx::Transform reflection;
1310     reflection.Scale3d(-1.0, 1.0, 1.0);
1311     grand_child1_replica->SetTransform(reflection);
1312     grand_child1->SetReplicaLayer(grand_child1_replica.Pass());
1313   }
1314   LayerImpl* grand_child1_replica = grand_child1->replica_layer();
1315
1316   // Set up the mask layer on the replica layer
1317   {
1318     scoped_ptr<LayerImpl> replica_mask_layer =
1319             LayerImpl::Create(host_impl_.active_tree(), 7);
1320     replica_mask_layer->SetPosition(gfx::PointF());
1321     // Note: this is not the transform origin being tested.
1322     replica_mask_layer->SetBounds(grand_child1->bounds());
1323     replica_mask_layer->SetContentBounds(grand_child1->bounds());
1324     grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
1325   }
1326   LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
1327
1328   EmulateDrawingOneFrame(root.get());
1329
1330   // Sanity check that the appropriate render surfaces were created
1331   ASSERT_TRUE(grand_child1->render_surface());
1332
1333   // A property change on the replica_mask should damage the reflected region on
1334   // the target surface.
1335   ClearDamageForAllSurfaces(root.get());
1336   replica_mask_layer->SetStackingOrderChanged(true);
1337
1338   EmulateDrawingOneFrame(root.get());
1339
1340   gfx::Rect child_damage_rect =
1341       child1->render_surface()->damage_tracker()->current_damage_rect();
1342   EXPECT_EQ(gfx::Rect(206, 200, 6, 8).ToString(), child_damage_rect.ToString());
1343 }
1344
1345 TEST_F(DamageTrackerTest, DamageWhenAddedExternally) {
1346   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
1347   LayerImpl* child = root->children()[0];
1348
1349   // Case 1: This test ensures that when the tracker is given damage, that
1350   //         it is included with any other partial damage.
1351   //
1352   ClearDamageForAllSurfaces(root.get());
1353   child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
1354   root->render_surface()->damage_tracker()->AddDamageNextUpdate(
1355       gfx::Rect(15, 16, 32, 33));
1356   EmulateDrawingOneFrame(root.get());
1357   gfx::Rect root_damage_rect =
1358       root->render_surface()->damage_tracker()->current_damage_rect();
1359   EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33),
1360                             gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(),
1361             root_damage_rect.ToString());
1362
1363   // Case 2: An additional sanity check that adding damage works even when
1364   //         nothing on the layer tree changed.
1365   //
1366   ClearDamageForAllSurfaces(root.get());
1367   root->render_surface()->damage_tracker()->AddDamageNextUpdate(
1368       gfx::Rect(30, 31, 14, 15));
1369   EmulateDrawingOneFrame(root.get());
1370   root_damage_rect =
1371       root->render_surface()->damage_tracker()->current_damage_rect();
1372   EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString());
1373 }
1374
1375 TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) {
1376   // Though it should never happen, its a good idea to verify that the damage
1377   // tracker does not crash when it receives an empty layer_list.
1378
1379   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1);
1380   root->CreateRenderSurface();
1381
1382   ASSERT_TRUE(root == root->render_target());
1383   RenderSurfaceImpl* target_surface = root->render_surface();
1384
1385   LayerImplList empty_list;
1386   target_surface->damage_tracker()->UpdateDamageTrackingState(
1387       empty_list,
1388       target_surface->OwningLayerId(),
1389       false,
1390       gfx::Rect(),
1391       NULL,
1392       FilterOperations());
1393
1394   gfx::Rect damage_rect =
1395       target_surface->damage_tracker()->current_damage_rect();
1396   EXPECT_TRUE(damage_rect.IsEmpty());
1397 }
1398
1399 TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) {
1400   // If damage is not cleared, it should accumulate.
1401
1402   scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
1403   LayerImpl* child = root->children()[0];
1404
1405   ClearDamageForAllSurfaces(root.get());
1406   child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f));
1407   EmulateDrawingOneFrame(root.get());
1408
1409   // Sanity check damage after the first frame; this isnt the actual test yet.
1410   gfx::Rect root_damage_rect =
1411       root->render_surface()->damage_tracker()->current_damage_rect();
1412   EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString());
1413
1414   // New damage, without having cleared the previous damage, should be unioned
1415   // to the previous one.
1416   child->SetUpdateRect(gfx::Rect(20, 25, 1, 2));
1417   EmulateDrawingOneFrame(root.get());
1418   root_damage_rect =
1419           root->render_surface()->damage_tracker()->current_damage_rect();
1420   EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(),
1421             root_damage_rect.ToString());
1422
1423   // If we notify the damage tracker that we drew the damaged area, then damage
1424   // should be emptied.
1425   root->render_surface()->damage_tracker()->DidDrawDamagedArea();
1426   root_damage_rect =
1427           root->render_surface()->damage_tracker()->current_damage_rect();
1428   EXPECT_TRUE(root_damage_rect.IsEmpty());
1429
1430   // Damage should remain empty even after one frame, since there's yet no new
1431   // damage.
1432   EmulateDrawingOneFrame(root.get());
1433   root_damage_rect =
1434           root->render_surface()->damage_tracker()->current_damage_rect();
1435   EXPECT_TRUE(root_damage_rect.IsEmpty());
1436 }
1437
1438 TEST_F(DamageTrackerTest, HugeDamageRect) {
1439   // This number is so large that we start losting floating point accuracy.
1440   const int kBigNumber = 900000000;
1441   // Walk over a range to find floating point inaccuracy boundaries that move
1442   // toward the wrong direction.
1443   const int kRange = 5000;
1444
1445   for (int i = 0; i < kRange; ++i) {
1446     scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface();
1447     LayerImpl* child = root->children()[0];
1448
1449     gfx::Transform transform;
1450     transform.Translate(-kBigNumber, -kBigNumber);
1451
1452     // The child layer covers (0, 0, i, i) of the viewport,
1453     // but has a huge negative position.
1454     child->SetPosition(gfx::PointF());
1455     child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
1456     child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
1457     child->SetTransform(transform);
1458     EmulateDrawingOneFrame(root.get());
1459
1460     // The expected damage should cover the visible part of the child layer,
1461     // which is (0, 0, i, i) in the viewport.
1462     gfx::Rect root_damage_rect =
1463         root->render_surface()->damage_tracker()->current_damage_rect();
1464     gfx::Rect damage_we_care_about = gfx::Rect(i, i);
1465     EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right());
1466     EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom());
1467   }
1468 }
1469
1470 }  // namespace
1471 }  // namespace cc