diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-07 18:12:18 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-07 18:12:18 +0000 |
commit | b4ead7bdfe512cee69862f8b79200b88d41d7317 (patch) | |
tree | 0d30671c758e273fcd79c9c52d68cf567411f389 /cc/trees/damage_tracker_unittest.cc | |
parent | 2056c3b91cd582ef0d4281f19d1e35215a4732ab (diff) | |
download | chromium_src-b4ead7bdfe512cee69862f8b79200b88d41d7317.zip chromium_src-b4ead7bdfe512cee69862f8b79200b88d41d7317.tar.gz chromium_src-b4ead7bdfe512cee69862f8b79200b88d41d7317.tar.bz2 |
cc: Change damage tracking from floats to integers.
Damage rects can become huge when layers clip the viewport, and in some
cases become so large that we reach inaccurate floating point
representation of the whole-number portion, which we fail to handle
correctly when doing gfx::ToEnclosingRect.
Int/float conversions are also slow, and the GL_SCISSOR wants integers
eventually anyway, so keeping track of partial-pixel damage is not
buying us much here. So convert the DamageTracker to use integer rects.
Also change cc::RenderSurfaceImpl to export a damage_rect that is
contained inside the output_rect for the RenderPass, and add DCHECKs
to cc::RenderPass to ensure we don't send pointlessly large damage_rects
to the cc::Renderer.
Tests:
DamageTrackerTest.HugeDamageRect
R=enne@chromium.org, piman@chromium.org
BUG=355514
Review URL: https://codereview.chromium.org/226183007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262160 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/trees/damage_tracker_unittest.cc')
-rw-r--r-- | cc/trees/damage_tracker_unittest.cc | 337 |
1 files changed, 189 insertions, 148 deletions
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index 2dd52ca..9476955 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc @@ -16,7 +16,8 @@ #include "cc/trees/single_thread_proxy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" -#include "ui/gfx/quad_f.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace cc { namespace { @@ -196,10 +197,10 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { EXPECT_EQ(1, root->render_surface()->layer_list()[0]->id()); EXPECT_EQ(2, root->render_surface()->layer_list()[1]->id()); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 500.f, 500.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { @@ -210,10 +211,10 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { LayerImpl* child1 = root->children()[0]; LayerImpl* child2 = root->children()[1]; - gfx::RectF child_damage_rect = - child1->render_surface()->damage_tracker()->current_damage_rect(); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect child_damage_rect = + child1->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); ASSERT_TRUE(child1->render_surface()); EXPECT_FALSE(child2->render_surface()); @@ -222,8 +223,9 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { // The render surface for child1 only has a content_rect that encloses // grand_child1 and grand_child2, because child1 does not draw content. - EXPECT_FLOAT_RECT_EQ(gfx::RectF(190.f, 190.f, 16.f, 18.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 500.f, 500.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), + child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { @@ -238,9 +240,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // Damage position on the surface should be: position of update_rect (10, 11) // relative to the child (100, 100). - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(110.f, 111.f, 12.f, 13.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), + root_damage_rect.ToString()); // CASE 2: The same update rect twice in a row still produces the same // damage. @@ -249,7 +252,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(110.f, 111.f, 12.f, 13.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), + root_damage_rect.ToString()); // CASE 3: Setting a different update rect should cause damage on the new // update region, but no additional exposed old region. @@ -261,7 +265,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // relative to the child (100, 100). root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(120.f, 125.f, 1.f, 2.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { @@ -281,10 +285,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { ASSERT_EQ(2u, root->render_surface()->layer_list().size()); // Damage should be the entire child layer in target_surface space. - gfx::RectF expected_rect = gfx::RectF(100.f, 100.f, 30.f, 30.f); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); + gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); // CASE 2: If a layer moves due to property change, it damages both the new // location and the old (exposed) location. The old location is the @@ -304,7 +308,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EmulateDrawingOneFrame(root.get()); // Expect damage to be the combination of the previous one and the new one. - expected_rect.Union(gfx::RectF(200, 230, 30, 30)); + expected_rect.Union(gfx::Rect(200, 230, 30, 30)); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); @@ -327,9 +331,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // Sanity check that the layer actually moved to (85, 85), damaging its old // location and new location. - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(85.f, 85.f, 45.f, 45.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString()); // With the anchor on the layer's center, now we can test the rotation more // intuitively, since it applies about the layer's anchor. @@ -343,11 +347,11 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // region. float expected_width = 30.f * sqrt(2.f); float expected_position = 100.f - 0.5f * expected_width; - gfx::RectF expected_rect( - expected_position, expected_position, expected_width, expected_width); + gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF( + expected_position, expected_position, expected_width, expected_width)); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); + EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { @@ -394,10 +398,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { // The expected damage should cover the entire root surface (500x500), but we // don't care whether the damage rect was clamped or is larger than the // surface for this test. - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - gfx::RectF damage_we_care_about = - gfx::RectF(gfx::PointF(), gfx::SizeF(500.f, 500.f)); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500)); EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about)); } @@ -424,22 +427,21 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // Damage position on the surface should be: position of update_rect (1, 2) // relative to the child (300, 300), but expanded by the blur outsets. - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - gfx::RectF expected_damage_rect = - gfx::RectF(301.f, 302.f, 3.f, 4.f); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect expected_damage_rect = gfx::Rect(301, 302, 3, 4); expected_damage_rect.Inset(-outset_left, -outset_top, -outset_right, -outset_bottom); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface(); LayerImpl* child = root->children()[0]; - gfx::RectF root_damage_rect, child_damage_rect; + gfx::Rect root_damage_rect, child_damage_rect; // Allow us to set damage on child too. child->SetDrawsContent(true); @@ -458,20 +460,22 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { root->render_surface()->damage_tracker()->current_damage_rect(); child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(100.f, 100.f, 30.f, 30.f), root_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 30.f, 30.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), + root_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); // CASE 1: Setting the update rect should damage the whole surface (for now) ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child->SetUpdateRect(gfx::RectF(1.f, 1.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(100.f, 100.f, 30.f, 30.f), root_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 30.f, 30.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), + root_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30.f, 30.f).ToString(), child_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { @@ -499,19 +503,18 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f)); EmulateDrawingOneFrame(root.get()); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); // Damage position on the surface should be a composition of the damage on // the root and on child2. Damage on the root should be: position of // update_rect (297, 297), but expanded by the blur outsets. - gfx::RectF expected_damage_rect = - gfx::RectF(297.f, 297.f, 2.f, 2.f); + gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2); expected_damage_rect.Inset(-outset_left, -outset_top, -outset_right, -outset_bottom); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 2: Setting the update rect should cause the corresponding damage to // the surface, blurred based on the size of the child's background @@ -526,14 +529,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // Damage position on the surface should be a composition of the damage on // the root and on child2. Damage on the root should be: position of // update_rect (297, 297), but expanded on the left/top by the blur outsets. - expected_damage_rect = - gfx::RectF(297.f, 297.f, 30.f, 30.f); + expected_damage_rect = gfx::Rect(297, 297, 30, 30); expected_damage_rect.Inset(-outset_left, -outset_top, 0, 0); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 3: Setting this update rect outside the blurred content_bounds of the // blurred child1 will not cause it to be expanded. @@ -545,10 +547,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->render_surface()->damage_tracker()->current_damage_rect(); // Damage on the root should be: position of update_rect (30, 30), not // expanded. - expected_damage_rect = - gfx::RectF(30.f, 30.f, 2.f, 2.f); + expected_damage_rect = gfx::Rect(30, 30, 2, 2); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 4: Setting this update rect inside the blurred content_bounds but // outside the original content_bounds of the blurred child1 will @@ -562,14 +563,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // Damage on the root should be: position of update_rect (99, 99), expanded by // the blurring on child1, but since it is 1 pixel outside the layer, the // expanding should be reduced by 1. - expected_damage_rect = - gfx::RectF(99.f, 99.f, 1.f, 1.f); + expected_damage_rect = gfx::Rect(99, 99, 1, 1); expected_damage_rect.Inset(-outset_left + 1, -outset_top + 1, -outset_right, -outset_bottom); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 5: Setting the update rect on child2, which is above child1, will // not get blurred by child1, so it does not need to get expanded. @@ -581,10 +581,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->render_surface()->damage_tracker()->current_damage_rect(); // Damage on child2 should be: position of update_rect offset by the child's // position (11, 11), and not expanded by anything. - expected_damage_rect = - gfx::RectF(11.f, 11.f, 1.f, 1.f); + expected_damage_rect = gfx::Rect(11, 11, 1, 1); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 6: Setting the update rect on child1 will also blur the damage, so // that any pixels needed for the blur are redrawn in the current @@ -597,14 +596,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->render_surface()->damage_tracker()->current_damage_rect(); // Damage on child1 should be: position of update_rect offset by the child's // position (100, 100), and expanded by the damage. - expected_damage_rect = - gfx::RectF(100.f, 100.f, 1.f, 1.f); + expected_damage_rect = gfx::Rect(100, 100, 1, 1); expected_damage_rect.Inset(-outset_left, -outset_top, -outset_right, -outset_bottom); - EXPECT_FLOAT_RECT_EQ(expected_damage_rect, root_damage_rect); + EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { @@ -630,9 +628,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { // surfaces are tested elsewhere. ASSERT_EQ(3u, root->render_surface()->layer_list().size()); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(400.f, 380.f, 6.f, 8.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); // CASE 2: If the layer is removed, its entire old layer becomes exposed, not // just the last update rect. @@ -653,7 +651,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(100.f, 100.f, 30.f, 30.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { @@ -685,9 +684,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { // surfaces are tested elsewhere. ASSERT_EQ(3u, root->render_surface()->layer_list().size()); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(400.f, 380.f, 6.f, 8.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { @@ -711,16 +710,16 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { EmulateDrawingOneFrame(root.get()); // Damaging two layers simultaneously should cause combined damage. - // - child1 update rect in surface space: gfx::RectF(100.f, 100.f, 1.f, 2.f); - // - child2 update rect in surface space: gfx::RectF(400.f, 380.f, 3.f, 4.f); + // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2); + // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4); ClearDamageForAllSurfaces(root.get()); child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f)); EmulateDrawingOneFrame(root.get()); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ( - gfx::RectF(100.f, 100.f, 303.f, 284.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { @@ -728,8 +727,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { LayerImpl* child1 = root->children()[0]; LayerImpl* child2 = root->children()[1]; LayerImpl* grand_child1 = root->children()[0]->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; // CASE 1: Damage to a descendant surface should propagate properly to // ancestor surface. @@ -740,15 +739,15 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { child1->render_surface()->damage_tracker()->current_damage_rect(); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(200.f, 200.f, 6.f, 8.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(300.f, 300.f, 6.f, 8.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString()); // CASE 2: Same as previous case, but with additional damage elsewhere that // should be properly unioned. // - child1 surface damage in root surface space: - // gfx::RectF(300.f, 300.f, 6.f, 8.f); + // gfx::Rect(300, 300, 6, 8); // - child2 damage in root surface space: - // gfx::RectF(11.f, 11.f, 18.f, 18.f); + // gfx::Rect(11, 11, 18, 18); ClearDamageForAllSurfaces(root.get()); grand_child1->SetOpacity(0.7f); child2->SetOpacity(0.7f); @@ -757,8 +756,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { child1->render_surface()->damage_tracker()->current_damage_rect(); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(200.f, 200.f, 6.f, 8.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(11.f, 11.f, 295.f, 297.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { @@ -772,8 +772,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->children()[0]; LayerImpl* grand_child1 = root->children()[0]->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root.get()); grand_child1->SetPosition(gfx::PointF(195.f, 205.f)); @@ -785,12 +785,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { // The new surface bounds should be damaged entirely, even though only one of // the layers changed. - EXPECT_FLOAT_RECT_EQ(gfx::RectF(190.f, 190.f, 11.f, 23.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(), + child_damage_rect.ToString()); // Damage to the root surface should be the union of child1's *entire* render // surface (in target space), and its old exposed area (also in target // space). - EXPECT_FLOAT_RECT_EQ(gfx::RectF(290.f, 290.f, 16.f, 23.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { @@ -807,8 +809,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root.get()); child1->SetPosition(gfx::PointF(50.f, 50.f)); @@ -819,20 +821,22 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { root->render_surface()->damage_tracker()->current_damage_rect(); // The new surface bounds should be damaged entirely. - EXPECT_FLOAT_RECT_EQ(gfx::RectF(190.f, 190.f, 16.f, 18.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), + child_damage_rect.ToString()); // The entire child1 surface and the old exposed child1 surface should damage // the root surface. - // - old child1 surface in target space: gfx::RectF(290.f, 290.f, 16.f, 18.f) - // - new child1 surface in target space: gfx::RectF(240.f, 240.f, 16.f, 18.f) - EXPECT_FLOAT_RECT_EQ(gfx::RectF(240.f, 240.f, 66.f, 68.f), root_damage_rect); + // - old child1 surface in target space: gfx::Rect(290, 290, 16, 18) + // - new child1 surface in target space: gfx::Rect(240, 240, 16, 18) + EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; // CASE 1: If a descendant surface disappears, its entire old area becomes // exposed. @@ -847,7 +851,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(290.f, 290.f, 16.f, 18.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), + root_damage_rect.ToString()); // CASE 2: If a descendant surface appears, its entire old area becomes // exposed. @@ -875,15 +880,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { child1->render_surface()->damage_tracker()->current_damage_rect(); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(190.f, 190.f, 16.f, 18.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(290.f, 290.f, 16.f, 18.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), + child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), + root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; // CASE 1: If nothing changes, the damage rect should be empty. // @@ -912,8 +919,8 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->children()[0]; - gfx::RectF child_damage_rect; - gfx::RectF root_damage_rect; + gfx::Rect child_damage_rect; + gfx::Rect root_damage_rect; // In our specific tree, the update rect of child1 should not cause any // damage to any surface because it does not actually draw content. @@ -969,19 +976,19 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { } EmulateDrawingOneFrame(root.get()); - gfx::RectF grand_child_damage_rect = - grand_child1->render_surface()->damage_tracker()-> - current_damage_rect(); - gfx::RectF child_damage_rect = - child1->render_surface()->damage_tracker()->current_damage_rect(); - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect grand_child_damage_rect = + grand_child1->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect child_damage_rect = + child1->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); // The grand_child surface damage should not include its own replica. The // child surface damage should include the normal and replica surfaces. - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 6.f, 8.f), grand_child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(194.f, 200.f, 12.f, 8.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(294.f, 300.f, 12.f, 8.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(194, 200, 12, 8).ToString(), + child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(294, 300, 12, 8).ToString(), root_damage_rect.ToString()); // CASE 2: moving the descendant surface should cause both the original and // reflected areas to be damaged on the target. @@ -1004,11 +1011,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // The child surface damage should include normal and replica surfaces for // both old and new locations. - // - old location in target space: gfx::RectF(194.f, 200.f, 12.f, 8.f) - // - new location in target space: gfx::RectF(189.f, 205.f, 12.f, 8.f) - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 6.f, 8.f), grand_child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(189.f, 200.f, 17.f, 13.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(289.f, 300.f, 17.f, 13.f), root_damage_rect); + // - old location in target space: gfx::Rect(194, 200, 12, 8) + // - new location in target space: gfx::Rect(189, 205, 12, 8) + EXPECT_EQ(gfx::Rect(6, 8).ToString(), grand_child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(189, 200, 17, 13).ToString(), + child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(289, 300, 17, 13).ToString(), + root_damage_rect.ToString()); // CASE 3: removing the reflection should cause the entire region including // reflection to damage the target surface. @@ -1026,8 +1035,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(189.f, 205.f, 12.f, 8.f), child_damage_rect); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(289.f, 305.f, 12.f, 8.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(189, 205, 12, 8).ToString(), + child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(289, 305, 12, 8).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForMask) { @@ -1074,9 +1084,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { ClearDamageForAllSurfaces(root.get()); mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); EmulateDrawingOneFrame(root.get()); - gfx::RectF child_damage_rect = - child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 30.f, 30.f), child_damage_rect); + gfx::Rect child_damage_rect = + child->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); // CASE 2: a property change on the mask layer should damage the entire // target surface. @@ -1096,7 +1106,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { EmulateDrawingOneFrame(root.get()); child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 30.f, 30.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); // CASE 3: removing the mask also damages the entire target surface. // @@ -1120,7 +1130,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 30.f, 30.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { @@ -1169,14 +1179,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { replica_mask_layer->SetStackingOrderChanged(true); EmulateDrawingOneFrame(root.get()); - gfx::RectF grand_child_damage_rect = - grand_child1->render_surface()->damage_tracker()-> - current_damage_rect(); - gfx::RectF child_damage_rect = - child1->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect grand_child_damage_rect = + grand_child1->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect child_damage_rect = + child1->render_surface()->damage_tracker()->current_damage_rect(); EXPECT_TRUE(grand_child_damage_rect.IsEmpty()); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(194.f, 200.f, 6.f, 8.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString()); // CASE 2: removing the replica mask damages only the reflected region on the // target surface. @@ -1192,7 +1201,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { child1->render_surface()->damage_tracker()->current_damage_rect(); EXPECT_TRUE(grand_child_damage_rect.IsEmpty()); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(194.f, 200.f, 6.f, 8.f), child_damage_rect); + EXPECT_EQ(gfx::Rect(194, 200, 6, 8).ToString(), child_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithAnchor) { @@ -1247,9 +1256,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithAnchor) { EmulateDrawingOneFrame(root.get()); - gfx::RectF child_damage_rect = - child1->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(206.f, 200.f, 6.f, 8.f), child_damage_rect); + gfx::Rect child_damage_rect = + child1->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(206, 200, 6, 8).ToString(), child_damage_rect.ToString()); } TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { @@ -1262,25 +1271,24 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { ClearDamageForAllSurfaces(root.get()); child->SetUpdateRect(gfx::RectF(10, 11, 12, 13)); root->render_surface()->damage_tracker()->AddDamageNextUpdate( - gfx::RectF(15, 16, 32, 33)); + gfx::Rect(15, 16, 32, 33)); EmulateDrawingOneFrame(root.get()); - gfx::RectF root_damage_rect = + gfx::Rect root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ( - gfx::UnionRects(gfx::RectF(15, 16, 32, 33), - gfx::RectF(100+10, 100+11, 12, 13)), - root_damage_rect); + EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33), + gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(), + root_damage_rect.ToString()); // Case 2: An additional sanity check that adding damage works even when // nothing on the layer tree changed. // ClearDamageForAllSurfaces(root.get()); root->render_surface()->damage_tracker()->AddDamageNextUpdate( - gfx::RectF(30, 31, 14, 15)); + gfx::Rect(30, 31, 14, 15)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(30, 31, 14, 15), root_damage_rect); + EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); } TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { @@ -1302,8 +1310,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { NULL, FilterOperations()); - gfx::RectF damage_rect = - target_surface->damage_tracker()->current_damage_rect(); + gfx::Rect damage_rect = + target_surface->damage_tracker()->current_damage_rect(); EXPECT_TRUE(damage_rect.IsEmpty()); } @@ -1314,13 +1322,13 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { LayerImpl* child = root->children()[0]; ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(10.f, 11.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f)); EmulateDrawingOneFrame(root.get()); // Sanity check damage after the first frame; this isnt the actual test yet. - gfx::RectF root_damage_rect = - root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(110.f, 111.f, 1.f, 2.f), root_damage_rect); + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString()); // New damage, without having cleared the previous damage, should be unioned // to the previous one. @@ -1328,7 +1336,8 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); - EXPECT_FLOAT_RECT_EQ(gfx::RectF(110.f, 111.f, 11.f, 16.f), root_damage_rect); + EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(), + root_damage_rect.ToString()); // If we notify the damage tracker that we drew the damaged area, then damage // should be emptied. @@ -1345,5 +1354,37 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { EXPECT_TRUE(root_damage_rect.IsEmpty()); } +TEST_F(DamageTrackerTest, HugeDamageRect) { + // This number is so large that we start losting floating point accuracy. + const int kBigNumber = 900000000; + // Walk over a range to find floating point inaccuracy boundaries that move + // toward the wrong direction. + const int kRange = 5000; + + for (int i = 0; i < kRange; ++i) { + scoped_ptr<LayerImpl> root = CreateTestTreeWithOneSurface(); + LayerImpl* child = root->children()[0]; + + gfx::Transform transform; + transform.Translate(-kBigNumber, -kBigNumber); + + // The child layer covers (0, 0, i, i) of the viewport, + // but has a huge negative position. + child->SetPosition(gfx::PointF()); + child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); + child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); + child->SetTransform(transform); + EmulateDrawingOneFrame(root.get()); + + // The expected damage should cover the visible part of the child layer, + // which is (0, 0, i, i) in the viewport. + gfx::Rect root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + gfx::Rect damage_we_care_about = gfx::Rect(i, i); + EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right()); + EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom()); + } +} + } // namespace } // namespace cc |