12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/damage_tracker.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/output/filter_operation.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/output/filter_operations.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_impl_proxy.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_layer_tree_host_impl.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/geometry_test_utils.h" 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "cc/test/test_shared_bitmap_manager.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host_common.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/effects/SkBlurImageFilter.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/geometry/quad_f.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/geometry/rect_conversions.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ExecuteCalculateDrawProperties(LayerImpl* root, 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LayerImplList* render_surface_layer_list) { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check: The test itself should create the root layer's render 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface, so that the surface (and its damage tracker) can 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // persist across multiple calls to this function. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(root->render_surface()); 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ASSERT_FALSE(render_surface_layer_list->size()); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); 34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) root, root->bounds(), render_surface_layer_list); 36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LayerTreeHostCommon::CalculateDrawProperties(&inputs); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ClearDamageForAllSurfaces(LayerImpl* layer) { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (layer->render_surface()) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer->render_surface()->damage_tracker()->DidDrawDamagedArea(); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Recursively clear damage for any existing surface. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < layer->children().size(); ++i) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(layer->children()[i]); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void EmulateDrawingOneFrame(LayerImpl* root) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This emulates only steps that are relevant to testing the damage tracker: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. computing the render passes and layerlists 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. updating all damage trackers in the correct order 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3. resetting all update_rects and property_changed flags for all layers 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and surfaces. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImplList render_surface_layer_list; 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ExecuteCalculateDrawProperties(root, &render_surface_layer_list); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Iterate back-to-front, so that damage correctly propagates from descendant 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surfaces to ancestors. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = render_surface_layer_list.size() - 1; i >= 0; --i) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderSurfaceImpl* target_surface = 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_surface_layer_list[i]->render_surface(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->damage_tracker()->UpdateDamageTrackingState( 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->layer_list(), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->OwningLayerId(), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->SurfacePropertyChangedOnlyFromDescendant(), 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->content_rect(), 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_surface_layer_list[i]->mask_layer(), 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) render_surface_layer_list[i]->filters()); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->ResetAllChangeTrackingForSubtree(); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DamageTrackerTest : public testing::Test { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DamageTrackerTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> CreateTestTreeWithOneSurface() { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 1); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child = 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 2); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetPosition(gfx::PointF()); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetBounds(gfx::Size(500, 500)); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetContentBounds(gfx::Size(500, 500)); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetDrawsContent(true); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->CreateRenderSurface(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500)); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetPosition(gfx::PointF(100.f, 100.f)); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetBounds(gfx::Size(30, 30)); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetContentBounds(gfx::Size(30, 30)); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetDrawsContent(true); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child.Pass()); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return root.Pass(); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> CreateTestTreeWithTwoSurfaces() { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This test tree has two render surfaces: one for the root, and one for 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // child1. Additionally, the root has a second child layer, and child1 has 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // two children of its own. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 1); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child1 = 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 2); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child2 = 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child1 = 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 4); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child2 = 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 5); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetPosition(gfx::PointF()); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetBounds(gfx::Size(500, 500)); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetContentBounds(gfx::Size(500, 500)); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->SetDrawsContent(true); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->CreateRenderSurface(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500)); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetPosition(gfx::PointF(100.f, 100.f)); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetBounds(gfx::Size(30, 30)); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetContentBounds(gfx::Size(30, 30)); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // With a child that draws_content, opacity will cause the layer to create 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its own RenderSurface. This layer does not draw, but is intended to 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // create its own RenderSurface. TODO: setting opacity and 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ForceRenderSurface may be redundant here. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetOpacity(0.5f); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetDrawsContent(false); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetForceRenderSurface(true); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetPosition(gfx::PointF(11.f, 11.f)); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetBounds(gfx::Size(18, 18)); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetContentBounds(gfx::Size(18, 18)); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetDrawsContent(true); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetPosition(gfx::PointF(200.f, 200.f)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetBounds(gfx::Size(6, 8)); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetContentBounds(gfx::Size(6, 8)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetDrawsContent(true); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child2->SetPosition(gfx::PointF(190.f, 190.f)); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child2->SetBounds(gfx::Size(6, 8)); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child2->SetContentBounds(gfx::Size(6, 8)); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child2->SetDrawsContent(true); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->AddChild(grand_child1.Pass()); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->AddChild(grand_child2.Pass()); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child1.Pass()); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child2.Pass()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return root.Pass(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithOneSurface() { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup includes going past the first frame which always damages 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // everything, so that we can actually perform specific tests. 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return root.Pass(); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> CreateAndSetUpTestTreeWithTwoSurfaces() { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateTestTreeWithTwoSurfaces(); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup includes going past the first frame which always damages 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // everything, so that we can actually perform specific tests. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return root.Pass(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FakeImplProxy proxy_; 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) TestSharedBitmapManager shared_bitmap_manager_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FakeLayerTreeHostImpl host_impl_; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the simple test tree will actually produce the expected 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // render surfaces and layer lists. 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2u, root->render_surface()->layer_list().size()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, root->render_surface()->layer_list()[0]->id()); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2, root->render_surface()->layer_list()[1]->id()); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the complex test tree will actually produce the expected 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // render surfaces and layer lists. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child2 = root->children()[1]; 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect = 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child1->render_surface()->damage_tracker()->current_damage_rect(); 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child1->render_surface()); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(child2->render_surface()); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(3u, root->render_surface()->layer_list().size()); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2u, child1->render_surface()->layer_list().size()); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The render surface for child1 only has a content_rect that encloses 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // grand_child1 and grand_child2, because child1 does not draw content. 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: Setting the update rect should cause the corresponding damage to 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the surface. 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage position on the surface should be: position of update_rect (10, 11) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // relative to the child (100, 100). 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: The same update rect twice in a row still produces the same 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // damage. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 3: Setting a different update rect should cause damage on the new 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // update region, but no additional exposed old region. 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage position on the surface should be: position of update_rect (20, 25) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // relative to the child (100, 100). 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString()); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { 2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LayerImpl* child = root->children()[0]; 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 1: Adding the layer damage rect should cause the corresponding damage 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // to the surface. 2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Damage position on the surface should be: position of layer damage_rect 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // (10, 11) relative to the child (100, 100). 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect root_damage_rect = 2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13))); 2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 2: The same layer damage rect twice in a row still produces the same 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // damage. 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root_damage_rect = 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13))); 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 3: Adding a different layer damage rect should cause damage on the 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // new damaged region, but no additional exposed old region. 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); 2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Damage position on the surface should be: position of layer damage_rect 2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // (20, 25) relative to the child (100, 100). 2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root_damage_rect = 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2))); 3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 4: Adding multiple layer damage rects should cause a unified 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // damage on root damage rect. 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(10.f, 15.f, 3.f, 4.f)); 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Damage position on the surface should be: position of layer damage_rect 3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // (20, 25) relative to the child (100, 100). 3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root_damage_rect = 3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2))); 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4))); 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { 3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LayerImpl* child = root->children()[0]; 3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 1: Adding the layer damage rect and update rect should cause the 3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // corresponding damage to the surface. 3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f)); 3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->SetUpdateRect(gfx::RectF(15.f, 16.f, 14.f, 10.f)); 3265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Damage position on the surface should be: position of unified layer 3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // damage_rect and update rect (5, 6) 3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // relative to the child (100, 100). 3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect root_damage_rect = 3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20))); 3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 2: The same layer damage rect and update rect twice in a row still 3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // produces the same damage. 3375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 3395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->SetUpdateRect(gfx::RectF(10.f, 11.f, 14.f, 15.f)); 3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root_damage_rect = 3425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15))); 3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // CASE 3: Adding a different layer damage rect and update rect should cause 3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // damage on the new damaged region, but no additional exposed old region. 3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ClearDamageForAllSurfaces(root.get()); 3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f)); 3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu child->SetUpdateRect(gfx::RectF(5.f, 10.f, 7.f, 8.f)); 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmulateDrawingOneFrame(root.get()); 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Damage position on the surface should be: position of unified layer damage 3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // rect and update rect (5, 10) relative to the child (100, 100). 3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root_damage_rect = 3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root->render_surface()->damage_tracker()->current_damage_rect(); 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18))); 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: The layer's property changed flag takes priority over update rect. 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetOpacity(0.5f); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check - we should not have accidentally created a separate render 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface for the translucent layer. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(child->render_surface()); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(2u, root->render_surface()->layer_list().size()); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage should be the entire child layer in target_surface space. 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30); 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: If a layer moves due to property change, it damages both the new 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // location and the old (exposed) location. The old location is the 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // entire old layer, not just the update_rect. 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Cycle one frame of no change, just to sanity check that the next rect is 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not because of the old damage state. 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then, test the actual layer movement. 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetPosition(gfx::PointF(200.f, 230.f)); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Expect damage to be the combination of the previous one and the new one. 399c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_rect.Union(gfx::Rect(200, 230, 30, 30)); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a layer is transformed, the damage rect should still enclose the entire 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // transformed layer. 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform rotation; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation.Rotate(45.0); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) child->SetTransformOrigin(gfx::Point3F( 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f)); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetPosition(gfx::PointF(85.f, 85.f)); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the layer actually moved to (85, 85), damaging its old 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // location and new location. 423c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 425c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString()); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // With the anchor on the layer's center, now we can test the rotation more 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // intuitively, since it applies about the layer's anchor. 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetTransform(rotation); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the child layer is square, rotation by 45 degrees about the center 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should increase the size of the expected rect by sqrt(2), centered around 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (100, 100). The old exposed region should be fully contained in the new 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // region. 43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float expected_width = 30.f * sqrt(2.f); 43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float expected_position = 100.f - 0.5f * expected_width; 439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF( 440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_position, expected_position, expected_width, expected_width)); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a layer has a perspective transform that causes w < 0, then not 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // clipping the layer can cause an invalid damage rect. This test checks that 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the w < 0 case is tracked properly. 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The transform is constructed so that if w < 0 clipping is not performed, 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the incorrect rect will be very small, specifically: position (500.972504, 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 498.544617) and size 0.056610 x 2.910767. Instead, the correctly 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // transformed rect should actually be very huge (i.e. in theory, -infinity 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // on the left), and positioned so that the right-most bound rect will be 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // approximately 501 units in root surface space. 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform transform; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate3d(500.0, 500.0, 0.0); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.ApplyPerspectiveDepth(1.0); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.RotateAboutYAxis(45.0); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transform.Translate3d(-50.0, -50.0, 0.0); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up the child 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetPosition(gfx::PointF(0.f, 0.f)); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetBounds(gfx::Size(100, 100)); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetContentBounds(gfx::Size(100, 100)); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetTransform(transform); 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the child layer's bounds would actually get clipped by 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // w < 0, otherwise this test is not actually testing the intended scenario. 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::QuadF test_quad(gfx::RectF(gfx::PointF(), gfx::SizeF(100.f, 100.f))); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool clipped = false; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MathUtil::MapQuad(transform, test_quad, &clipped); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(clipped); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage the child without moving it. 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetOpacity(0.5f); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The expected damage should cover the entire root surface (500x500), but we 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // don't care whether the damage rect was clamped or is larger than the 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface for this test. 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500)); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about)); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { 497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 498b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LayerImpl* surface = root->children()[0]; 499b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LayerImpl* child = surface->children()[0]; 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FilterOperations filters; 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch filters.Append(FilterOperation::CreateBlurFilter(5.f)); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int outset_top, outset_right, outset_bottom, outset_left; 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left); 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setting the filter will damage the whole surface. 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) surface->SetFilters(filters); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setting the update rect should cause the corresponding damage to the 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface, blurred based on the size of the blur filter. 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Damage position on the surface should be: position of update_rect (1, 2) 518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // relative to the child (300, 300), but expanded by the blur outsets. 519c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect expected_damage_rect = gfx::Rect(301, 302, 3, 4); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_damage_rect.Inset(-outset_left, 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_top, 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_right, 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_bottom); 527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect, child_damage_rect; 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow us to set damage on child too. 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetDrawsContent(true); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( 539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SkBlurImageFilter::Create(SkIntToScalar(2), SkIntToScalar(2))); 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FilterOperations filters; 54168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) filters.Append(FilterOperation::CreateReferenceFilter(filter)); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setting the filter will damage the whole surface. 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 54568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) child->SetFilters(filters); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 551c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), 552c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 553c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: Setting the update rect should damage the whole surface (for now) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 557c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetUpdateRect(gfx::RectF(1.f, 1.f)); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), 565c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30.f, 30.f).ToString(), child_damage_rect.ToString()); 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child2 = root->children()[1]; 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow us to set damage on child1 too. 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetDrawsContent(true); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FilterOperations filters; 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch filters.Append(FilterOperation::CreateBlurFilter(2.f)); 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int outset_top, outset_right, outset_bottom, outset_left; 580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch filters.GetOutsets(&outset_top, &outset_right, &outset_bottom, &outset_left); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setting the filter will damage the whole surface. 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetBackgroundFilters(filters); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: Setting the update rect should cause the corresponding damage to 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the surface, blurred based on the size of the child's background 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blur filter. 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f)); 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 594c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 595c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage position on the surface should be a composition of the damage on 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the root and on child2. Damage on the root should be: position of 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // update_rect (297, 297), but expanded by the blur outsets. 599c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2); 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_damage_rect.Inset(-outset_left, 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_top, 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_right, 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_bottom); 605c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: Setting the update rect should cause the corresponding damage to 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the surface, blurred based on the size of the child's background 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blur filter. Since the damage extends to the right/bottom outside 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the blurred layer, only the left/top should end up expanded. 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root->SetUpdateRect(gfx::RectF(297.f, 297.f, 30.f, 30.f)); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage position on the surface should be a composition of the damage on 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the root and on child2. Damage on the root should be: position of 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // update_rect (297, 297), but expanded on the left/top by the blur outsets. 620c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_damage_rect = gfx::Rect(297, 297, 30, 30); 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_damage_rect.Inset(-outset_left, 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_top, 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0); 626c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 3: Setting this update rect outside the blurred content_bounds of the 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blurred child1 will not cause it to be expanded. 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root->SetUpdateRect(gfx::RectF(30.f, 30.f, 2.f, 2.f)); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage on the root should be: position of update_rect (30, 30), not 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expanded. 638c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_damage_rect = gfx::Rect(30, 30, 2, 2); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 640c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 4: Setting this update rect inside the blurred content_bounds but 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // outside the original content_bounds of the blurred child1 will 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cause it to be expanded. 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root->SetUpdateRect(gfx::RectF(99.f, 99.f, 1.f, 1.f)); 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage on the root should be: position of update_rect (99, 99), expanded by 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the blurring on child1, but since it is 1 pixel outside the layer, the 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expanding should be reduced by 1. 654c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_damage_rect = gfx::Rect(99, 99, 1, 1); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_damage_rect.Inset(-outset_left + 1, 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_top + 1, 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_right, 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_bottom); 660c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 5: Setting the update rect on child2, which is above child1, will 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not get blurred by child1, so it does not need to get expanded. 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage on child2 should be: position of update_rect offset by the child's 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // position (11, 11), and not expanded by anything. 672c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_damage_rect = gfx::Rect(11, 11, 1, 1); 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 674c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 6: Setting the update rect on child1 will also blur the damage, so 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that any pixels needed for the blur are redrawn in the current 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // frame. 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage on child1 should be: position of update_rect offset by the child's 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // position (100, 100), and expanded by the damage. 687c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch expected_damage_rect = gfx::Rect(100, 100, 1, 1); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_damage_rect.Inset(-outset_left, 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_top, 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_right, 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -outset_bottom); 693c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: Adding a new layer should cause the appropriate damage. 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child2 = 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetPosition(gfx::PointF(400.f, 380.f)); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetBounds(gfx::Size(6, 8)); 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetContentBounds(gfx::Size(6, 8)); 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetDrawsContent(true); 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child2.Pass()); 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check - all 3 layers should be on the same render surface; render 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surfaces are tested elsewhere. 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(3u, root->render_surface()->layer_list().size()); 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 718c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 719c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 720c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: If the layer is removed, its entire old layer becomes exposed, not 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // just the last update rect. 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Advance one frame without damage so that we know the damage rect is not 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leftover from the previous case. 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then, test removing child1. 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->RemoveChild(child1); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1 = NULL; 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 741c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), 742c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If child2 is added to the layer tree, but it doesn't have any explicit 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // damage of its own, it should still indeed damage the target surface. 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child2 = 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetPosition(gfx::PointF(400.f, 380.f)); 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetBounds(gfx::Size(6, 8)); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetContentBounds(gfx::Size(6, 8)); 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetDrawsContent(true); 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->ResetAllChangeTrackingForSubtree(); 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check the initial conditions of the test, if these asserts 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // trigger, it means the test no longer actually covers the intended 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scenario. 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(child2->LayerPropertyChanged()); 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child2->update_rect().IsEmpty()); 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child2.Pass()); 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check - all 3 layers should be on the same render surface; render 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surfaces are tested elsewhere. 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(3u, root->render_surface()->layer_list().size()); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 773c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 774c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 775c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this test we don't want the above tree manipulation to be considered 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // part of the same frame. 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> child2 = 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetPosition(gfx::PointF(400.f, 380.f)); 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetBounds(gfx::Size(6, 8)); 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetContentBounds(gfx::Size(6, 8)); 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetDrawsContent(true); 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->AddChild(child2.Pass()); 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child2 = root->children()[1]; 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damaging two layers simultaneously should cause combined damage. 798c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2); 799c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4); 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f)); 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 804c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 805c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 806c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(), 807c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child2 = root->children()[1]; 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1 = root->children()[0]->children()[0]; 815c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 816c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: Damage to a descendant surface should propagate properly to 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ancestor surface. 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetOpacity(0.5f); 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 827c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); 828c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString()); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: Same as previous case, but with additional damage elsewhere that 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should be properly unioned. 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - child1 surface damage in root surface space: 833c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // gfx::Rect(300, 300, 6, 8); 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - child2 damage in root surface space: 835c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // gfx::Rect(11, 11, 18, 18); 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetOpacity(0.7f); 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child2->SetOpacity(0.7f); 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 844c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); 845c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(), 846c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If descendant layer changes and affects the content bounds of the render 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface, then the entire descendant surface should be damaged, and it 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should damage its ancestor surface with the old and new surface regions. 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is a tricky case, since only the first grand_child changes, but the 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // entire surface should be marked dirty. 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1 = root->children()[0]->children()[0]; 860c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 861c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetPosition(gfx::PointF(195.f, 205.f)); 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The new surface bounds should be damaged entirely, even though only one of 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the layers changed. 873c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(), 874c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage to the root surface should be the union of child1's *entire* render 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface (in target space), and its old exposed area (also in target 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // space). 879c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(), 880c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // An ancestor/owning layer changes that affects the position/transform of 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the render surface. Note that in this case, the layer_property_changed flag 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // already propagates to the subtree (tested in LayerImpltest), which damages 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the entire child1 surface, but the damage tracker still needs the correct 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // logic to compute the exposed region on the root surface. 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(shawnsingh): the expectations of this test case should change when we 891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // add support for a unique scissor_rect per RenderSurface. In that case, the 892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // child1 surface should be completely unchanged, since we are only 893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // transforming it, while the root surface would be damaged appropriately. 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 897c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 898c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetPosition(gfx::PointF(50.f, 50.f)); 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The new surface bounds should be damaged entirely. 909c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), 910c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The entire child1 surface and the old exposed child1 surface should damage 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the root surface. 914c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - old child1 surface in target space: gfx::Rect(290, 290, 16, 18) 915c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - new child1 surface in target space: gfx::Rect(240, 240, 16, 18) 916c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(), 917c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 923c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 924c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: If a descendant surface disappears, its entire old area becomes 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // exposed. 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetOpacity(1.f); 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetForceRenderSurface(false); 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that there is only one surface now. 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(child1->render_surface()); 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(4u, root->render_surface()->layer_list().size()); 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 939c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), 940c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: If a descendant surface appears, its entire old area becomes 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // exposed. 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Cycle one frame of no change, just to sanity check that the next rect is 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not because of the old damage state. 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then change the tree so that the render surface is added back. 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetOpacity(0.5f); 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetForceRenderSurface(true); 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that there is a new surface now. 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child1->render_surface()); 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(3u, root->render_surface()->layer_list().size()); 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(2u, child1->render_surface()->layer_list().size()); 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 968c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), 969c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 970c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), 971c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 977c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 978c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: If nothing changes, the damage rect should be empty. 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(child_damage_rect.IsEmpty()); 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: If nothing changes twice in a row, the damage rect should still be 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // empty. 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(child_damage_rect.IsEmpty()); 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 1007c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect; 1008c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect; 10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In our specific tree, the update rect of child1 should not cause any 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // damage to any surface because it does not actually draw content. 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); 10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(child_damage_rect.IsEmpty()); 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForReplica) { 10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1 = child1->children()[0]; 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child2 = child1->children()[1]; 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage on a surface that has a reflection should cause the target surface 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to receive the surface's damage and the surface's reflected damage. 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For this test case, we modify grand_child2, and add grand_child3 to extend 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the bounds of child1's surface. This way, we can test reflection changes 10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // without changing content_bounds of the surface. 10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child2->SetPosition(gfx::PointF(180.f, 180.f)); 10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child3 = 10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 6); 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child3->SetPosition(gfx::PointF(240.f, 240.f)); 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child3->SetBounds(gfx::Size(10, 10)); 10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child3->SetContentBounds(gfx::Size(10, 10)); 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child3->SetDrawsContent(true); 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->AddChild(grand_child3.Pass()); 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->SetOpacity(0.5f); 10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: adding a reflection about the left edge of grand_child1. 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child1_replica = 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 7); 10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetPosition(gfx::PointF()); 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform reflection; 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reflection.Scale3d(-1.0, 1.0, 1.0); 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetTransform(reflection); 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetReplicaLayer(grand_child1_replica.Pass()); 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect grand_child_damage_rect = 1063c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch grand_child1->render_surface()->damage_tracker()->current_damage_rect(); 1064c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect = 1065c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child1->render_surface()->damage_tracker()->current_damage_rect(); 1066c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 1067c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The grand_child surface damage should not include its own replica. The 10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // child surface damage should include the normal and replica surfaces. 1071c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString()); 1072c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(194, 200, 12, 8).ToString(), 1073c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 1074c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(294, 300, 12, 8).ToString(), root_damage_rect.ToString()); 10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: moving the descendant surface should cause both the original and 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // reflected areas to be damaged on the target. 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect old_content_rect = child1->render_surface()->content_rect(); 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetPosition(gfx::PointF(195.f, 205.f)); 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(old_content_rect.width(), 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->content_rect().width()); 10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(old_content_rect.height(), 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->content_rect().height()); 10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child_damage_rect = 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->render_surface()-> 10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_tracker()->current_damage_rect(); 10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The child surface damage should include normal and replica surfaces for 10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // both old and new locations. 1097c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - old location in target space: gfx::Rect(194, 200, 12, 8) 1098c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // - new location in target space: gfx::Rect(189, 205, 12, 8) 1099c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString()); 1100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(189, 200, 17, 13).ToString(), 1101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 1102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(289, 300, 17, 13).ToString(), 1103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 3: removing the reflection should cause the entire region including 11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // reflection to damage the target surface. 11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetReplicaLayer(scoped_ptr<LayerImpl>()); 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(old_content_rect.width(), 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->content_rect().width()); 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(old_content_rect.height(), 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->content_rect().height()); 11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(grand_child1->render_surface()); 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(189, 205, 12, 8).ToString(), 1122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child_damage_rect.ToString()); 1123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(289, 305, 12, 8).ToString(), root_damage_rect.ToString()); 11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForMask) { 11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In the current implementation of the damage tracker, changes to mask 11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layers should damage the entire corresponding surface. 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up the mask layer. 11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> mask_layer = 11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mask_layer->SetPosition(child->position()); 11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mask_layer->SetBounds(child->bounds()); 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mask_layer->SetContentBounds(child->bounds()); 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetMaskLayer(mask_layer.Pass()); 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* mask_layer = child->mask_layer(); 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add opacity and a grand_child so that the render surface persists even 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // after we remove the mask. 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetOpacity(0.5f); 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child = 11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 4); 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(2.f, 2.f)); 11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child->SetBounds(gfx::Size(2, 2)); 11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child->SetContentBounds(gfx::Size(2, 2)); 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child->SetDrawsContent(true); 11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->AddChild(grand_child.Pass()); 11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that a new surface was created for the child. 11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child->render_surface()); 11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: the update_rect on a mask layer should damage the entire target 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface. 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); 11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 1168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect = 1169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->render_surface()->damage_tracker()->current_damage_rect(); 1170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: a property change on the mask layer should damage the entire 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // target surface. 11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Advance one frame without damage so that we know the damage rect is not 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leftover from the previous case. 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(child_damage_rect.IsEmpty()); 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then test the property change. 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mask_layer->SetStackingOrderChanged(true); 11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 1190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); 11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 3: removing the mask also damages the entire target surface. 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Advance one frame without damage so that we know the damage rect is not 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leftover from the previous case. 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(child_damage_rect.IsEmpty()); 12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then test mask removal. 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->SetMaskLayer(scoped_ptr<LayerImpl>()); 12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child->LayerPropertyChanged()); 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that a render surface still exists. 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(child->render_surface()); 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child->render_surface()->damage_tracker()->current_damage_rect(); 1214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1 = child1->children()[0]; 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Changes to a replica's mask should not damage the original surface, 12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // because it is not masked. But it does damage the ancestor target surface. 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a reflection about the left edge of grand_child1. 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child1_replica = 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 6); 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetPosition(gfx::PointF()); 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform reflection; 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reflection.Scale3d(-1.0, 1.0, 1.0); 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetTransform(reflection); 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetReplicaLayer(grand_child1_replica.Pass()); 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1_replica = grand_child1->replica_layer(); 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up the mask layer on the replica layer 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> replica_mask_layer = 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 7); 12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetPosition(gfx::PointF()); 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetBounds(grand_child1->bounds()); 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetContentBounds(grand_child1->bounds()); 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass()); 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer(); 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the appropriate render surfaces were created 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(grand_child1->render_surface()); 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 1: a property change on the mask should damage only the reflected 12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // region on the target surface. 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetStackingOrderChanged(true); 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect grand_child_damage_rect = 1262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch grand_child1->render_surface()->damage_tracker()->current_damage_rect(); 1263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect = 1264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child1->render_surface()->damage_tracker()->current_damage_rect(); 12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(grand_child_damage_rect.IsEmpty()); 1267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString()); 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CASE 2: removing the replica mask damages only the reflected region on the 12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // target surface. 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetMaskLayer(scoped_ptr<LayerImpl>()); 12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child_damage_rect = 12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->render_surface()->damage_tracker()-> 12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_damage_rect(); 12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_damage_rect = 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child1->render_surface()->damage_tracker()->current_damage_rect(); 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(grand_child_damage_rect.IsEmpty()); 1283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString()); 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 128646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) { 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child1 = root->children()[0]; 12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1 = child1->children()[0]; 12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify that the correct replica_origin_transform is used for the 12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // replica_mask. 12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 129546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This is not actually the transform origin point being tested, but by 129646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // convention its 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected to be the same as the replica's anchor point. 129846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) grand_child1->SetTransformOrigin( 129946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f)); 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child1_replica = 13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 6); 13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetPosition(gfx::PointF()); 13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is the anchor being tested. 130746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) grand_child1_replica->SetTransformOrigin( 130846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::Point3F(grand_child1->bounds().width(), 0.f, 0.f)); 13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform reflection; 13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reflection.Scale3d(-1.0, 1.0, 1.0); 13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetTransform(reflection); 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1->SetReplicaLayer(grand_child1_replica.Pass()); 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* grand_child1_replica = grand_child1->replica_layer(); 13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up the mask layer on the replica layer 13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> replica_mask_layer = 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 7); 13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetPosition(gfx::PointF()); 132146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Note: this is not the transform origin being tested. 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetBounds(grand_child1->bounds()); 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetContentBounds(grand_child1->bounds()); 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass()); 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer(); 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check that the appropriate render surfaces were created 13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(grand_child1->render_surface()); 13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A property change on the replica_mask should damage the reflected region on 13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the target surface. 13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->SetStackingOrderChanged(true); 13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect child_damage_rect = 1341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child1->render_surface()->damage_tracker()->current_damage_rect(); 1342c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(206, 200, 6, 8).ToString(), child_damage_rect.ToString()); 13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: This test ensures that when the tracker is given damage, that 1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it is included with any other partial damage. 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(10, 11, 12, 13)); 1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->render_surface()->damage_tracker()->AddDamageNextUpdate( 1355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect(15, 16, 32, 33)); 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 1357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 1359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33), 1360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(), 1361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: An additional sanity check that adding damage works even when 1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nothing on the layer tree changed. 13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->render_surface()->damage_tracker()->AddDamageNextUpdate( 1368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect(30, 31, 14, 15)); 13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 1372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { 13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Though it should never happen, its a good idea to verify that the damage 13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tracker does not crash when it receives an empty layer_list. 13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1); 13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->CreateRenderSurface(); 13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(root == root->render_target()); 13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderSurfaceImpl* target_surface = root->render_surface(); 1384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LayerImplList empty_list; 13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->damage_tracker()->UpdateDamageTrackingState( 1387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch empty_list, 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_surface->OwningLayerId(), 13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false, 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect(), 13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 139268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FilterOperations()); 13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect = 1395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch target_surface->damage_tracker()->current_damage_rect(); 13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(damage_rect.IsEmpty()); 13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If damage is not cleared, it should accumulate. 14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* child = root->children()[0]; 14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearDamageForAllSurfaces(root.get()); 1406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f)); 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sanity check damage after the first frame; this isnt the actual test yet. 1410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 1411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 1412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString()); 14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // New damage, without having cleared the previous damage, should be unioned 14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the previous one. 14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); 14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 1420c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(), 1421c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root_damage_rect.ToString()); 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we notify the damage tracker that we drew the damaged area, then damage 14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should be emptied. 14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->DidDrawDamagedArea(); 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage should remain empty even after one frame, since there's yet no new 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // damage. 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmulateDrawingOneFrame(root.get()); 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_damage_rect = 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root->render_surface()->damage_tracker()->current_damage_rect(); 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(root_damage_rect.IsEmpty()); 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DamageTrackerTest, HugeDamageRect) { 1439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This number is so large that we start losting floating point accuracy. 1440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int kBigNumber = 900000000; 1441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Walk over a range to find floating point inaccuracy boundaries that move 1442c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // toward the wrong direction. 1443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int kRange = 5000; 1444c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1445c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (int i = 0; i < kRange; ++i) { 1446c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface(); 1447c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LayerImpl* child = root->children()[0]; 1448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1449c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Transform transform; 1450c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch transform.Translate(-kBigNumber, -kBigNumber); 1451c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1452c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The child layer covers (0, 0, i, i) of the viewport, 1453c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // but has a huge negative position. 1454c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetPosition(gfx::PointF()); 1455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); 1456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); 1457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch child->SetTransform(transform); 1458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EmulateDrawingOneFrame(root.get()); 1459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The expected damage should cover the visible part of the child layer, 1461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // which is (0, 0, i, i) in the viewport. 1462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect root_damage_rect = 1463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch root->render_surface()->damage_tracker()->current_damage_rect(); 1464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_we_care_about = gfx::Rect(i, i); 1465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right()); 1466c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom()); 1467c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 1468c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 1469c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 1472