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