summaryrefslogtreecommitdiffstats
path: root/chromium/cc/trees
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-12 14:07:37 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-17 10:29:26 +0000
commitec02ee4181c49b61fce1c8fb99292dbb8139cc90 (patch)
tree25cde714b2b71eb639d1cd53f5a22e9ba76e14ef /chromium/cc/trees
parentbb09965444b5bb20b096a291445170876225268d (diff)
BASELINE: Update Chromium to 59.0.3071.134
Change-Id: Id02ef6fb2204c5fd21668a1c3e6911c83b17585a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/cc/trees')
-rw-r--r--chromium/cc/trees/blocking_task_runner.h2
-rw-r--r--chromium/cc/trees/clip_expander.h2
-rw-r--r--chromium/cc/trees/clip_node.cc61
-rw-r--r--chromium/cc/trees/clip_node.h50
-rw-r--r--chromium/cc/trees/damage_tracker.cc6
-rw-r--r--chromium/cc/trees/damage_tracker.h2
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc73
-rw-r--r--chromium/cc/trees/debug_rect_history.cc238
-rw-r--r--chromium/cc/trees/debug_rect_history.h99
-rw-r--r--chromium/cc/trees/draw_property_utils.cc1591
-rw-r--r--chromium/cc/trees/draw_property_utils.h62
-rw-r--r--chromium/cc/trees/effect_node.cc4
-rw-r--r--chromium/cc/trees/effect_node.h12
-rw-r--r--chromium/cc/trees/element_id.h2
-rw-r--r--chromium/cc/trees/frame_rate_counter.cc145
-rw-r--r--chromium/cc/trees/frame_rate_counter.h60
-rw-r--r--chromium/cc/trees/layer_tree_host.cc193
-rw-r--r--chromium/cc/trees/layer_tree_host.h46
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h7
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc80
-rw-r--r--chromium/cc/trees/layer_tree_host_common.h10
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc5
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc602
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc456
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h67
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc716
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc14
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc23
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc845
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc42
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc64
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_damage.cc10
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc65
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc93
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc271
-rw-r--r--chromium/cc/trees/layer_tree_impl.h37
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc45
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h2
-rw-r--r--chromium/cc/trees/layer_tree_settings.cc62
-rw-r--r--chromium/cc/trees/layer_tree_settings.h24
-rw-r--r--chromium/cc/trees/occlusion.h2
-rw-r--r--chromium/cc/trees/occlusion_tracker.cc66
-rw-r--r--chromium/cc/trees/occlusion_tracker.h44
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc63
-rw-r--r--chromium/cc/trees/property_animation_state.h2
-rw-r--r--chromium/cc/trees/property_tree.cc282
-rw-r--r--chromium/cc/trees/property_tree.h137
-rw-r--r--chromium/cc/trees/property_tree_builder.cc366
-rw-r--r--chromium/cc/trees/property_tree_builder.h27
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc41
-rw-r--r--chromium/cc/trees/proxy.h2
-rw-r--r--chromium/cc/trees/proxy_common.h3
-rw-r--r--chromium/cc/trees/proxy_impl.cc76
-rw-r--r--chromium/cc/trees/proxy_impl.h2
-rw-r--r--chromium/cc/trees/proxy_main.cc137
-rw-r--r--chromium/cc/trees/proxy_main.h2
-rw-r--r--chromium/cc/trees/scroll_node.h4
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc46
-rw-r--r--chromium/cc/trees/single_thread_proxy.h1
-rw-r--r--chromium/cc/trees/swap_promise_manager.h2
-rw-r--r--chromium/cc/trees/swap_promise_monitor.h2
-rw-r--r--chromium/cc/trees/target_property.h2
-rw-r--r--chromium/cc/trees/task_runner_provider.h2
-rw-r--r--chromium/cc/trees/transform_node.cc7
-rw-r--r--chromium/cc/trees/transform_node.h6
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc4
-rw-r--r--chromium/cc/trees/tree_synchronizer.h2
70 files changed, 4378 insertions, 3155 deletions
diff --git a/chromium/cc/trees/blocking_task_runner.h b/chromium/cc/trees/blocking_task_runner.h
index 515cb258945..d34e2f20cd4 100644
--- a/chromium/cc/trees/blocking_task_runner.h
+++ b/chromium/cc/trees/blocking_task_runner.h
@@ -13,7 +13,7 @@
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace cc {
diff --git a/chromium/cc/trees/clip_expander.h b/chromium/cc/trees/clip_expander.h
index 781d489ba04..209477a2553 100644
--- a/chromium/cc/trees/clip_expander.h
+++ b/chromium/cc/trees/clip_expander.h
@@ -5,7 +5,7 @@
#ifndef CC_TREES_CLIP_EXPANDER_H_
#define CC_TREES_CLIP_EXPANDER_H_
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "ui/gfx/geometry/rect.h"
namespace cc {
diff --git a/chromium/cc/trees/clip_node.cc b/chromium/cc/trees/clip_node.cc
index d3c1863d448..c8d2eff7f65 100644
--- a/chromium/cc/trees/clip_node.cc
+++ b/chromium/cc/trees/clip_node.cc
@@ -15,14 +15,10 @@ ClipNode::ClipNode()
: id(ClipTree::kInvalidNodeId),
parent_id(ClipTree::kInvalidNodeId),
owning_layer_id(Layer::INVALID_ID),
- clip_type(ClipType::NONE),
- transform_id(TransformTree::kInvalidNodeId),
- target_transform_id(TransformTree::kInvalidNodeId),
- target_effect_id(EffectTree::kInvalidNodeId),
- layer_clipping_uses_only_local_clip(false),
- layers_are_clipped(false),
- layers_are_clipped_when_surfaces_disabled(false),
- resets_clip(false) {}
+ clip_type(ClipType::APPLIES_LOCAL_CLIP),
+ transform_id(TransformTree::kInvalidNodeId) {
+ cached_clip_rects = std::vector<ClipRectData>(defaultCachedClipsSize);
+}
ClipNode::ClipNode(const ClipNode& other)
: id(other.id),
@@ -30,21 +26,14 @@ ClipNode::ClipNode(const ClipNode& other)
owning_layer_id(other.owning_layer_id),
clip_type(other.clip_type),
clip(other.clip),
- combined_clip_in_target_space(other.combined_clip_in_target_space),
- clip_in_target_space(other.clip_in_target_space),
- transform_id(other.transform_id),
- target_transform_id(other.target_transform_id),
- target_effect_id(other.target_effect_id),
- layer_clipping_uses_only_local_clip(
- other.layer_clipping_uses_only_local_clip),
- layers_are_clipped(other.layers_are_clipped),
- layers_are_clipped_when_surfaces_disabled(
- other.layers_are_clipped_when_surfaces_disabled),
- resets_clip(other.resets_clip) {
+ transform_id(other.transform_id) {
if (other.clip_expander) {
DCHECK_EQ(clip_type, ClipType::EXPANDS_CLIP);
clip_expander = base::MakeUnique<ClipExpander>(*other.clip_expander);
}
+ cached_clip_rects = other.cached_clip_rects;
+ cached_accumulated_rect_in_screen_space =
+ other.cached_accumulated_rect_in_screen_space;
}
ClipNode& ClipNode::operator=(const ClipNode& other) {
@@ -53,17 +42,7 @@ ClipNode& ClipNode::operator=(const ClipNode& other) {
owning_layer_id = other.owning_layer_id;
clip_type = other.clip_type;
clip = other.clip;
- combined_clip_in_target_space = other.combined_clip_in_target_space;
- clip_in_target_space = other.clip_in_target_space;
transform_id = other.transform_id;
- target_transform_id = other.target_transform_id;
- target_effect_id = other.target_effect_id;
- layer_clipping_uses_only_local_clip =
- other.layer_clipping_uses_only_local_clip;
- layers_are_clipped = other.layers_are_clipped;
- layers_are_clipped_when_surfaces_disabled =
- other.layers_are_clipped_when_surfaces_disabled;
- resets_clip = other.resets_clip;
if (other.clip_expander) {
DCHECK_EQ(clip_type, ClipType::EXPANDS_CLIP);
@@ -71,7 +50,9 @@ ClipNode& ClipNode::operator=(const ClipNode& other) {
} else {
clip_expander.reset();
}
-
+ cached_clip_rects = other.cached_clip_rects;
+ cached_accumulated_rect_in_screen_space =
+ other.cached_accumulated_rect_in_screen_space;
return *this;
}
@@ -87,17 +68,7 @@ bool ClipNode::operator==(const ClipNode& other) const {
return id == other.id && parent_id == other.parent_id &&
owning_layer_id == other.owning_layer_id &&
clip_type == other.clip_type && clip == other.clip &&
- combined_clip_in_target_space == other.combined_clip_in_target_space &&
- clip_in_target_space == other.clip_in_target_space &&
- transform_id == other.transform_id &&
- target_transform_id == other.target_transform_id &&
- target_effect_id == other.target_effect_id &&
- layer_clipping_uses_only_local_clip ==
- other.layer_clipping_uses_only_local_clip &&
- layers_are_clipped == other.layers_are_clipped &&
- layers_are_clipped_when_surfaces_disabled ==
- other.layers_are_clipped_when_surfaces_disabled &&
- resets_clip == other.resets_clip;
+ transform_id == other.transform_id;
}
void ClipNode::AsValueInto(base::trace_event::TracedValue* value) const {
@@ -107,14 +78,6 @@ void ClipNode::AsValueInto(base::trace_event::TracedValue* value) const {
value->SetInteger("clip_type", static_cast<int>(clip_type));
MathUtil::AddToTracedValue("clip", clip, value);
value->SetInteger("transform_id", transform_id);
- value->SetInteger("target_transform_id", target_transform_id);
- value->SetInteger("target_effect_id", target_effect_id);
- value->SetBoolean("layer_clipping_uses_only_local_clip",
- layer_clipping_uses_only_local_clip);
- value->SetBoolean("layers_are_clipped", layers_are_clipped);
- value->SetBoolean("layers_are_clipped_when_surfaces_disabled",
- layers_are_clipped_when_surfaces_disabled);
- value->SetBoolean("resets_clip", resets_clip);
}
} // namespace cc
diff --git a/chromium/cc/trees/clip_node.h b/chromium/cc/trees/clip_node.h
index b81c72c235e..5c204549d1c 100644
--- a/chromium/cc/trees/clip_node.h
+++ b/chromium/cc/trees/clip_node.h
@@ -7,7 +7,7 @@
#include <memory>
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/trees/clip_expander.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -27,6 +27,8 @@ struct CC_EXPORT ClipNode {
~ClipNode();
+ static const int defaultCachedClipsSize = 1;
+
// The node index of this node in the clip tree node vector.
int id;
// The node index of the parent node in the clip tree node vector.
@@ -35,10 +37,6 @@ struct CC_EXPORT ClipNode {
int owning_layer_id;
enum class ClipType {
- // The node doesn't contribute a new clip. It exists only for caching clips
- // or for resetting clipping state.
- NONE,
-
// The node contributes a new clip (that is, |clip| needs to be applied).
APPLIES_LOCAL_CLIP,
@@ -57,46 +55,20 @@ struct CC_EXPORT ClipNode {
// transform node.
gfx::RectF clip;
+ // Each element of this cache stores the accumulated clip from this clip
+ // node to a particular target.
+ mutable std::vector<ClipRectData> cached_clip_rects;
+
+ // This rect accumulates all clips from this node to the root in screen space.
+ // It is used in the computation of layer's visible rect.
+ gfx::RectF cached_accumulated_rect_in_screen_space;
+
// For nodes that expand, this represents the amount of expansion.
std::unique_ptr<ClipExpander> clip_expander;
- // Clip nodes are used for two reasons. First, they are used for determining
- // which parts of each layer are visible. Second, they are used for
- // determining whether a clip needs to be applied when drawing a layer, and if
- // so, the rect that needs to be used. These can be different since not all
- // clips need to be applied directly to each layer. For example, a layer is
- // implicitly clipped by the bounds of its target render surface and by clips
- // applied to this surface. |combined_clip_in_target_space| is used for
- // computing visible rects, and |clip_in_target_space| is used for computing
- // clips applied at draw time. Both rects are expressed in the space of the
- // target transform node, and may include clips contributed by ancestors.
- gfx::RectF combined_clip_in_target_space;
- gfx::RectF clip_in_target_space;
-
// The id of the transform node that defines the clip node's local space.
int transform_id;
- // The id of the transform node that defines the clip node's target space.
- int target_transform_id;
-
- // The id of the effect node that defines the clip node's target space.
- // TODO(crbug.com/642581 crbug.com/642584): As we progress toward SPv2 and
- // layer list mode, there may be layers having the same clip but draw onto
- // different target. Target information shall be removed from here.
- int target_effect_id;
-
- // When true, |clip_in_target_space| does not include clips from ancestor
- // nodes.
- bool layer_clipping_uses_only_local_clip : 1;
-
- // True if layers with this clip tree node need to be drawn with a clip
- // applied.
- bool layers_are_clipped : 1;
- bool layers_are_clipped_when_surfaces_disabled : 1;
-
- // Nodes that correspond to unclipped surfaces disregard ancestor clips.
- bool resets_clip : 1;
-
bool operator==(const ClipNode& other) const;
void AsValueInto(base::trace_event::TracedValue* value) const;
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc
index ae311dd2cfd..aa4a6236801 100644
--- a/chromium/cc/trees/damage_tracker.cc
+++ b/chromium/cc/trees/damage_tracker.cc
@@ -9,11 +9,11 @@
#include <algorithm>
#include "base/memory/ptr_util.h"
+#include "cc/base/filter_operations.h"
#include "cc/base/math_util.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/render_surface_impl.h"
-#include "cc/output/filter_operations.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -128,8 +128,8 @@ void DamageTracker::UpdateDamageTrackingState(
gfx::Rect damage_rect;
bool is_rect_valid = damage_for_this_update.GetAsRect(&damage_rect);
if (is_rect_valid) {
- damage_rect = filters.MapRect(
- damage_rect, target_surface->FiltersTransform().matrix());
+ damage_rect =
+ filters.MapRect(damage_rect, target_surface->SurfaceScale().matrix());
damage_for_this_update = DamageAccumulator();
damage_for_this_update.Union(damage_rect);
}
diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h
index e41a1cf8573..6ddc504dafa 100644
--- a/chromium/cc/trees/damage_tracker.h
+++ b/chromium/cc/trees/damage_tracker.h
@@ -9,7 +9,7 @@
#include <vector>
#include "base/macros.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/layers/layer_collections.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index 13f8742476f..91cec6dc030 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -6,10 +6,10 @@
#include <stddef.h>
+#include "cc/base/filter_operation.h"
+#include "cc/base/filter_operations.h"
#include "cc/base/math_util.h"
#include "cc/layers/layer_impl.h"
-#include "cc/output/filter_operation.h"
-#include "cc/output/filter_operations.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
@@ -27,18 +27,14 @@ namespace {
void ExecuteCalculateDrawProperties(LayerImpl* root,
float device_scale_factor,
- bool skip_verify_visible_rect_calculations,
LayerImplList* render_surface_layer_list) {
// Sanity check: The test itself should create the root layer's render
// surface, so that the surface (and its damage tracker) can
// persist across multiple calls to this function.
ASSERT_FALSE(render_surface_layer_list->size());
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), device_scale_factor, render_surface_layer_list);
- if (skip_verify_visible_rect_calculations)
- inputs.verify_visible_rect_calculations = false;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
ASSERT_TRUE(root->GetRenderSurface());
}
@@ -50,10 +46,7 @@ void ClearDamageForAllSurfaces(LayerImpl* root) {
}
}
-void EmulateDrawingOneFrame(
- LayerImpl* root,
- float device_scale_factor = 1.f,
- bool skip_verify_visible_rect_calculations = false) {
+void EmulateDrawingOneFrame(LayerImpl* root, float device_scale_factor = 1.f) {
// This emulates only steps that are relevant to testing the damage tracker:
// 1. computing the render passes and layerlists
// 2. updating all damage trackers in the correct order
@@ -62,7 +55,6 @@ void EmulateDrawingOneFrame(
LayerImplList render_surface_layer_list;
ExecuteCalculateDrawProperties(root, device_scale_factor,
- skip_verify_visible_rect_calculations,
&render_surface_layer_list);
// Iterate back-to-front, so that damage correctly propagates from descendant
@@ -106,6 +98,7 @@ class DamageTrackerTest : public testing::Test {
root->test_properties()->AddChild(std::move(child));
}
host_impl_.active_tree()->SetRootLayerForTesting(std::move(root));
+ host_impl_.active_tree()->SetElementIdsForTesting();
return host_impl_.active_tree()->root_layer_for_testing();
}
@@ -157,6 +150,7 @@ class DamageTrackerTest : public testing::Test {
root->test_properties()->AddChild(std::move(child1));
root->test_properties()->AddChild(std::move(child2));
host_impl_.active_tree()->SetRootLayerForTesting(std::move(root));
+ host_impl_.active_tree()->SetElementIdsForTesting();
return host_impl_.active_tree()->root_layer_for_testing();
}
@@ -393,8 +387,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
EmulateDrawingOneFrame(root);
ClearDamageForAllSurfaces(root);
child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
- root->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.5f, child->effect_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f);
EmulateDrawingOneFrame(root);
ASSERT_EQ(2u, root->GetRenderSurface()->layer_list().size());
@@ -423,8 +416,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
ClearDamageForAllSurfaces(root);
gfx::Transform translation;
translation.Translate(100.f, 130.f);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- translation, child->transform_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetTransformMutated(child->element_id(),
+ translation);
EmulateDrawingOneFrame(root);
// Expect damage to be the combination of the previous one and the new one.
@@ -482,8 +475,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) {
// With the anchor on the layer's center, now we can test the rotation more
// intuitively, since it applies about the layer's anchor.
ClearDamageForAllSurfaces(root);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- rotation, child->transform_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetTransformMutated(child->element_id(), rotation);
EmulateDrawingOneFrame(root);
// Since the child layer is square, rotation by 45 degrees about the center
@@ -530,9 +522,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
// Sanity check that the child layer's bounds would actually get clipped by
// w < 0, otherwise this test is not actually testing the intended scenario.
- gfx::QuadF test_quad(gfx::RectF(gfx::PointF(), gfx::SizeF(100.f, 100.f)));
+ gfx::RectF test_rect(child->position(), gfx::SizeF(child->bounds()));
bool clipped = false;
- MathUtil::MapQuad(transform, test_quad, &clipped);
+ MathUtil::MapQuad(transform, gfx::QuadF(test_rect), &clipped);
EXPECT_TRUE(clipped);
// Damage the child without moving it.
@@ -540,8 +532,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
ClearDamageForAllSurfaces(root);
- root->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.5f, child->effect_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f);
EmulateDrawingOneFrame(root);
// The expected damage should cover the entire root surface (500x500), but we
@@ -601,8 +592,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) {
child->test_properties()->force_render_surface = true;
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
- child->layer_tree_impl()->property_trees()->effect_tree.OnFilterAnimated(
- filters, child->effect_tree_index(), child->layer_tree_impl());
+ child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
@@ -652,8 +642,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) {
child->test_properties()->transform = transform;
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
EmulateDrawingOneFrame(root);
- child->layer_tree_impl()->property_trees()->effect_tree.OnFilterAnimated(
- filters, child->effect_tree_index(), child->layer_tree_impl());
+ child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
@@ -708,8 +697,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
int device_scale_factor = 2;
EmulateDrawingOneFrame(root, device_scale_factor);
- child->layer_tree_impl()->property_trees()->effect_tree.OnFilterAnimated(
- filters, child->effect_tree_index(), child->layer_tree_impl());
+ child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters);
EmulateDrawingOneFrame(root, device_scale_factor);
EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
@@ -1009,8 +997,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) {
// CASE 1: Damage to a descendant surface should propagate properly to
// ancestor surface.
ClearDamageForAllSurfaces(root);
- root->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.5f, grand_child1->effect_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.5f);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
@@ -1027,10 +1014,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) {
// - child2 damage in root surface space:
// gfx::Rect(11, 11, 18, 18);
ClearDamageForAllSurfaces(root);
- root->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.7f, grand_child1->effect_tree_index(), root->layer_tree_impl());
- root->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.7f, child2->effect_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.7f);
+ root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.7f);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
@@ -1099,8 +1084,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) {
ClearDamageForAllSurfaces(root);
gfx::Transform translation;
translation.Translate(-50.f, -50.f);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- translation, child1->transform_tree_index(), root->layer_tree_impl());
+ root->layer_tree_impl()->SetTransformMutated(child1->element_id(),
+ translation);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid(
@@ -1451,9 +1436,7 @@ TEST_F(DamageTrackerTest, HugeDamageRect) {
// Visible rects computed from combining clips in target space and root
// space don't match because of the loss in floating point accuracy. So, we
// skip verify_clip_tree_calculations.
- bool skip_verify_visible_rect_calculations = true;
- EmulateDrawingOneFrame(root, device_scale_factor,
- skip_verify_visible_rect_calculations);
+ EmulateDrawingOneFrame(root, device_scale_factor);
// The expected damage should cover the visible part of the child layer,
// which is (0, 0, i, i) in the viewport.
@@ -1482,9 +1465,7 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
float device_scale_factor = 1.f;
- bool skip_verify_visible_rect_calculations = true;
- EmulateDrawingOneFrame(root, device_scale_factor,
- skip_verify_visible_rect_calculations);
+ EmulateDrawingOneFrame(root, device_scale_factor);
// The expected damage would be too large to store in a gfx::Rect, so we
// should damage everything (ie, we don't have a valid rect).
@@ -1515,9 +1496,7 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
float device_scale_factor = 1.f;
- bool skip_verify_visible_rect_calculations = true;
- EmulateDrawingOneFrame(root, device_scale_factor,
- skip_verify_visible_rect_calculations);
+ EmulateDrawingOneFrame(root, device_scale_factor);
// The expected damage would be too large to store in a gfx::Rect, so we
// should damage everything (ie, we don't have a valid rect).
@@ -1548,10 +1527,8 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
float device_scale_factor = 1.f;
- bool skip_verify_visible_rect_calculations = true;
LayerImplList render_surface_layer_list;
ExecuteCalculateDrawProperties(root, device_scale_factor,
- skip_verify_visible_rect_calculations,
&render_surface_layer_list);
auto* surface = child1->GetRenderSurface();
@@ -1590,7 +1567,6 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) {
// Recompute all damage / properties.
render_surface_layer_list.clear();
ExecuteCalculateDrawProperties(root, device_scale_factor,
- skip_verify_visible_rect_calculations,
&render_surface_layer_list);
surface = child1->GetRenderSurface();
surface->damage_tracker()->UpdateDamageTrackingState(
@@ -1645,10 +1621,8 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) {
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
float device_scale_factor = 1.f;
- bool skip_verify_visible_rect_calculations = true;
LayerImplList render_surface_layer_list;
ExecuteCalculateDrawProperties(root, device_scale_factor,
- skip_verify_visible_rect_calculations,
&render_surface_layer_list);
auto* surface = child1->GetRenderSurface();
@@ -1687,7 +1661,6 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) {
// Recompute all damage / properties.
render_surface_layer_list.clear();
ExecuteCalculateDrawProperties(root, device_scale_factor,
- skip_verify_visible_rect_calculations,
&render_surface_layer_list);
surface = child1->GetRenderSurface();
surface->damage_tracker()->UpdateDamageTrackingState(
diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc
new file mode 100644
index 00000000000..243c610214c
--- /dev/null
+++ b/chromium/cc/trees/debug_rect_history.cc
@@ -0,0 +1,238 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/debug_rect_history.h"
+
+#include <stddef.h>
+
+#include "base/memory/ptr_util.h"
+#include "cc/base/math_util.h"
+#include "cc/layers/layer_impl.h"
+#include "cc/layers/layer_list_iterator.h"
+#include "cc/layers/layer_utils.h"
+#include "cc/layers/render_surface_impl.h"
+#include "cc/trees/damage_tracker.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_host_common.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+
+namespace cc {
+
+// static
+std::unique_ptr<DebugRectHistory> DebugRectHistory::Create() {
+ return base::WrapUnique(new DebugRectHistory());
+}
+
+DebugRectHistory::DebugRectHistory() {}
+
+DebugRectHistory::~DebugRectHistory() {}
+
+void DebugRectHistory::SaveDebugRectsForCurrentFrame(
+ LayerTreeImpl* tree_impl,
+ LayerImpl* hud_layer,
+ const LayerImplList& render_surface_layer_list,
+ const LayerTreeDebugState& debug_state) {
+ // For now, clear all rects from previous frames. In the future we may want to
+ // store all debug rects for a history of many frames.
+ debug_rects_.clear();
+
+ if (debug_state.show_touch_event_handler_rects)
+ SaveTouchEventHandlerRects(tree_impl);
+
+ if (debug_state.show_wheel_event_handler_rects)
+ SaveWheelEventHandlerRects(tree_impl);
+
+ if (debug_state.show_scroll_event_handler_rects)
+ SaveScrollEventHandlerRects(tree_impl);
+
+ if (debug_state.show_non_fast_scrollable_rects)
+ SaveNonFastScrollableRects(tree_impl);
+
+ if (debug_state.show_paint_rects)
+ SavePaintRects(tree_impl);
+
+ if (debug_state.show_property_changed_rects)
+ SavePropertyChangedRects(render_surface_layer_list, hud_layer);
+
+ if (debug_state.show_surface_damage_rects)
+ SaveSurfaceDamageRects(render_surface_layer_list);
+
+ if (debug_state.show_screen_space_rects)
+ SaveScreenSpaceRects(render_surface_layer_list);
+
+ if (debug_state.show_layer_animation_bounds_rects)
+ SaveLayerAnimationBoundsRects(tree_impl);
+}
+
+void DebugRectHistory::SavePaintRects(LayerTreeImpl* tree_impl) {
+ // We would like to visualize where any layer's paint rect (update rect) has
+ // changed, regardless of whether this layer is skipped for actual drawing or
+ // not. Therefore we traverse over all layers, not just the render surface
+ // list.
+ for (auto* layer : *tree_impl) {
+ Region invalidation_region = layer->GetInvalidationRegionForDebugging();
+ if (invalidation_region.IsEmpty() || !layer->DrawsContent())
+ continue;
+
+ for (Region::Iterator it(invalidation_region); it.has_rect(); it.next()) {
+ debug_rects_.push_back(DebugRect(
+ PAINT_RECT_TYPE, MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), it.rect())));
+ }
+ }
+}
+
+void DebugRectHistory::SavePropertyChangedRects(
+ const LayerImplList& render_surface_layer_list,
+ LayerImpl* hud_layer) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
+ LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
+ RenderSurfaceImpl* render_surface =
+ render_surface_layer->GetRenderSurface();
+ DCHECK(render_surface);
+
+ const LayerImplList& layer_list = render_surface->layer_list();
+ for (unsigned layer_index = 0; layer_index < layer_list.size();
+ ++layer_index) {
+ LayerImpl* layer = layer_list[layer_index];
+
+ if (layer->GetRenderSurface() &&
+ layer->GetRenderSurface() != render_surface)
+ continue;
+
+ if (layer == hud_layer)
+ continue;
+
+ if (!layer->LayerPropertyChanged())
+ continue;
+
+ debug_rects_.push_back(DebugRect(
+ PROPERTY_CHANGED_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(),
+ gfx::Rect(layer->bounds()))));
+ }
+ }
+}
+
+void DebugRectHistory::SaveSurfaceDamageRects(
+ const LayerImplList& render_surface_layer_list) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
+ LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
+ RenderSurfaceImpl* render_surface =
+ render_surface_layer->GetRenderSurface();
+ DCHECK(render_surface);
+
+ debug_rects_.push_back(DebugRect(
+ SURFACE_DAMAGE_RECT_TYPE, MathUtil::MapEnclosingClippedRect(
+ render_surface->screen_space_transform(),
+ render_surface->GetDamageRect())));
+ }
+}
+
+void DebugRectHistory::SaveScreenSpaceRects(
+ const LayerImplList& render_surface_layer_list) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
+ LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
+ RenderSurfaceImpl* render_surface =
+ render_surface_layer->GetRenderSurface();
+ DCHECK(render_surface);
+
+ debug_rects_.push_back(DebugRect(
+ SCREEN_SPACE_RECT_TYPE, MathUtil::MapEnclosingClippedRect(
+ render_surface->screen_space_transform(),
+ render_surface->content_rect())));
+ }
+}
+
+void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) {
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ tree_impl,
+ [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); });
+}
+
+void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
+ for (Region::Iterator iter(layer->touch_event_handler_region());
+ iter.has_rect(); iter.next()) {
+ debug_rects_.push_back(
+ DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), iter.rect())));
+ }
+}
+
+void DebugRectHistory::SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl) {
+ EventListenerProperties event_properties =
+ tree_impl->event_listener_properties(EventListenerClass::kMouseWheel);
+ if (event_properties == EventListenerProperties::kNone ||
+ event_properties == EventListenerProperties::kPassive) {
+ return;
+ }
+
+ // Since the wheel event handlers property is on the entire layer tree just
+ // mark inner viewport if have listeners.
+ LayerImpl* inner_viewport = tree_impl->InnerViewportScrollLayer();
+ if (!inner_viewport)
+ return;
+ debug_rects_.push_back(DebugRect(
+ WHEEL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(inner_viewport->ScreenSpaceTransform(),
+ gfx::Rect(inner_viewport->bounds()))));
+}
+
+void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) {
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ tree_impl,
+ [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); });
+}
+
+void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) {
+ if (!layer->layer_tree_impl()->have_scroll_event_handlers())
+ return;
+
+ debug_rects_.push_back(
+ DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(),
+ gfx::Rect(layer->bounds()))));
+}
+
+void DebugRectHistory::SaveNonFastScrollableRects(LayerTreeImpl* tree_impl) {
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ tree_impl,
+ [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); });
+}
+
+void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
+ for (Region::Iterator iter(layer->non_fast_scrollable_region());
+ iter.has_rect(); iter.next()) {
+ debug_rects_.push_back(
+ DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), iter.rect())));
+ }
+}
+
+void DebugRectHistory::SaveLayerAnimationBoundsRects(LayerTreeImpl* tree_impl) {
+ for (auto it = tree_impl->rbegin(); it != tree_impl->rend(); ++it) {
+ if (!(*it)->is_drawn_render_surface_layer_list_member())
+ continue;
+
+ // TODO(avallee): Figure out if we should show something for a layer who's
+ // animating bounds but that we can't compute them.
+ gfx::BoxF inflated_bounds;
+ if (!LayerUtils::GetAnimationBounds(**it, &inflated_bounds))
+ continue;
+
+ debug_rects_.push_back(
+ DebugRect(ANIMATION_BOUNDS_RECT_TYPE,
+ gfx::ToEnclosingRect(gfx::RectF(
+ inflated_bounds.x(), inflated_bounds.y(),
+ inflated_bounds.width(), inflated_bounds.height()))));
+ }
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/debug_rect_history.h b/chromium/cc/trees/debug_rect_history.h
new file mode 100644
index 00000000000..183cddeb775
--- /dev/null
+++ b/chromium/cc/trees/debug_rect_history.h
@@ -0,0 +1,99 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_DEBUG_RECT_HISTORY_H_
+#define CC_TREES_DEBUG_RECT_HISTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "cc/layers/layer_collections.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace cc {
+
+class LayerImpl;
+class LayerTreeDebugState;
+class LayerTreeImpl;
+
+// There are currently six types of debug rects:
+//
+// - Paint rects (update rects): regions of a layer that needed to be
+// re-uploaded to the texture resource; in most cases implying that they had to
+// be repainted, too.
+//
+// - Property-changed rects: enclosing bounds of layers that cause changes to
+// the screen even if the layer did not change internally. (For example, if the
+// layer's opacity or position changes.)
+//
+// - Surface damage rects: the aggregate damage on a target surface that is
+// caused by all layers and surfaces that contribute to it. This includes (1)
+// paint rects, (2) property- changed rects, and (3) newly exposed areas.
+//
+// - Screen space rects: this is the region the contents occupy in screen space.
+enum DebugRectType {
+ PAINT_RECT_TYPE,
+ PROPERTY_CHANGED_RECT_TYPE,
+ SURFACE_DAMAGE_RECT_TYPE,
+ SCREEN_SPACE_RECT_TYPE,
+ TOUCH_EVENT_HANDLER_RECT_TYPE,
+ WHEEL_EVENT_HANDLER_RECT_TYPE,
+ SCROLL_EVENT_HANDLER_RECT_TYPE,
+ NON_FAST_SCROLLABLE_RECT_TYPE,
+ ANIMATION_BOUNDS_RECT_TYPE,
+};
+
+struct DebugRect {
+ DebugRect(DebugRectType new_type, const gfx::Rect& new_rect)
+ : type(new_type), rect(new_rect) {}
+
+ DebugRectType type;
+ gfx::Rect rect;
+};
+
+// This class maintains a history of rects of various types that can be used
+// for debugging purposes. The overhead of collecting rects is performed only if
+// the appropriate LayerTreeSettings are enabled.
+class DebugRectHistory {
+ public:
+ static std::unique_ptr<DebugRectHistory> Create();
+
+ ~DebugRectHistory();
+
+ // Note: Saving debug rects must happen before layers' change tracking is
+ // reset.
+ void SaveDebugRectsForCurrentFrame(
+ LayerTreeImpl* tree_impl,
+ LayerImpl* hud_layer,
+ const LayerImplList& render_surface_layer_list,
+ const LayerTreeDebugState& debug_state);
+
+ const std::vector<DebugRect>& debug_rects() { return debug_rects_; }
+
+ private:
+ DebugRectHistory();
+
+ void SavePaintRects(LayerTreeImpl* tree_impl);
+ void SavePropertyChangedRects(const LayerImplList& render_surface_layer_list,
+ LayerImpl* hud_layer);
+ void SaveSurfaceDamageRects(const LayerImplList& render_surface_layer_list);
+ void SaveScreenSpaceRects(const LayerImplList& render_surface_layer_list);
+ void SaveTouchEventHandlerRects(LayerTreeImpl* layer);
+ void SaveTouchEventHandlerRectsCallback(LayerImpl* layer);
+ void SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl);
+ void SaveScrollEventHandlerRects(LayerTreeImpl* layer);
+ void SaveScrollEventHandlerRectsCallback(LayerImpl* layer);
+ void SaveNonFastScrollableRects(LayerTreeImpl* layer);
+ void SaveNonFastScrollableRectsCallback(LayerImpl* layer);
+ void SaveLayerAnimationBoundsRects(LayerTreeImpl* tree_impl);
+
+ std::vector<DebugRect> debug_rects_;
+
+ DISALLOW_COPY_AND_ASSIGN(DebugRectHistory);
+};
+
+} // namespace cc
+
+#endif // CC_TREES_DEBUG_RECT_HISTORY_H_
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index c5128934db9..5af6686aa61 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -17,6 +17,7 @@
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/property_tree.h"
#include "cc/trees/property_tree_builder.h"
+#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -34,54 +35,45 @@ static bool IsRootLayer(const LayerImpl* layer) {
return layer->layer_tree_impl()->IsRootLayer(layer);
}
-static const EffectNode* ContentsTargetEffectNode(
- const int effect_tree_index,
- const EffectTree& effect_tree) {
- const EffectNode* effect_node = effect_tree.Node(effect_tree_index);
- return effect_tree.GetRenderSurface(effect_tree_index)
- ? effect_node
- : effect_tree.Node(effect_node->target_id);
+static void PostConcatSurfaceContentsScale(const EffectNode* effect_node,
+ gfx::Transform* transform) {
+ if (!effect_node) {
+ // This can happen when PaintArtifactCompositor builds property trees as it
+ // doesn't set effect ids on clip nodes.
+ return;
+ }
+ DCHECK(effect_node->has_render_surface);
+ transform->matrix().postScale(effect_node->surface_contents_scale.x(),
+ effect_node->surface_contents_scale.y(), 1.f);
}
-bool ComputeClipRectInTargetSpace(const LayerImpl* layer,
- const ClipNode* clip_node,
- const PropertyTrees* property_trees,
- int target_node_id,
- bool for_visible_rect_calculation,
- gfx::RectF* clip_rect_in_target_space) {
- DCHECK(layer->clip_tree_index() == clip_node->id);
- DCHECK(clip_node->target_transform_id != target_node_id);
-
- const EffectTree& effect_tree = property_trees->effect_tree;
- const EffectNode* target_effect_node =
- ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree);
- gfx::Transform clip_to_target;
- // We use the local clip for clip rect calculation and combined clip for
- // visible rect calculation.
- gfx::RectF clip_from_clip_node =
- for_visible_rect_calculation ? clip_node->combined_clip_in_target_space
- : clip_node->clip_in_target_space;
-
- if (clip_node->target_transform_id > target_node_id) {
- // In this case, layer has a scroll parent. We need to keep the scale
- // at the layer's target but remove the scale at the scroll parent's
- // target.
- if (property_trees->GetToTarget(clip_node->target_transform_id,
- target_effect_node->id, &clip_to_target)) {
- const EffectNode* source_node =
- effect_tree.Node(clip_node->target_effect_id);
- ConcatInverseSurfaceContentsScale(source_node, &clip_to_target);
- *clip_rect_in_target_space =
- MathUtil::MapClippedRect(clip_to_target, clip_from_clip_node);
+static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees,
+ int source_effect_id,
+ int dest_effect_id,
+ gfx::RectF clip_in_source_space,
+ gfx::RectF* clip_in_dest_space) {
+ const EffectNode* source_effect_node =
+ property_trees->effect_tree.Node(source_effect_id);
+ int source_transform_id = source_effect_node->transform_id;
+ const EffectNode* dest_effect_node =
+ property_trees->effect_tree.Node(dest_effect_id);
+ int dest_transform_id = dest_effect_node->transform_id;
+ gfx::Transform source_to_dest;
+ if (source_transform_id > dest_transform_id) {
+ if (property_trees->GetToTarget(source_transform_id, dest_effect_id,
+ &source_to_dest)) {
+ ConcatInverseSurfaceContentsScale(source_effect_node, &source_to_dest);
+ *clip_in_dest_space =
+ MathUtil::MapClippedRect(source_to_dest, clip_in_source_space);
} else {
return false;
}
} else {
- if (property_trees->GetFromTarget(
- target_node_id, clip_node->target_effect_id, &clip_to_target)) {
- PostConcatSurfaceContentsScale(target_effect_node, &clip_to_target);
- *clip_rect_in_target_space =
- MathUtil::ProjectClippedRect(clip_to_target, clip_from_clip_node);
+ if (property_trees->GetFromTarget(dest_transform_id, source_effect_id,
+ &source_to_dest)) {
+ PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest);
+ *clip_in_dest_space =
+ MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space);
} else {
return false;
}
@@ -89,11 +81,6 @@ bool ComputeClipRectInTargetSpace(const LayerImpl* layer,
return true;
}
-struct ConditionalClip {
- bool is_clipped;
- gfx::RectF clip_rect;
-};
-
static ConditionalClip ComputeTargetRectInLocalSpace(
gfx::RectF rect,
const PropertyTrees* property_trees,
@@ -103,8 +90,8 @@ static ConditionalClip ComputeTargetRectInLocalSpace(
gfx::Transform target_to_local;
bool success = property_trees->GetFromTarget(
local_transform_id, target_effect_id, &target_to_local);
+ // If transform is not invertible, cannot apply clip.
if (!success)
- // If transform is not invertible, cannot apply clip.
return ConditionalClip{false, gfx::RectF()};
if (target_transform_id > local_transform_id)
@@ -115,29 +102,6 @@ static ConditionalClip ComputeTargetRectInLocalSpace(
MathUtil::ProjectClippedRect(target_to_local, rect)};
}
-static ConditionalClip ConvertRectBetweenSurfaceSpaces(
- gfx::RectF rect,
- const PropertyTrees* property_trees,
- int source_transform_id,
- int source_effect_id,
- int dest_transform_id,
- int dest_effect_id) {
- gfx::Transform source_to_dest;
- bool success = property_trees->GetToTarget(source_transform_id,
- dest_effect_id, &source_to_dest);
- if (!success)
- return ConditionalClip{false, gfx::RectF()};
- const EffectTree& effect_tree = property_trees->effect_tree;
- const EffectNode* source_effect_node = effect_tree.Node(source_effect_id);
- ConcatInverseSurfaceContentsScale(source_effect_node, &source_to_dest);
- if (source_transform_id > dest_transform_id) {
- return ConditionalClip{true, // is_clipped
- MathUtil::MapClippedRect(source_to_dest, rect)};
- }
- return ConditionalClip{true, // is_clipped
- MathUtil::ProjectClippedRect(source_to_dest, rect)};
-}
-
static ConditionalClip ComputeLocalRectInTargetSpace(
gfx::RectF rect,
const PropertyTrees* property_trees,
@@ -206,362 +170,149 @@ static bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees,
const EffectNode* expanding_effect_node =
property_trees->effect_tree.Node(
clip_node->clip_expander->target_effect_id());
- ConditionalClip accumulated_clip_in_expanding_space =
- ConvertRectBetweenSurfaceSpaces(
- *accumulated_clip, property_trees, target_transform_id, target_id,
- expanding_effect_node->transform_id, expanding_effect_node->id);
+ gfx::RectF accumulated_clip_rect_in_expanding_space;
+ bool success = ConvertRectBetweenSurfaceSpaces(
+ property_trees, target_id, expanding_effect_node->id,
+ *accumulated_clip, &accumulated_clip_rect_in_expanding_space);
// If transform is not invertible, no clip will be applied.
- if (!accumulated_clip_in_expanding_space.is_clipped)
+ if (!success)
return false;
// Do the expansion.
gfx::RectF expanded_clip_in_expanding_space =
gfx::RectF(clip_node->clip_expander->MapRectReverse(
- gfx::ToEnclosingRect(
- accumulated_clip_in_expanding_space.clip_rect),
+ gfx::ToEnclosingRect(accumulated_clip_rect_in_expanding_space),
property_trees));
// Put the expanded clip back into the original target space.
- ConditionalClip expanded_clip_in_target_space =
- ConvertRectBetweenSurfaceSpaces(
- expanded_clip_in_expanding_space, property_trees,
- expanding_effect_node->transform_id, expanding_effect_node->id,
- target_transform_id, target_id);
+ success = ConvertRectBetweenSurfaceSpaces(
+ property_trees, expanding_effect_node->id, target_id,
+ expanded_clip_in_expanding_space, accumulated_clip);
// If transform is not invertible, no clip will be applied.
- if (!expanded_clip_in_target_space.is_clipped)
+ if (!success)
return false;
- *accumulated_clip = expanded_clip_in_target_space.clip_rect;
return true;
}
- case ClipNode::ClipType::NONE:
- return true;
}
NOTREACHED();
return true;
}
-static ConditionalClip ComputeAccumulatedClip(
- const PropertyTrees* property_trees,
- bool include_viewport_clip,
- bool include_expanding_clips,
- int local_clip_id,
- int target_id) {
- DCHECK(!include_viewport_clip ||
- target_id == EffectTree::kContentsRootNodeId);
- const ClipTree& clip_tree = property_trees->clip_tree;
- const EffectTree& effect_tree = property_trees->effect_tree;
+static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees,
+ bool include_expanding_clips,
+ int local_clip_id,
+ int target_id) {
+ ClipRectData* cached_data =
+ property_trees->FetchClipRectFromCache(local_clip_id, target_id);
+ if (cached_data->target_id != EffectTree::kInvalidNodeId) {
+ // Cache hit
+ return cached_data->clip;
+ }
+ cached_data->target_id = target_id;
+ const ClipTree& clip_tree = property_trees->clip_tree;
const ClipNode* clip_node = clip_tree.Node(local_clip_id);
+ const EffectTree& effect_tree = property_trees->effect_tree;
const EffectNode* target_node = effect_tree.Node(target_id);
int target_transform_id = target_node->transform_id;
+ bool cache_hit = false;
+ ConditionalClip cached_clip = ConditionalClip{false, gfx::RectF()};
+ ConditionalClip unclipped = ConditionalClip{false, gfx::RectF()};
+
// Collect all the clips that need to be accumulated.
- std::stack<const ClipNode*> parent_chain;
+ std::stack<const ClipNode*, std::vector<const ClipNode*>> parent_chain;
// If target is not direct ancestor of clip, this will find least common
- // ancestor between the target and the clip.
+ // ancestor between the target and the clip. Or, if the target has a
+ // contributing layer that escapes clip, this will find the nearest ancestor
+ // that doesn't.
while (target_node->clip_id > clip_node->id ||
- target_node->has_unclipped_descendants) {
+ effect_tree.GetRenderSurface(target_node->id)
+ ->has_contributing_layer_that_escapes_clip()) {
target_node = effect_tree.Node(target_node->target_id);
}
- // Collect clip nodes up to the least common ancestor.
+ // Collect clip nodes up to the least common ancestor or till we get a cache
+ // hit.
while (target_node->clip_id < clip_node->id) {
+ if (parent_chain.size() > 0) {
+ // Search the cache.
+ for (auto& data : clip_node->cached_clip_rects) {
+ if (data.target_id == target_id) {
+ cache_hit = true;
+ cached_clip = data.clip;
+ }
+ }
+ }
parent_chain.push(clip_node);
clip_node = clip_tree.parent(clip_node);
}
- DCHECK_EQ(target_node->clip_id, clip_node->id);
- if (!include_viewport_clip && parent_chain.size() == 0) {
- // There aren't any clips to apply.
- return ConditionalClip{false, gfx::RectF()};
+ if (parent_chain.size() == 0) {
+ // No accumulated clip nodes.
+ cached_data->clip = unclipped;
+ return unclipped;
}
- if (!include_viewport_clip) {
- clip_node = parent_chain.top();
- parent_chain.pop();
- }
-
- // Find the first clip in the chain that we need to apply.
- while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP &&
- parent_chain.size() > 0) {
- clip_node = parent_chain.top();
- parent_chain.pop();
- }
+ clip_node = parent_chain.top();
+ parent_chain.pop();
- if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
- // No clip node applying clip in between.
- return ConditionalClip{false, gfx::RectF()};
- }
-
- ConditionalClip current_clip = ComputeCurrentClip(
- clip_node, property_trees, target_transform_id, target_id);
-
- // If transform is not invertible, no clip will be applied.
- if (!current_clip.is_clipped)
- return ConditionalClip{false, gfx::RectF()};
- gfx::RectF accumulated_clip = current_clip.clip_rect;
-
- while (parent_chain.size() > 0) {
- clip_node = parent_chain.top();
- parent_chain.pop();
+ gfx::RectF accumulated_clip;
+ if (cache_hit && cached_clip.is_clipped) {
+ // Apply the first clip in parent_chain to the cached clip.
+ accumulated_clip = cached_clip.clip_rect;
bool success = ApplyClipNodeToAccumulatedClip(
property_trees, include_expanding_clips, target_id, target_transform_id,
clip_node, &accumulated_clip);
-
- // Failure to apply the clip means we encountered an uninvertible transform,
- // so no clip will be applied.
- if (!success)
- return ConditionalClip{false /* is_clipped */, gfx::RectF()};
- }
-
- return ConditionalClip{true /* is_clipped */, accumulated_clip.IsEmpty()
- ? gfx::RectF()
- : accumulated_clip};
-}
-
-static gfx::RectF ComputeAccumulatedClipInRootSpaceForVisibleRect(
- const PropertyTrees* property_trees,
- int local_clip_id) {
- const int root_effect_id = EffectTree::kContentsRootNodeId;
- bool include_viewport_clip = true;
- bool include_expanding_clips = true;
- ConditionalClip accumulated_clip = ComputeAccumulatedClip(
- property_trees, include_viewport_clip, include_expanding_clips,
- local_clip_id, root_effect_id);
- DCHECK(accumulated_clip.is_clipped);
- return accumulated_clip.clip_rect;
-}
-
-void CalculateClipRects(const std::vector<LayerImpl*>& visible_layer_list,
- const PropertyTrees* property_trees,
- bool non_root_surfaces_enabled) {
- const ClipTree& clip_tree = property_trees->clip_tree;
- for (auto* layer : visible_layer_list) {
- const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
- bool layer_needs_clip_rect =
- non_root_surfaces_enabled
- ? clip_node->layers_are_clipped
- : clip_node->layers_are_clipped_when_surfaces_disabled;
- if (!layer_needs_clip_rect) {
- layer->set_clip_rect(gfx::Rect());
- continue;
+ if (!success) {
+ // Singular transform
+ cached_data->clip = unclipped;
+ return unclipped;
}
- if (!non_root_surfaces_enabled) {
- layer->set_clip_rect(
- gfx::ToEnclosingRect(clip_node->clip_in_target_space));
- continue;
+ } else {
+ // No cache hit or the cached clip has no clip to apply. We need to find
+ // the first clip that applies clip as there is no clip to expand.
+ while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP &&
+ parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
}
- const TransformTree& transform_tree = property_trees->transform_tree;
- const TransformNode* transform_node =
- transform_tree.Node(layer->transform_tree_index());
- int target_node_id = transform_tree.ContentTargetId(transform_node->id);
-
- // The clip node stores clip rect in its target space.
- gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space;
-
- // If required, this clip rect should be mapped to the current layer's
- // target space.
- if (clip_node->target_transform_id != target_node_id) {
- // In this case, layer has a clip parent or scroll parent (or shares the
- // target with an ancestor layer that has clip parent) and the clip
- // parent's target is different from the layer's target. As the layer's
- // target has unclippped descendants, it is unclippped.
- if (!clip_node->layers_are_clipped)
- continue;
-
- // Compute the clip rect in target space and store it.
- bool for_visible_rect_calculation = false;
- if (!ComputeClipRectInTargetSpace(
- layer, clip_node, property_trees, target_node_id,
- for_visible_rect_calculation, &clip_rect_in_target_space))
- continue;
+ if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
+ // No clip to apply.
+ cached_data->clip = unclipped;
+ return unclipped;
}
-
- if (!clip_rect_in_target_space.IsEmpty()) {
- layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space));
- } else {
- layer->set_clip_rect(gfx::Rect());
+ ConditionalClip current_clip = ComputeCurrentClip(
+ clip_node, property_trees, target_transform_id, target_id);
+ if (!current_clip.is_clipped) {
+ // Singular transform
+ cached_data->clip = unclipped;
+ return unclipped;
}
+ accumulated_clip = current_clip.clip_rect;
}
-}
-
-void CalculateVisibleRects(const LayerImplList& visible_layer_list,
- const PropertyTrees* property_trees,
- bool non_root_surfaces_enabled) {
- const EffectTree& effect_tree = property_trees->effect_tree;
- const TransformTree& transform_tree = property_trees->transform_tree;
- const ClipTree& clip_tree = property_trees->clip_tree;
- for (auto* layer : visible_layer_list) {
- gfx::Size layer_bounds = layer->bounds();
-
- int effect_ancestor_with_copy_request =
- effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index());
- if (effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId) {
- // Non root copy request.
- bool include_viewport_clip = false;
- bool include_expanding_clips = true;
- ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip(
- property_trees, include_viewport_clip, include_expanding_clips,
- layer->clip_tree_index(), effect_ancestor_with_copy_request);
- if (!accumulated_clip_rect.is_clipped) {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- continue;
- }
-
- gfx::RectF accumulated_clip_in_copy_request_space =
- accumulated_clip_rect.clip_rect;
-
- const EffectNode* copy_request_effect_node =
- effect_tree.Node(effect_ancestor_with_copy_request);
- ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace(
- accumulated_clip_in_copy_request_space, property_trees,
- copy_request_effect_node->transform_id, layer->transform_tree_index(),
- copy_request_effect_node->id);
-
- if (clip_in_layer_space.is_clipped) {
- gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
- clip_rect.Offset(-layer->offset_to_transform_parent());
- gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
- visible_rect.Intersect(gfx::Rect(layer_bounds));
- layer->set_visible_layer_rect(visible_rect);
- } else {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- }
- continue;
- }
-
- const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
- const TransformNode* transform_node =
- transform_tree.Node(layer->transform_tree_index());
- if (!non_root_surfaces_enabled) {
- // When we only have a root surface, the clip node and the layer must
- // necessarily have the same target (the root).
- if (transform_node->ancestors_are_invertible) {
- gfx::RectF combined_clip_rect_in_target_space =
- clip_node->combined_clip_in_target_space;
- gfx::Transform target_to_content;
- target_to_content.Translate(-layer->offset_to_transform_parent().x(),
- -layer->offset_to_transform_parent().y());
- target_to_content.PreconcatTransform(
- transform_tree.FromScreen(transform_node->id));
-
- gfx::Rect visible_rect =
- gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
- target_to_content, combined_clip_rect_in_target_space));
- visible_rect.Intersect(gfx::Rect(layer_bounds));
- layer->set_visible_layer_rect(visible_rect);
- } else {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- }
- continue;
- }
-
- // When both the layer and the target are unclipped, we only have to apply
- // the viewport clip.
- const bool fully_visible =
- !clip_node->layers_are_clipped &&
- !effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped;
-
- if (fully_visible) {
- if (!transform_node->ancestors_are_invertible) {
- // An animated singular transform may become non-singular during the
- // animation, so we still need to compute a visible rect. In this
- // situation, we treat the entire layer as visible.
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- } else {
- gfx::Transform from_screen;
- from_screen.Translate(-layer->offset_to_transform_parent().x(),
- -layer->offset_to_transform_parent().y());
- from_screen.PreconcatTransform(
- property_trees->transform_tree.FromScreen(transform_node->id));
- gfx::Rect visible_rect =
- gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
- from_screen, property_trees->clip_tree.ViewportClip()));
- visible_rect.Intersect(gfx::Rect(layer_bounds));
- layer->set_visible_layer_rect(visible_rect);
- }
- continue;
- }
-
- int target_node_id = transform_tree.ContentTargetId(transform_node->id);
-
- // The clip node stores clip rect in its target space. If required,
- // this clip rect should be mapped to the current layer's target space.
- gfx::RectF combined_clip_rect_in_target_space;
- if (clip_node->target_transform_id != target_node_id) {
- // In this case, layer has a clip parent or scroll parent (or shares the
- // target with an ancestor layer that has clip parent) and the clip
- // parent's target is different from the layer's target. As the layer's
- // target has unclippped descendants, it is unclippped.
- if (!clip_node->layers_are_clipped) {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- continue;
- }
-
- bool for_visible_rect_calculation = true;
- if (!ComputeClipRectInTargetSpace(layer, clip_node, property_trees,
- target_node_id,
- for_visible_rect_calculation,
- &combined_clip_rect_in_target_space)) {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- continue;
- }
- } else {
- combined_clip_rect_in_target_space =
- clip_node->combined_clip_in_target_space;
- }
-
- // The clip rect should be intersected with layer rect in target space.
- gfx::Transform content_to_target;
- property_trees->GetToTarget(transform_node->id,
- layer->render_target_effect_tree_index(),
- &content_to_target);
- content_to_target.Translate(layer->offset_to_transform_parent().x(),
- layer->offset_to_transform_parent().y());
- gfx::Rect layer_content_rect = gfx::Rect(layer_bounds);
- gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect(
- content_to_target, gfx::RectF(layer_content_rect));
- // If the layer is fully contained within the clip, treat it as fully
- // visible.
- if (!layer_content_bounds_in_target_space.IsEmpty() &&
- combined_clip_rect_in_target_space.Contains(
- layer_content_bounds_in_target_space)) {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- continue;
- }
-
- combined_clip_rect_in_target_space.Intersect(
- layer_content_bounds_in_target_space);
- if (combined_clip_rect_in_target_space.IsEmpty()) {
- layer->set_visible_layer_rect(gfx::Rect());
- continue;
- }
-
- gfx::Transform target_to_layer;
- const EffectNode* target_effect_node =
- ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree);
- bool success = property_trees->GetFromTarget(
- transform_node->id, target_effect_node->id, &target_to_layer);
+ // Apply remaining clips
+ while (parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ bool success = ApplyClipNodeToAccumulatedClip(
+ property_trees, include_expanding_clips, target_id, target_transform_id,
+ clip_node, &accumulated_clip);
if (!success) {
- // An animated singular transform may become non-singular during the
- // animation, so we still need to compute a visible rect. In this
- // situation, we treat the entire layer as visible.
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
- continue;
+ // Singular transform
+ cached_data->clip = unclipped;
+ return unclipped;
}
- gfx::Transform target_to_content;
- target_to_content.Translate(-layer->offset_to_transform_parent().x(),
- -layer->offset_to_transform_parent().y());
- target_to_content.PreconcatTransform(target_to_layer);
-
- gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
- target_to_content, combined_clip_rect_in_target_space));
- visible_rect.Intersect(gfx::Rect(layer_bounds));
- layer->set_visible_layer_rect(visible_rect);
}
+
+ ConditionalClip clip = ConditionalClip{
+ true /* is_clipped */,
+ accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip};
+ cached_data->clip = clip;
+ return clip;
}
static bool HasSingularTransform(int transform_tree_index,
@@ -570,6 +321,36 @@ static bool HasSingularTransform(int transform_tree_index,
return !node->is_invertible || !node->ancestors_are_invertible;
}
+static int LowestCommonAncestor(int clip_id_1,
+ int clip_id_2,
+ const ClipTree* clip_tree) {
+ const ClipNode* clip_node_1 = clip_tree->Node(clip_id_1);
+ const ClipNode* clip_node_2 = clip_tree->Node(clip_id_2);
+ while (clip_node_1->id != clip_node_2->id) {
+ if (clip_node_1->id < clip_node_2->id)
+ clip_node_2 = clip_tree->parent(clip_node_2);
+ else
+ clip_node_1 = clip_tree->parent(clip_node_1);
+ }
+ return clip_node_1->id;
+}
+
+static void SetHasContributingLayerThatEscapesClip(int lca_clip_id,
+ int target_effect_id,
+ EffectTree* effect_tree) {
+ const EffectNode* effect_node = effect_tree->Node(target_effect_id);
+ // Find all ancestor targets starting from effect_node who are clipped by
+ // a descendant of lowest ancestor clip and set their
+ // has_contributing_layer_that_escapes_clip to true.
+ while (effect_node->clip_id > lca_clip_id) {
+ RenderSurfaceImpl* render_surface =
+ effect_tree->GetRenderSurface(effect_node->id);
+ DCHECK(render_surface);
+ render_surface->set_has_contributing_layer_that_escapes_clip(true);
+ effect_node = effect_tree->Node(effect_node->target_id);
+ }
+}
+
template <typename LayerType>
static int TransformTreeIndexForBackfaceVisibility(LayerType* layer,
const TransformTree& tree) {
@@ -668,27 +449,6 @@ static bool LayerNeedsUpdateInternal(LayerType* layer,
return true;
}
-void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
- const PropertyTrees* property_trees,
- std::vector<LayerImpl*>* visible_layer_list) {
- const TransformTree& transform_tree = property_trees->transform_tree;
- const EffectTree& effect_tree = property_trees->effect_tree;
-
- for (auto* layer_impl : *layer_tree_impl) {
- if (!IsRootLayer(layer_impl) &&
- LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree))
- continue;
-
- bool layer_is_drawn =
- effect_tree.Node(layer_impl->effect_tree_index())->is_drawn;
-
- if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees))
- visible_layer_list->push_back(layer_impl);
- }
-}
-
-} // namespace
-
template <typename LayerType>
static inline bool LayerShouldBeSkippedInternal(
LayerType* layer,
@@ -701,6 +461,7 @@ static inline bool LayerShouldBeSkippedInternal(
if (effect_node->has_render_surface &&
effect_node->num_copy_requests_in_subtree > 0)
return false;
+
// If the layer transform is not invertible, it should be skipped.
// TODO(ajuma): Correctly process subtrees with singular transform for the
// case where we may animate to a non-singular transform and wish to
@@ -709,6 +470,345 @@ static inline bool LayerShouldBeSkippedInternal(
effect_node->hidden_by_backface_visibility || !effect_node->is_drawn;
}
+template <typename LayerType>
+static void UpdateElasticOverscrollInternal(
+ PropertyTrees* property_trees,
+ const LayerType* overscroll_elasticity_layer,
+ const gfx::Vector2dF& elastic_overscroll) {
+ if (!overscroll_elasticity_layer) {
+ DCHECK(elastic_overscroll.IsZero());
+ return;
+ }
+
+ TransformNode* node = property_trees->transform_tree.Node(
+ overscroll_elasticity_layer->transform_tree_index());
+ DCHECK(node);
+
+ // TODO(pdr): This is a workaround for https://crbug.com/721772 to avoid
+ // crashing when there's no transform node. This workaround should be removed.
+ if (!node)
+ return;
+
+ if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll))
+ return;
+
+ node->scroll_offset = gfx::ScrollOffset(elastic_overscroll);
+ node->needs_local_transform_update = true;
+ property_trees->transform_tree.set_needs_update(true);
+}
+
+#if DCHECK_IS_ON()
+static void ValidatePageScaleLayer(const Layer* page_scale_layer) {
+ DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString());
+ DCHECK_EQ(page_scale_layer->transform_origin().ToString(),
+ gfx::Point3F().ToString());
+}
+
+static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {}
+#endif
+
+template <typename LayerType>
+static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees,
+ const LayerType* page_scale_layer,
+ float page_scale_factor,
+ float device_scale_factor,
+ gfx::Transform device_transform) {
+ if (property_trees->transform_tree.page_scale_factor() == page_scale_factor)
+ return;
+
+ property_trees->transform_tree.set_page_scale_factor(page_scale_factor);
+ DCHECK(page_scale_layer);
+ DCHECK_GE(page_scale_layer->transform_tree_index(),
+ TransformTree::kRootNodeId);
+ TransformNode* node = property_trees->transform_tree.Node(
+ page_scale_layer->transform_tree_index());
+// TODO(enne): property trees can't ask the layer these things, but
+// the page scale layer should *just* be the page scale.
+#if DCHECK_IS_ON()
+ ValidatePageScaleLayer(page_scale_layer);
+#endif
+
+ if (IsRootLayer(page_scale_layer)) {
+ // When the page scale layer is also the root layer, the node should also
+ // store the combined scale factor and not just the page scale factor.
+ float post_local_scale_factor = page_scale_factor * device_scale_factor;
+ node->post_local_scale_factor = post_local_scale_factor;
+ node->post_local = device_transform;
+ node->post_local.Scale(post_local_scale_factor, post_local_scale_factor);
+ } else {
+ node->post_local_scale_factor = page_scale_factor;
+ node->update_post_local_transform(gfx::PointF(), gfx::Point3F());
+ }
+ node->needs_local_transform_update = true;
+ property_trees->transform_tree.set_needs_update(true);
+}
+
+static gfx::Rect LayerDrawableContentRect(
+ const LayerImpl* layer,
+ const gfx::Rect& layer_bounds_in_target_space,
+ const gfx::Rect& clip_rect) {
+ if (layer->is_clipped())
+ return IntersectRects(layer_bounds_in_target_space, clip_rect);
+
+ return layer_bounds_in_target_space;
+}
+
+static void SetSurfaceIsClipped(const ClipTree& clip_tree,
+ RenderSurfaceImpl* render_surface) {
+ bool is_clipped;
+ if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) {
+ // Root render surface is always clipped.
+ is_clipped = true;
+ } else if (render_surface->has_contributing_layer_that_escapes_clip()) {
+ // We cannot clip a surface that has a contribuitng layer which escapes the
+ // clip.
+ is_clipped = false;
+ } else if (render_surface->ClipTreeIndex() ==
+ render_surface->render_target()->ClipTreeIndex()) {
+ // There is no clip between between the render surface and its target, so
+ // the surface need not be clipped.
+ is_clipped = false;
+ } else {
+ // If the clips between the render surface and its target only expand the
+ // clips and do not apply any new clip, we need not clip the render surface.
+ const ClipNode* clip_node = clip_tree.Node(render_surface->ClipTreeIndex());
+ is_clipped = clip_node->clip_type != ClipNode::ClipType::EXPANDS_CLIP;
+ }
+ render_surface->SetIsClipped(is_clipped);
+}
+
+static void SetSurfaceDrawOpacity(const EffectTree& tree,
+ RenderSurfaceImpl* render_surface) {
+ // Draw opacity of a surface is the product of opacities between the surface
+ // (included) and its target surface (excluded).
+ const EffectNode* node = tree.Node(render_surface->EffectTreeIndex());
+ float draw_opacity = tree.EffectiveOpacity(node);
+ for (node = tree.parent(node); node && !node->has_render_surface;
+ node = tree.parent(node)) {
+ draw_opacity *= tree.EffectiveOpacity(node);
+ }
+ render_surface->SetDrawOpacity(draw_opacity);
+}
+
+static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) {
+ if (!layer->render_target())
+ return 0.f;
+
+ const EffectNode* target_node =
+ tree.Node(layer->render_target()->EffectTreeIndex());
+ const EffectNode* node = tree.Node(layer->effect_tree_index());
+ if (node == target_node)
+ return 1.f;
+
+ float draw_opacity = 1.f;
+ while (node != target_node) {
+ draw_opacity *= tree.EffectiveOpacity(node);
+ node = tree.parent(node);
+ }
+ return draw_opacity;
+}
+
+template <typename LayerType>
+static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer,
+ const TransformTree& tree) {
+ gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(),
+ layer->offset_to_transform_parent().y());
+ gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index());
+ xform.ConcatTransform(ssxform);
+ if (layer->should_flatten_transform_from_property_tree())
+ xform.FlattenTo2d();
+ return xform;
+}
+
+static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
+ PropertyTrees* property_trees,
+ RenderSurfaceImpl* render_surface) {
+ if (!render_surface->is_clipped()) {
+ render_surface->SetClipRect(gfx::Rect());
+ return;
+ }
+
+ const EffectTree& effect_tree = property_trees->effect_tree;
+ const ClipTree& clip_tree = property_trees->clip_tree;
+ const EffectNode* effect_node =
+ effect_tree.Node(render_surface->EffectTreeIndex());
+ const EffectNode* target_node = effect_tree.Node(effect_node->target_id);
+ bool include_expanding_clips = false;
+ if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) {
+ render_surface->SetClipRect(
+ gfx::ToEnclosingRect(clip_tree.Node(effect_node->clip_id)->clip));
+ } else {
+ ConditionalClip accumulated_clip_rect =
+ ComputeAccumulatedClip(property_trees, include_expanding_clips,
+ effect_node->clip_id, target_node->id);
+ render_surface->SetClipRect(
+ gfx::ToEnclosingRect(accumulated_clip_rect.clip_rect));
+ }
+}
+
+static void SetSurfaceDrawTransform(const PropertyTrees* property_trees,
+ RenderSurfaceImpl* render_surface) {
+ const TransformTree& transform_tree = property_trees->transform_tree;
+ const EffectTree& effect_tree = property_trees->effect_tree;
+ const TransformNode* transform_node =
+ transform_tree.Node(render_surface->TransformTreeIndex());
+ const EffectNode* effect_node =
+ effect_tree.Node(render_surface->EffectTreeIndex());
+ // The draw transform of root render surface is identity tranform.
+ if (transform_node->id == TransformTree::kRootNodeId) {
+ render_surface->SetDrawTransform(gfx::Transform());
+ return;
+ }
+
+ gfx::Transform render_surface_transform;
+ const EffectNode* target_effect_node =
+ effect_tree.Node(effect_node->target_id);
+ property_trees->GetToTarget(transform_node->id, target_effect_node->id,
+ &render_surface_transform);
+
+ ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform);
+ render_surface->SetDrawTransform(render_surface_transform);
+}
+
+static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees,
+ LayerImpl* layer) {
+ int effect_ancestor_with_copy_request =
+ property_trees->effect_tree.ClosestAncestorWithCopyRequest(
+ layer->effect_tree_index());
+ bool non_root_copy_request =
+ effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId;
+ gfx::Rect layer_content_rect = gfx::Rect(layer->bounds());
+ gfx::RectF accumulated_clip_in_root_space;
+ if (non_root_copy_request) {
+ bool include_expanding_clips = true;
+ ConditionalClip accumulated_clip = ComputeAccumulatedClip(
+ property_trees, include_expanding_clips, layer->clip_tree_index(),
+ effect_ancestor_with_copy_request);
+ if (!accumulated_clip.is_clipped)
+ return layer_content_rect;
+ accumulated_clip_in_root_space = accumulated_clip.clip_rect;
+ } else {
+ const ClipNode* clip_node =
+ property_trees->clip_tree.Node(layer->clip_tree_index());
+ accumulated_clip_in_root_space =
+ clip_node->cached_accumulated_rect_in_screen_space;
+ }
+
+ const EffectNode* root_effect_node =
+ non_root_copy_request
+ ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request)
+ : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId);
+ ConditionalClip accumulated_clip_in_layer_space =
+ ComputeTargetRectInLocalSpace(
+ accumulated_clip_in_root_space, property_trees,
+ root_effect_node->transform_id, layer->transform_tree_index(),
+ root_effect_node->id);
+ if (!accumulated_clip_in_layer_space.is_clipped) {
+ return layer_content_rect;
+ }
+ gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect;
+ clip_in_layer_space.Offset(-layer->offset_to_transform_parent());
+
+ gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space);
+ visible_rect.Intersect(layer_content_rect);
+ return visible_rect;
+}
+
+static ConditionalClip LayerClipRect(PropertyTrees* property_trees,
+ LayerImpl* layer) {
+ const EffectTree* effect_tree = &property_trees->effect_tree;
+ const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index());
+ const EffectNode* target_node =
+ effect_node->has_render_surface
+ ? effect_node
+ : effect_tree->Node(effect_node->target_id);
+ // TODO(weiliangc): When effect node has up to date render surface info on
+ // compositor thread, no need to check for resourceless draw mode
+ if (!property_trees->non_root_surfaces_enabled) {
+ target_node = effect_tree->Node(1);
+ }
+
+ bool include_expanding_clips = false;
+ return ComputeAccumulatedClip(property_trees, include_expanding_clips,
+ layer->clip_tree_index(), target_node->id);
+}
+
+static void UpdateRenderTarget(EffectTree* effect_tree,
+ bool can_render_to_separate_surface) {
+ for (int i = EffectTree::kContentsRootNodeId;
+ i < static_cast<int>(effect_tree->size()); ++i) {
+ EffectNode* node = effect_tree->Node(i);
+ if (i == EffectTree::kContentsRootNodeId) {
+ // Render target of the node corresponding to root is itself.
+ node->target_id = EffectTree::kContentsRootNodeId;
+ } else if (!can_render_to_separate_surface) {
+ node->target_id = EffectTree::kContentsRootNodeId;
+ } else if (effect_tree->parent(node)->has_render_surface) {
+ node->target_id = node->parent_id;
+ } else {
+ node->target_id = effect_tree->parent(node)->target_id;
+ }
+ }
+}
+
+static void UpdateScrollTree(ScrollTree* scroll_tree,
+ const LayerTreeHost* layer_tree_host) {
+ if (!scroll_tree->needs_update())
+ return;
+
+ for (int i = ScrollTree::kRootNodeId;
+ i < static_cast<int>(scroll_tree->size()); ++i) {
+ ScrollNode* scroll_node = scroll_tree->Node(i);
+ if (Layer* scroll_layer =
+ layer_tree_host->LayerById(scroll_node->owning_layer_id)) {
+ if (Layer* scroll_clip_layer = scroll_layer->scroll_clip_layer()) {
+ scroll_node->scroll_clip_layer_bounds = scroll_clip_layer->bounds();
+ }
+ }
+ }
+}
+
+static void ComputeClips(PropertyTrees* property_trees) {
+ DCHECK(!property_trees->transform_tree.needs_update());
+ ClipTree* clip_tree = &property_trees->clip_tree;
+ if (!clip_tree->needs_update())
+ return;
+ const int target_effect_id = EffectTree::kContentsRootNodeId;
+ const int target_transform_id = TransformTree::kRootNodeId;
+ const bool include_expanding_clips = true;
+ for (int i = ClipTree::kViewportNodeId;
+ i < static_cast<int>(clip_tree->size()); ++i) {
+ ClipNode* clip_node = clip_tree->Node(i);
+ // Clear the clip rect cache
+ clip_node->cached_clip_rects = std::vector<ClipRectData>(1);
+ if (clip_node->id == ClipTree::kViewportNodeId) {
+ clip_node->cached_accumulated_rect_in_screen_space = clip_node->clip;
+ continue;
+ }
+ ClipNode* parent_clip_node = clip_tree->parent(clip_node);
+ DCHECK(parent_clip_node);
+ gfx::RectF accumulated_clip =
+ parent_clip_node->cached_accumulated_rect_in_screen_space;
+ bool success = ApplyClipNodeToAccumulatedClip(
+ property_trees, include_expanding_clips, target_effect_id,
+ target_transform_id, clip_node, &accumulated_clip);
+ DCHECK(success);
+ clip_node->cached_accumulated_rect_in_screen_space = accumulated_clip;
+ }
+ clip_tree->set_needs_update(false);
+}
+
+} // namespace
+
+void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
+ gfx::Transform* transform) {
+ DCHECK(effect_node->has_render_surface);
+ if (effect_node->surface_contents_scale.x() != 0.0 &&
+ effect_node->surface_contents_scale.y() != 0.0)
+ transform->Scale(1.0 / effect_node->surface_contents_scale.x(),
+ 1.0 / effect_node->surface_contents_scale.y());
+}
+
bool LayerShouldBeSkipped(LayerImpl* layer,
const TransformTree& transform_tree,
const EffectTree& effect_tree) {
@@ -745,184 +845,31 @@ void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
}
}
-static void ResetIfHasNanCoordinate(gfx::RectF* rect) {
- if (std::isnan(rect->x()) || std::isnan(rect->y()) ||
- std::isnan(rect->right()) || std::isnan(rect->bottom()))
- *rect = gfx::RectF();
-}
-
-void PostConcatSurfaceContentsScale(const EffectNode* effect_node,
- gfx::Transform* transform) {
- if (!effect_node) {
- // This can happen when PaintArtifactCompositor builds property trees as it
- // doesn't set effect ids on clip nodes.
- return;
- }
- DCHECK(effect_node->has_render_surface);
- transform->matrix().postScale(effect_node->surface_contents_scale.x(),
- effect_node->surface_contents_scale.y(), 1.f);
-}
-
-void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
- gfx::Transform* transform) {
- DCHECK(effect_node->has_render_surface);
- if (effect_node->surface_contents_scale.x() != 0.0 &&
- effect_node->surface_contents_scale.y() != 0.0)
- transform->Scale(1.0 / effect_node->surface_contents_scale.x(),
- 1.0 / effect_node->surface_contents_scale.y());
-}
-
-void ComputeClips(PropertyTrees* property_trees,
- bool non_root_surfaces_enabled) {
- ClipTree* clip_tree = &property_trees->clip_tree;
- if (!clip_tree->needs_update())
- return;
- for (int i = ClipTree::kViewportNodeId;
- i < static_cast<int>(clip_tree->size()); ++i) {
- ClipNode* clip_node = clip_tree->Node(i);
+void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
+ const PropertyTrees* property_trees,
+ std::vector<LayerImpl*>* visible_layer_list) {
+ const TransformTree& transform_tree = property_trees->transform_tree;
+ const EffectTree& effect_tree = property_trees->effect_tree;
- if (clip_node->id == ClipTree::kViewportNodeId) {
- ResetIfHasNanCoordinate(&clip_node->clip);
- clip_node->clip_in_target_space = clip_node->clip;
- clip_node->combined_clip_in_target_space = clip_node->clip;
+ for (auto* layer_impl : *layer_tree_impl) {
+ DCHECK(layer_impl);
+ DCHECK(layer_impl->layer_tree_impl());
+ // TODO(crbug.com/726423) : This is a workaround for crbug.com/725851 to
+ // avoid crashing when layer_impl is nullptr. This workaround should be
+ // removed as layer_impl should not be nullptr here.
+ if (!layer_impl || !layer_impl->HasValidPropertyTreeIndices())
continue;
- }
- const TransformTree& transform_tree = property_trees->transform_tree;
- const EffectTree& effect_tree = property_trees->effect_tree;
- const TransformNode* transform_node =
- transform_tree.Node(clip_node->transform_id);
- ClipNode* parent_clip_node = clip_tree->parent(clip_node);
- bool target_is_clipped =
- effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped;
-
- gfx::Transform parent_to_current;
- const TransformNode* parent_target_transform_node =
- transform_tree.Node(parent_clip_node->target_transform_id);
- bool success = true;
-
- // Clips must be combined in target space. We cannot, for example, combine
- // clips in the space of the child clip. The reason is non-affine
- // transforms. Say we have the following tree T->A->B->C, and B clips C, but
- // draw into target T. It may be the case that A applies a perspective
- // transform, and B and C are at different z positions. When projected into
- // target space, the relative sizes and positions of B and C can shift.
- // Since it's the relationship in target space that matters, that's where we
- // must combine clips. For each clip node, we save the clip rects in its
- // target space. So, we need to get the ancestor clip rect in the current
- // clip node's target space.
- gfx::RectF parent_combined_clip_in_target_space =
- parent_clip_node->combined_clip_in_target_space;
- gfx::RectF parent_clip_in_target_space =
- parent_clip_node->clip_in_target_space;
- if (parent_target_transform_node &&
- parent_target_transform_node->id != clip_node->target_transform_id &&
- non_root_surfaces_enabled) {
- success &= property_trees->GetFromTarget(
- clip_node->target_transform_id, parent_clip_node->target_effect_id,
- &parent_to_current);
- const EffectNode* target_effect_node =
- effect_tree.Node(clip_node->target_effect_id);
- PostConcatSurfaceContentsScale(target_effect_node, &parent_to_current);
- // If we can't compute a transform, it's because we had to use the inverse
- // of a singular transform. We won't draw in this case, so there's no need
- // to compute clips.
- if (!success)
- continue;
- parent_combined_clip_in_target_space = MathUtil::ProjectClippedRect(
- parent_to_current, parent_clip_node->combined_clip_in_target_space);
- if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) {
- parent_combined_clip_in_target_space =
- gfx::RectF(clip_node->clip_expander->MapRectReverse(
- gfx::ToEnclosingRect(parent_combined_clip_in_target_space),
- property_trees));
- }
- parent_clip_in_target_space = MathUtil::ProjectClippedRect(
- parent_to_current, parent_clip_node->clip_in_target_space);
- }
- // Only nodes affected by ancestor clips will have their clip adjusted due
- // to intersecting with an ancestor clip. But, we still need to propagate
- // the combined clip to our children because if they are clipped, they may
- // need to clip using our parent clip and if we don't propagate it here,
- // it will be lost.
- if (clip_node->resets_clip && non_root_surfaces_enabled) {
- if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
- gfx::Transform to_target;
- property_trees->GetToTarget(clip_node->transform_id,
- clip_node->target_effect_id, &to_target);
- clip_node->clip_in_target_space =
- MathUtil::MapClippedRect(to_target, clip_node->clip);
- ResetIfHasNanCoordinate(&clip_node->clip_in_target_space);
- clip_node->combined_clip_in_target_space =
- gfx::IntersectRects(clip_node->clip_in_target_space,
- parent_combined_clip_in_target_space);
- } else {
- DCHECK(!target_is_clipped);
- DCHECK(!clip_node->layers_are_clipped);
- clip_node->combined_clip_in_target_space =
- parent_combined_clip_in_target_space;
- }
- ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space);
+ if (!IsRootLayer(layer_impl) &&
+ LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree))
continue;
- }
- bool use_only_parent_clip =
- clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP;
- if (use_only_parent_clip) {
- clip_node->combined_clip_in_target_space =
- parent_combined_clip_in_target_space;
- if (!non_root_surfaces_enabled) {
- clip_node->clip_in_target_space =
- parent_clip_node->clip_in_target_space;
- } else if (!target_is_clipped) {
- clip_node->clip_in_target_space = parent_clip_in_target_space;
- } else {
- // Render Surface applies clip and the owning layer itself applies
- // no clip. So, clip_in_target_space is not used and hence we can set
- // it to an empty rect.
- clip_node->clip_in_target_space = gfx::RectF();
- }
- } else {
- gfx::Transform source_to_target;
-
- if (!non_root_surfaces_enabled) {
- source_to_target = transform_tree.ToScreen(clip_node->transform_id);
- } else if (transform_tree.ContentTargetId(transform_node->id) ==
- clip_node->target_transform_id) {
- property_trees->GetToTarget(clip_node->transform_id,
- clip_node->target_effect_id,
- &source_to_target);
- } else {
- success = property_trees->GetToTarget(
- transform_node->id, clip_node->target_effect_id, &source_to_target);
- // source_to_target computation should be successful as target is an
- // ancestor of the transform node.
- DCHECK(success);
- }
- gfx::RectF source_clip_in_target_space =
- MathUtil::MapClippedRect(source_to_target, clip_node->clip);
-
- // With surfaces disabled, the only case where we use only the local clip
- // for layer clipping is the case where no non-viewport ancestor node
- // applies a local clip.
- bool layer_clipping_uses_only_local_clip =
- non_root_surfaces_enabled
- ? clip_node->layer_clipping_uses_only_local_clip
- : !parent_clip_node->layers_are_clipped_when_surfaces_disabled;
- if (!layer_clipping_uses_only_local_clip) {
- clip_node->clip_in_target_space = gfx::IntersectRects(
- parent_clip_in_target_space, source_clip_in_target_space);
- } else {
- clip_node->clip_in_target_space = source_clip_in_target_space;
- }
+ bool layer_is_drawn =
+ effect_tree.Node(layer_impl->effect_tree_index())->is_drawn;
- clip_node->combined_clip_in_target_space = gfx::IntersectRects(
- parent_combined_clip_in_target_space, source_clip_in_target_space);
- }
- ResetIfHasNanCoordinate(&clip_node->clip_in_target_space);
- ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space);
+ if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees))
+ visible_layer_list->push_back(layer_impl);
}
- clip_tree->set_needs_update(false);
}
void ComputeTransforms(TransformTree* transform_tree) {
@@ -934,24 +881,6 @@ void ComputeTransforms(TransformTree* transform_tree) {
transform_tree->set_needs_update(false);
}
-void UpdateRenderTarget(EffectTree* effect_tree,
- bool can_render_to_separate_surface) {
- for (int i = EffectTree::kContentsRootNodeId;
- i < static_cast<int>(effect_tree->size()); ++i) {
- EffectNode* node = effect_tree->Node(i);
- if (i == EffectTree::kContentsRootNodeId) {
- // Render target of the node corresponding to root is itself.
- node->target_id = EffectTree::kContentsRootNodeId;
- } else if (!can_render_to_separate_surface) {
- node->target_id = EffectTree::kContentsRootNodeId;
- } else if (effect_tree->parent(node)->has_render_surface) {
- node->target_id = node->parent_id;
- } else {
- node->target_id = effect_tree->parent(node)->target_id;
- }
- }
-}
-
void ComputeEffects(EffectTree* effect_tree) {
if (!effect_tree->needs_update())
return;
@@ -961,220 +890,62 @@ void ComputeEffects(EffectTree* effect_tree) {
effect_tree->set_needs_update(false);
}
-static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) {
- EffectTree* effect_tree = &property_trees->effect_tree;
- const ClipTree* clip_tree = &property_trees->clip_tree;
- EffectNode* root_effect_node =
- effect_tree->Node(EffectTree::kContentsRootNodeId);
- const RenderSurfaceImpl* root_render_surface =
- effect_tree->GetRenderSurface(EffectTree::kContentsRootNodeId);
- gfx::Rect root_clip =
- gfx::ToEnclosingRect(clip_tree->Node(root_effect_node->clip_id)->clip);
- if (root_render_surface->is_clipped())
- DCHECK(root_clip == root_render_surface->clip_rect())
- << "clip on root render surface: "
- << root_render_surface->clip_rect().ToString()
- << " v.s. root effect node's clip: " << root_clip.ToString();
- for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) {
- EffectNode* effect_node = effect_tree->Node(i);
- const EffectNode* target_node = effect_tree->Node(effect_node->target_id);
- bool include_viewport_clip = false;
- bool include_expanding_clips = false;
- ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip(
- property_trees, include_viewport_clip, include_expanding_clips,
- effect_node->clip_id, target_node->id);
- gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect;
- const RenderSurfaceImpl* render_surface = effect_tree->GetRenderSurface(i);
- if (render_surface && render_surface->is_clipped()) {
- DCHECK(gfx::ToEnclosingRect(accumulated_clip) ==
- render_surface->clip_rect())
- << " render surface's clip rect: "
- << render_surface->clip_rect().ToString()
- << " v.s. accumulated clip: "
- << gfx::ToEnclosingRect(accumulated_clip).ToString();
- }
- }
-}
-
-static void ComputeLayerClipRect(const PropertyTrees* property_trees,
- const LayerImpl* layer) {
- const EffectTree* effect_tree = &property_trees->effect_tree;
- const ClipTree* clip_tree = &property_trees->clip_tree;
- const ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index());
- const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index());
- const EffectNode* target_node =
- effect_node->has_render_surface
- ? effect_node
- : effect_tree->Node(effect_node->target_id);
- // TODO(weiliangc): When effect node has up to date render surface info on
- // compositor thread, no need to check for resourceless draw mode
- if (!property_trees->non_root_surfaces_enabled) {
- target_node = effect_tree->Node(1);
- }
-
- bool include_viewport_clip = false;
- bool include_expanding_clips = false;
- ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip(
- property_trees, include_viewport_clip, include_expanding_clips,
- layer->clip_tree_index(), target_node->id);
-
- bool is_clipped_from_clip_tree =
- property_trees->non_root_surfaces_enabled
- ? clip_node->layers_are_clipped
- : clip_node->layers_are_clipped_when_surfaces_disabled;
- DCHECK_EQ(is_clipped_from_clip_tree, accumulated_clip_rect.is_clipped);
-
- gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect;
-
- DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip))
- << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index()
- << " layer clip: " << layer->clip_rect().ToString() << " v.s. "
- << gfx::ToEnclosingRect(accumulated_clip).ToString()
- << " and clip node clip: "
- << gfx::ToEnclosingRect(clip_node->clip_in_target_space).ToString();
-}
-
-void ComputeVisibleRects(LayerImpl* root_layer,
+void UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
PropertyTrees* property_trees,
- bool can_render_to_separate_surface,
- LayerImplList* visible_layer_list) {
- bool render_surfaces_need_update = false;
+ bool can_render_to_separate_surface) {
+ DCHECK(layer_tree_host);
+ DCHECK(property_trees);
+ DCHECK_EQ(layer_tree_host->property_trees(), property_trees);
if (property_trees->non_root_surfaces_enabled !=
can_render_to_separate_surface) {
property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
property_trees->transform_tree.set_needs_update(true);
- render_surfaces_need_update = true;
}
if (property_trees->transform_tree.needs_update()) {
property_trees->clip_tree.set_needs_update(true);
property_trees->effect_tree.set_needs_update(true);
}
-
- if (render_surfaces_need_update) {
- property_trees->effect_tree.UpdateRenderSurfaces(
- root_layer->layer_tree_impl(),
- property_trees->non_root_surfaces_enabled);
- }
- UpdateRenderTarget(&property_trees->effect_tree,
- property_trees->non_root_surfaces_enabled);
+ UpdateScrollTree(&property_trees->scroll_tree, layer_tree_host);
ComputeTransforms(&property_trees->transform_tree);
- // Computation of clips uses surface contents scale which is updated while
- // computing effects. So, ComputeEffects should be before ComputeClips.
ComputeEffects(&property_trees->effect_tree);
- ComputeClips(property_trees, can_render_to_separate_surface);
-
- FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), property_trees,
- visible_layer_list);
- CalculateClipRects(*visible_layer_list, property_trees,
- can_render_to_separate_surface);
- CalculateVisibleRects(*visible_layer_list, property_trees,
- can_render_to_separate_surface);
+ // Computation of clips uses ToScreen which is updated while computing
+ // transforms. So, ComputeTransforms should be before ComputeClips.
+ ComputeClips(property_trees);
}
-void UpdatePropertyTrees(PropertyTrees* property_trees,
- bool can_render_to_separate_surface) {
+void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
+ PropertyTrees* property_trees,
+ bool can_render_to_separate_surface,
+ bool can_adjust_raster_scales) {
+ bool render_surfaces_need_update = false;
if (property_trees->non_root_surfaces_enabled !=
can_render_to_separate_surface) {
property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
property_trees->transform_tree.set_needs_update(true);
+ render_surfaces_need_update = true;
+ }
+ if (property_trees->can_adjust_raster_scales != can_adjust_raster_scales) {
+ property_trees->can_adjust_raster_scales = can_adjust_raster_scales;
+ property_trees->transform_tree.set_needs_update(true);
+ render_surfaces_need_update = true;
}
if (property_trees->transform_tree.needs_update()) {
property_trees->clip_tree.set_needs_update(true);
property_trees->effect_tree.set_needs_update(true);
}
- ComputeTransforms(&property_trees->transform_tree);
- // Computation of clips uses surface contents scale which is updated while
- // computing effects. So, ComputeEffects should be before ComputeClips.
- ComputeEffects(&property_trees->effect_tree);
- ComputeClips(property_trees, can_render_to_separate_surface);
-}
-
-void BuildPropertyTreesAndComputeVisibleRects(
- LayerImpl* root_layer,
- const LayerImpl* page_scale_layer,
- const LayerImpl* inner_viewport_scroll_layer,
- const LayerImpl* outer_viewport_scroll_layer,
- const LayerImpl* overscroll_elasticity_layer,
- const gfx::Vector2dF& elastic_overscroll,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- bool can_render_to_separate_surface,
- PropertyTrees* property_trees,
- LayerImplList* visible_layer_list) {
- PropertyTreeBuilder::BuildPropertyTrees(
- root_layer, page_scale_layer, inner_viewport_scroll_layer,
- outer_viewport_scroll_layer, overscroll_elasticity_layer,
- elastic_overscroll, page_scale_factor, device_scale_factor, viewport,
- device_transform, property_trees);
- ComputeVisibleRects(root_layer, property_trees,
- can_render_to_separate_surface, visible_layer_list);
-}
-
-void VerifyClipTreeCalculations(const LayerImplList& layer_list,
- PropertyTrees* property_trees) {
- if (property_trees->non_root_surfaces_enabled) {
- ComputeClipsWithEffectTree(property_trees);
- }
- for (auto* layer : layer_list)
- ComputeLayerClipRect(property_trees, layer);
-}
-
-gfx::Rect ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees,
- const LayerImpl* layer) {
- int effect_ancestor_with_copy_request =
- property_trees->effect_tree.ClosestAncestorWithCopyRequest(
- layer->effect_tree_index());
- bool non_root_copy_request =
- effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId;
- gfx::Rect layer_content_rect = gfx::Rect(layer->bounds());
- gfx::RectF accumulated_clip_in_root_space;
- if (non_root_copy_request) {
- bool include_viewport_clip = false;
- bool include_expanding_clips = true;
- ConditionalClip accumulated_clip = ComputeAccumulatedClip(
- property_trees, include_viewport_clip, include_expanding_clips,
- layer->clip_tree_index(), effect_ancestor_with_copy_request);
- if (!accumulated_clip.is_clipped)
- return layer_content_rect;
- accumulated_clip_in_root_space = accumulated_clip.clip_rect;
- } else {
- accumulated_clip_in_root_space =
- ComputeAccumulatedClipInRootSpaceForVisibleRect(
- property_trees, layer->clip_tree_index());
+ if (render_surfaces_need_update) {
+ property_trees->effect_tree.UpdateRenderSurfaces(
+ root_layer->layer_tree_impl(),
+ property_trees->non_root_surfaces_enabled);
}
+ UpdateRenderTarget(&property_trees->effect_tree,
+ property_trees->non_root_surfaces_enabled);
- const EffectNode* root_effect_node =
- non_root_copy_request
- ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request)
- : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId);
- ConditionalClip accumulated_clip_in_layer_space =
- ComputeTargetRectInLocalSpace(
- accumulated_clip_in_root_space, property_trees,
- root_effect_node->transform_id, layer->transform_tree_index(),
- root_effect_node->id);
- if (!accumulated_clip_in_layer_space.is_clipped)
- return layer_content_rect;
- gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect;
- clip_in_layer_space.Offset(-layer->offset_to_transform_parent());
-
- gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space);
- visible_rect.Intersect(layer_content_rect);
- return visible_rect;
-}
-
-void VerifyVisibleRectsCalculations(const LayerImplList& layer_list,
- const PropertyTrees* property_trees) {
- for (auto* layer : layer_list) {
- gfx::Rect visible_rect_dynamic =
- ComputeLayerVisibleRectDynamic(property_trees, layer);
- DCHECK(layer->visible_layer_rect() == visible_rect_dynamic)
- << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index()
- << " visible rect cached: " << layer->visible_layer_rect().ToString()
- << " v.s. "
- << " visible rect dynamic: " << visible_rect_dynamic.ToString();
- }
+ ComputeTransforms(&property_trees->transform_tree);
+ ComputeEffects(&property_trees->effect_tree);
+ // Computation of clips uses ToScreen which is updated while computing
+ // transforms. So, ComputeTransforms should be before ComputeClips.
+ ComputeClips(property_trees);
}
bool LayerNeedsUpdate(Layer* layer,
@@ -1209,88 +980,6 @@ gfx::Transform DrawTransform(const LayerImpl* layer,
return xform;
}
-static void SetSurfaceDrawTransform(const PropertyTrees* property_trees,
- RenderSurfaceImpl* render_surface) {
- const TransformTree& transform_tree = property_trees->transform_tree;
- const EffectTree& effect_tree = property_trees->effect_tree;
- const TransformNode* transform_node =
- transform_tree.Node(render_surface->TransformTreeIndex());
- const EffectNode* effect_node =
- effect_tree.Node(render_surface->EffectTreeIndex());
- // The draw transform of root render surface is identity tranform.
- if (transform_node->id == TransformTree::kRootNodeId) {
- render_surface->SetDrawTransform(gfx::Transform());
- return;
- }
-
- gfx::Transform render_surface_transform;
- const EffectNode* target_effect_node =
- effect_tree.Node(effect_node->target_id);
- property_trees->GetToTarget(transform_node->id, target_effect_node->id,
- &render_surface_transform);
-
- ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform);
- render_surface->SetDrawTransform(render_surface_transform);
-}
-
-static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
- const PropertyTrees* property_trees,
- RenderSurfaceImpl* render_surface) {
- if (!render_surface->is_clipped()) {
- render_surface->SetClipRect(gfx::Rect());
- return;
- }
-
- const EffectTree& effect_tree = property_trees->effect_tree;
- const TransformTree& transform_tree = property_trees->transform_tree;
- const TransformNode* transform_node =
- transform_tree.Node(render_surface->TransformTreeIndex());
- if (transform_tree.TargetId(transform_node->id) ==
- parent_clip_node->target_transform_id) {
- render_surface->SetClipRect(
- gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space));
- return;
- }
-
- // In this case, the clip child has reset the clip node for subtree and hence
- // the parent clip node's clip rect is in clip parent's target space and not
- // our target space. We need to transform it to our target space.
- gfx::Transform clip_parent_target_to_target;
- const EffectNode* effect_node =
- effect_tree.Node(render_surface->EffectTreeIndex());
- int target_effect_id = effect_node->target_id;
- const bool success = property_trees->GetToTarget(
- parent_clip_node->target_transform_id, target_effect_id,
- &clip_parent_target_to_target);
-
- if (!success) {
- render_surface->SetClipRect(gfx::Rect());
- return;
- }
-
- if (parent_clip_node->target_transform_id <
- transform_tree.TargetId(transform_node->id)) {
- render_surface->SetClipRect(gfx::ToEnclosingRect(
- MathUtil::ProjectClippedRect(clip_parent_target_to_target,
- parent_clip_node->clip_in_target_space)));
- } else {
- render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::MapClippedRect(
- clip_parent_target_to_target, parent_clip_node->clip_in_target_space)));
- }
-}
-
-template <typename LayerType>
-static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer,
- const TransformTree& tree) {
- gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(),
- layer->offset_to_transform_parent().y());
- gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index());
- xform.ConcatTransform(ssxform);
- if (layer->should_flatten_transform_from_property_tree())
- xform.FlattenTo2d();
- return xform;
-}
-
gfx::Transform ScreenSpaceTransform(const Layer* layer,
const TransformTree& tree) {
return ScreenSpaceTransformInternal(layer, tree);
@@ -1301,81 +990,68 @@ gfx::Transform ScreenSpaceTransform(const LayerImpl* layer,
return ScreenSpaceTransformInternal(layer, tree);
}
-static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) {
- if (!layer->render_target())
- return 0.f;
-
- const EffectNode* target_node =
- tree.Node(layer->render_target()->EffectTreeIndex());
- const EffectNode* node = tree.Node(layer->effect_tree_index());
- if (node == target_node)
- return 1.f;
-
- float draw_opacity = 1.f;
- while (node != target_node) {
- draw_opacity *= tree.EffectiveOpacity(node);
- node = tree.parent(node);
+void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
+ PropertyTrees* property_trees) {
+ // Compute transforms
+ for (LayerImpl* layer : *layer_list) {
+ const TransformNode* transform_node =
+ property_trees->transform_tree.Node(layer->transform_tree_index());
+
+ layer->draw_properties().screen_space_transform =
+ ScreenSpaceTransformInternal(layer, property_trees->transform_tree);
+ layer->draw_properties().target_space_transform = DrawTransform(
+ layer, property_trees->transform_tree, property_trees->effect_tree);
+ layer->draw_properties().screen_space_transform_is_animating =
+ transform_node->to_screen_is_potentially_animated;
}
- return draw_opacity;
-}
-static void SetSurfaceDrawOpacity(const EffectTree& tree,
- RenderSurfaceImpl* render_surface) {
- // Draw opacity of a surface is the product of opacities between the surface
- // (included) and its target surface (excluded).
- const EffectNode* node = tree.Node(render_surface->EffectTreeIndex());
- float draw_opacity = tree.EffectiveOpacity(node);
- for (node = tree.parent(node); node && !node->has_render_surface;
- node = tree.parent(node)) {
- draw_opacity *= tree.EffectiveOpacity(node);
+ // Compute effects and determine if render surfaces have contributing layers
+ // that escape clip.
+ for (LayerImpl* layer : *layer_list) {
+ layer->draw_properties().opacity =
+ LayerDrawOpacity(layer, property_trees->effect_tree);
+ RenderSurfaceImpl* render_target = layer->render_target();
+ int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(),
+ render_target->ClipTreeIndex(),
+ &property_trees->clip_tree);
+ if (lca_clip_id != render_target->ClipTreeIndex()) {
+ SetHasContributingLayerThatEscapesClip(lca_clip_id,
+ render_target->EffectTreeIndex(),
+ &property_trees->effect_tree);
+ }
}
- render_surface->SetDrawOpacity(draw_opacity);
-}
-static gfx::Rect LayerDrawableContentRect(
- const LayerImpl* layer,
- const gfx::Rect& layer_bounds_in_target_space,
- const gfx::Rect& clip_rect) {
- if (layer->is_clipped())
- return IntersectRects(layer_bounds_in_target_space, clip_rect);
-
- return layer_bounds_in_target_space;
-}
-
-void ComputeLayerDrawProperties(LayerImpl* layer,
- const PropertyTrees* property_trees) {
- const TransformNode* transform_node =
- property_trees->transform_tree.Node(layer->transform_tree_index());
- const ClipNode* clip_node =
- property_trees->clip_tree.Node(layer->clip_tree_index());
-
- layer->draw_properties().screen_space_transform =
- ScreenSpaceTransformInternal(layer, property_trees->transform_tree);
- layer->draw_properties().target_space_transform = DrawTransform(
- layer, property_trees->transform_tree, property_trees->effect_tree);
- layer->draw_properties().screen_space_transform_is_animating =
- transform_node->to_screen_is_potentially_animated;
-
- layer->draw_properties().opacity =
- LayerDrawOpacity(layer, property_trees->effect_tree);
- if (property_trees->non_root_surfaces_enabled) {
- layer->draw_properties().is_clipped = clip_node->layers_are_clipped;
- } else {
- layer->draw_properties().is_clipped =
- clip_node->layers_are_clipped_when_surfaces_disabled;
+ // Compute clips and visible rects
+ for (LayerImpl* layer : *layer_list) {
+ ConditionalClip clip = LayerClipRect(property_trees, layer);
+ // is_clipped should be set before visible rect computation as it is used
+ // there.
+ layer->draw_properties().is_clipped = clip.is_clipped;
+ layer->draw_properties().clip_rect = gfx::ToEnclosingRect(clip.clip_rect);
+ layer->draw_properties().visible_layer_rect =
+ LayerVisibleRect(property_trees, layer);
}
- gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect(
- layer->draw_properties().target_space_transform,
- gfx::Rect(layer->bounds()));
- layer->draw_properties().drawable_content_rect = LayerDrawableContentRect(
- layer, bounds_in_target_space, layer->draw_properties().clip_rect);
+ // Compute drawable content rects
+ for (LayerImpl* layer : *layer_list) {
+ gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect(
+ layer->draw_properties().target_space_transform,
+ gfx::Rect(layer->bounds()));
+ layer->draw_properties().drawable_content_rect = LayerDrawableContentRect(
+ layer, bounds_in_target_space, layer->draw_properties().clip_rect);
+ }
}
void ComputeMaskDrawProperties(LayerImpl* mask_layer,
const PropertyTrees* property_trees) {
// Mask draw properties are used only for rastering, so most of the draw
// properties computed for other layers are not needed.
+ // Draw transform of a mask layer has to be a 2d scale.
+ // TODO(sunxd): the draw transform of a mask layer misses the "scale to fit"
+ // factor from mask layer to its parent. So does the screen space transform.
+ // It does not cause a problem because currently we only have 1:1 mask layer.
+ mask_layer->draw_properties().target_space_transform = DrawTransform(
+ mask_layer, property_trees->transform_tree, property_trees->effect_tree);
mask_layer->draw_properties().screen_space_transform =
ScreenSpaceTransformInternal(mask_layer,
property_trees->transform_tree);
@@ -1383,11 +1059,10 @@ void ComputeMaskDrawProperties(LayerImpl* mask_layer,
gfx::Rect(mask_layer->bounds());
}
-void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees,
- RenderSurfaceImpl* render_surface) {
- const EffectNode* effect_node =
- property_trees->effect_tree.Node(render_surface->EffectTreeIndex());
- render_surface->SetIsClipped(effect_node->surface_is_clipped);
+void ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
+ RenderSurfaceImpl* render_surface,
+ const bool use_layer_lists) {
+ SetSurfaceIsClipped(property_trees->clip_tree, render_surface);
SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface);
SetSurfaceDrawTransform(property_trees, render_surface);
render_surface->SetScreenSpaceTransform(
@@ -1400,52 +1075,6 @@ void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees,
SetSurfaceClipRect(clip_node, property_trees, render_surface);
}
-#if DCHECK_IS_ON()
-static void ValidatePageScaleLayer(const Layer* page_scale_layer) {
- DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString());
- DCHECK_EQ(page_scale_layer->transform_origin().ToString(),
- gfx::Point3F().ToString());
-}
-
-static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {}
-#endif
-
-template <typename LayerType>
-static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees,
- const LayerType* page_scale_layer,
- float page_scale_factor,
- float device_scale_factor,
- gfx::Transform device_transform) {
- if (property_trees->transform_tree.page_scale_factor() == page_scale_factor)
- return;
-
- property_trees->transform_tree.set_page_scale_factor(page_scale_factor);
- DCHECK(page_scale_layer);
- DCHECK_GE(page_scale_layer->transform_tree_index(),
- TransformTree::kRootNodeId);
- TransformNode* node = property_trees->transform_tree.Node(
- page_scale_layer->transform_tree_index());
- // TODO(enne): property trees can't ask the layer these things, but
- // the page scale layer should *just* be the page scale.
-#if DCHECK_IS_ON()
- ValidatePageScaleLayer(page_scale_layer);
-#endif
-
- if (IsRootLayer(page_scale_layer)) {
- // When the page scale layer is also the root layer, the node should also
- // store the combined scale factor and not just the page scale factor.
- float post_local_scale_factor = page_scale_factor * device_scale_factor;
- node->post_local_scale_factor = post_local_scale_factor;
- node->post_local = device_transform;
- node->post_local.Scale(post_local_scale_factor, post_local_scale_factor);
- } else {
- node->post_local_scale_factor = page_scale_factor;
- node->update_post_local_transform(gfx::PointF(), gfx::Point3F());
- }
- node->needs_local_transform_update = true;
- property_trees->transform_tree.set_needs_update(true);
-}
-
void UpdatePageScaleFactor(PropertyTrees* property_trees,
const LayerImpl* page_scale_layer,
float page_scale_factor,
@@ -1466,26 +1095,6 @@ void UpdatePageScaleFactor(PropertyTrees* property_trees,
device_transform);
}
-template <typename LayerType>
-static void UpdateElasticOverscrollInternal(
- PropertyTrees* property_trees,
- const LayerType* overscroll_elasticity_layer,
- const gfx::Vector2dF& elastic_overscroll) {
- if (!overscroll_elasticity_layer) {
- DCHECK(elastic_overscroll.IsZero());
- return;
- }
-
- TransformNode* node = property_trees->transform_tree.Node(
- overscroll_elasticity_layer->transform_tree_index());
- if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll))
- return;
-
- node->scroll_offset = gfx::ScrollOffset(elastic_overscroll);
- node->needs_local_transform_update = true;
- property_trees->transform_tree.set_needs_update(true);
-}
-
void UpdateElasticOverscroll(PropertyTrees* property_trees,
const LayerImpl* overscroll_elasticity_layer,
const gfx::Vector2dF& elastic_overscroll) {
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index 4f19d144f88..b5ff981c579 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -5,11 +5,10 @@
#ifndef CC_TREES_DRAW_PROPERTY_UTILS_H_
#define CC_TREES_DRAW_PROPERTY_UTILS_H_
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/layers/layer_collections.h"
namespace gfx {
-class Rect;
class Transform;
class Vector2dF;
} // namespace gfx
@@ -19,6 +18,7 @@ namespace cc {
class Layer;
class LayerImpl;
class LayerTreeHost;
+class LayerTreeImpl;
class RenderSurfaceImpl;
class EffectTree;
class TransformTree;
@@ -27,15 +27,8 @@ struct EffectNode;
namespace draw_property_utils {
-void CC_EXPORT PostConcatSurfaceContentsScale(const EffectNode* effect_node,
- gfx::Transform* transform);
-
void CC_EXPORT ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
gfx::Transform* transform);
-// Computes combined clips for every node in |clip_tree|. This function requires
-// that |transform_tree| has been updated via |ComputeTransforms|.
-void CC_EXPORT ComputeClips(PropertyTrees* property_trees,
- bool non_root_surfaces_enabled);
// Computes combined (screen space) transforms for every node in the transform
// tree. This must be done prior to calling |ComputeClips|.
@@ -44,48 +37,36 @@ void CC_EXPORT ComputeTransforms(TransformTree* transform_tree);
// Computes screen space opacity for every node in the opacity tree.
void CC_EXPORT ComputeEffects(EffectTree* effect_tree);
-void CC_EXPORT BuildPropertyTreesAndComputeVisibleRects(
- LayerImpl* root_layer,
- const LayerImpl* page_scale_layer,
- const LayerImpl* inner_viewport_scroll_layer,
- const LayerImpl* outer_viewport_scroll_layer,
- const LayerImpl* overscroll_elasticity_layer,
- const gfx::Vector2dF& elastic_overscroll,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- bool can_render_to_separate_surface,
- PropertyTrees* property_trees,
- LayerImplList* visible_layer_list);
-
-void CC_EXPORT UpdatePropertyTrees(PropertyTrees* property_trees,
+
+void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
+ PropertyTrees* property_trees,
bool can_render_to_separate_surface);
+void CC_EXPORT
+UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
+ PropertyTrees* property_trees,
+ bool can_render_to_separate_surface,
+ bool can_adjust_raster_scales);
+
void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
const PropertyTrees* property_trees,
LayerList* update_layer_list);
-void CC_EXPORT ComputeVisibleRects(LayerImpl* root_layer,
- PropertyTrees* property_trees,
- bool can_render_to_separate_surface,
- LayerImplList* visible_layer_list);
-
-gfx::Rect CC_EXPORT
-ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees,
- const LayerImpl* layer);
void CC_EXPORT
-VerifyVisibleRectsCalculations(const LayerImplList& layer_list,
- const PropertyTrees* property_trees);
+FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
+ const PropertyTrees* property_trees,
+ std::vector<LayerImpl*>* visible_layer_list);
-void CC_EXPORT ComputeLayerDrawProperties(LayerImpl* layer,
- const PropertyTrees* property_trees);
+void CC_EXPORT
+ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
+ PropertyTrees* property_trees);
void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer,
const PropertyTrees* property_trees);
-void CC_EXPORT ComputeSurfaceDrawProperties(const PropertyTrees* property_trees,
- RenderSurfaceImpl* render_surface);
+void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
+ RenderSurfaceImpl* render_surface,
+ const bool use_layer_lists);
bool CC_EXPORT LayerShouldBeSkipped(LayerImpl* layer,
const TransformTree& transform_tree,
@@ -99,9 +80,6 @@ bool CC_EXPORT LayerNeedsUpdate(LayerImpl* layer,
bool layer_is_drawn,
const PropertyTrees* property_trees);
-void CC_EXPORT VerifyClipTreeCalculations(const LayerImplList& layer_list,
- PropertyTrees* property_trees);
-
gfx::Transform CC_EXPORT DrawTransform(const LayerImpl* layer,
const TransformTree& transform_tree,
const EffectTree& effect_tree);
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index 5385b35286c..142cb08db41 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -17,7 +17,6 @@ EffectNode::EffectNode()
screen_space_opacity(1.f),
blend_mode(SkBlendMode::kSrcOver),
has_render_surface(false),
- surface_is_clipped(false),
has_copy_request(false),
hidden_by_backface_visibility(false),
double_sided(false),
@@ -29,7 +28,6 @@ EffectNode::EffectNode()
is_currently_animating_opacity(false),
effect_changed(false),
num_copy_requests_in_subtree(0),
- has_unclipped_descendants(false),
transform_id(0),
clip_id(0),
target_id(1),
@@ -42,7 +40,6 @@ bool EffectNode::operator==(const EffectNode& other) const {
owning_layer_id == other.owning_layer_id && opacity == other.opacity &&
screen_space_opacity == other.screen_space_opacity &&
has_render_surface == other.has_render_surface &&
- surface_is_clipped == other.surface_is_clipped &&
has_copy_request == other.has_copy_request &&
filters == other.filters &&
background_filters == other.background_filters &&
@@ -72,7 +69,6 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
value->SetInteger("owning_layer_id", owning_layer_id);
value->SetDouble("opacity", opacity);
value->SetBoolean("has_render_surface", has_render_surface);
- value->SetBoolean("surface_is_clipped", surface_is_clipped);
value->SetBoolean("has_copy_request", has_copy_request);
value->SetBoolean("double_sided", double_sided);
value->SetBoolean("is_drawn", is_drawn);
diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h
index a5a1385de5b..48997c03823 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -5,8 +5,8 @@
#ifndef CC_TREES_EFFECT_NODE_H_
#define CC_TREES_EFFECT_NODE_H_
-#include "cc/base/cc_export.h"
-#include "cc/output/filter_operations.h"
+#include "cc/base/filter_operations.h"
+#include "cc/cc_export.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/size_f.h"
@@ -44,13 +44,6 @@ struct CC_EXPORT EffectNode {
gfx::Size unscaled_mask_target_size;
bool has_render_surface;
- // Only applicable if has render surface. A true value means a clip needs to
- // be applied to the output of the surface when it is drawn onto its parent
- // surface.
- // TODO(crbug.com/504464): There is ongoing work to delay render surface
- // decision to later phase of the pipeline. This flag shall be removed and
- // computed during render surface decision.
- bool surface_is_clipped;
bool has_copy_request;
bool hidden_by_backface_visibility;
bool double_sided;
@@ -66,7 +59,6 @@ struct CC_EXPORT EffectNode {
// rect.
bool effect_changed;
int num_copy_requests_in_subtree;
- bool has_unclipped_descendants;
int transform_id;
int clip_id;
// Effect node id of which this effect contributes to.
diff --git a/chromium/cc/trees/element_id.h b/chromium/cc/trees/element_id.h
index 4c0b652cc88..74de4c9995f 100644
--- a/chromium/cc/trees/element_id.h
+++ b/chromium/cc/trees/element_id.h
@@ -13,7 +13,7 @@
#include <memory>
#include "base/hash.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace base {
class Value;
diff --git a/chromium/cc/trees/frame_rate_counter.cc b/chromium/cc/trees/frame_rate_counter.cc
new file mode 100644
index 00000000000..f801dbf640d
--- /dev/null
+++ b/chromium/cc/trees/frame_rate_counter.cc
@@ -0,0 +1,145 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/frame_rate_counter.h"
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <limits>
+
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+
+namespace cc {
+
+// The following constants are measured in seconds.
+
+// Two thresholds (measured in seconds) that describe what is considered to be a
+// "no-op frame" that should not be counted.
+// - if the frame is too fast, then given our compositor implementation, the
+// frame probably was a no-op and did not draw.
+// - if the frame is too slow, then there is probably not animating content, so
+// we should not pollute the average.
+static const double kFrameTooFast = 1.0 / 70.0;
+static const double kFrameTooSlow = 1.5;
+
+// If a frame takes longer than this threshold (measured in seconds) then we
+// (naively) assume that it missed a screen refresh; that is, we dropped a
+// frame.
+// TODO(brianderson): Determine this threshold based on monitor refresh rate,
+// crbug.com/138642.
+static const double kDroppedFrameTime = 1.0 / 50.0;
+
+// static
+std::unique_ptr<FrameRateCounter> FrameRateCounter::Create(
+ bool has_impl_thread) {
+ return base::WrapUnique(new FrameRateCounter(has_impl_thread));
+}
+
+base::TimeDelta FrameRateCounter::RecentFrameInterval(size_t n) const {
+ DCHECK_GT(n, 0u);
+ DCHECK_LT(n, ring_buffer_.BufferSize());
+ return ring_buffer_.ReadBuffer(n) - ring_buffer_.ReadBuffer(n - 1);
+}
+
+FrameRateCounter::FrameRateCounter(bool has_impl_thread)
+ : has_impl_thread_(has_impl_thread), dropped_frame_count_(0) {}
+
+void FrameRateCounter::SaveTimeStamp(base::TimeTicks timestamp, bool software) {
+ ring_buffer_.SaveToBuffer(timestamp);
+
+ // Check if frame interval can be computed.
+ if (ring_buffer_.CurrentIndex() < 2)
+ return;
+
+ base::TimeDelta frame_interval_seconds =
+ RecentFrameInterval(ring_buffer_.BufferSize() - 1);
+
+ if (has_impl_thread_ && ring_buffer_.CurrentIndex() > 0) {
+ if (software) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Renderer4.SoftwareCompositorThreadImplDrawDelay",
+ frame_interval_seconds.InMilliseconds(), 1, 120, 60);
+ } else {
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay",
+ frame_interval_seconds.InMilliseconds(), 1,
+ 120, 60);
+ }
+ }
+
+ if (!IsBadFrameInterval(frame_interval_seconds) &&
+ frame_interval_seconds.InSecondsF() > kDroppedFrameTime)
+ dropped_frame_count_ +=
+ frame_interval_seconds.InSecondsF() / kDroppedFrameTime;
+}
+
+bool FrameRateCounter::IsBadFrameInterval(
+ base::TimeDelta interval_between_consecutive_frames) const {
+ double delta = interval_between_consecutive_frames.InSecondsF();
+ bool scheduler_allows_double_frames = !has_impl_thread_;
+ bool interval_too_fast =
+ scheduler_allows_double_frames ? delta < kFrameTooFast : delta <= 0.0;
+ bool interval_too_slow = delta > kFrameTooSlow;
+ return interval_too_fast || interval_too_slow;
+}
+
+void FrameRateCounter::GetMinAndMaxFPS(double* min_fps, double* max_fps) const {
+ *min_fps = std::numeric_limits<double>::max();
+ *max_fps = 0.0;
+
+ for (RingBufferType::Iterator it = --ring_buffer_.End(); it; --it) {
+ base::TimeDelta delta = RecentFrameInterval(it.index() + 1);
+
+ if (IsBadFrameInterval(delta))
+ continue;
+
+ DCHECK_GT(delta.InSecondsF(), 0.f);
+ double fps = 1.0 / delta.InSecondsF();
+
+ *min_fps = std::min(fps, *min_fps);
+ *max_fps = std::max(fps, *max_fps);
+ }
+
+ if (*min_fps > *max_fps)
+ *min_fps = *max_fps;
+}
+
+double FrameRateCounter::GetAverageFPS() const {
+ int frame_count = 0;
+ double frame_times_total = 0.0;
+ double average_fps = 0.0;
+
+ // Walk backwards through the samples looking for a run of good frame
+ // timings from which to compute the mean.
+ //
+ // Slow frames occur just because the user is inactive, and should be
+ // ignored. Fast frames are ignored if the scheduler is in single-thread
+ // mode in order to represent the true frame rate in spite of the fact that
+ // the first few swapbuffers happen instantly which skews the statistics
+ // too much for short lived animations.
+ //
+ // IsBadFrameInterval encapsulates the frame too slow/frame too fast logic.
+
+ for (RingBufferType::Iterator it = --ring_buffer_.End();
+ it && frame_times_total < 1.0; --it) {
+ base::TimeDelta delta = RecentFrameInterval(it.index() + 1);
+
+ if (!IsBadFrameInterval(delta)) {
+ frame_count++;
+ frame_times_total += delta.InSecondsF();
+ } else if (frame_count) {
+ break;
+ }
+ }
+
+ if (frame_count) {
+ DCHECK_GT(frame_times_total, 0.0);
+ average_fps = frame_count / frame_times_total;
+ }
+
+ return average_fps;
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/frame_rate_counter.h b/chromium/cc/trees/frame_rate_counter.h
new file mode 100644
index 00000000000..83e8cf7151f
--- /dev/null
+++ b/chromium/cc/trees/frame_rate_counter.h
@@ -0,0 +1,60 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_FRAME_RATE_COUNTER_H_
+#define CC_TREES_FRAME_RATE_COUNTER_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "cc/base/ring_buffer.h"
+
+namespace cc {
+
+// This class maintains a history of timestamps, and provides functionality to
+// intelligently compute average frames per second.
+class FrameRateCounter {
+ public:
+ static std::unique_ptr<FrameRateCounter> Create(bool has_impl_thread);
+
+ size_t current_frame_number() const { return ring_buffer_.CurrentIndex(); }
+ int dropped_frame_count() const { return dropped_frame_count_; }
+ size_t time_stamp_history_size() const { return ring_buffer_.BufferSize(); }
+
+ void SaveTimeStamp(base::TimeTicks timestamp, bool software);
+
+ // n = 0 returns the oldest frame interval retained in the history, while n =
+ // time_stamp_history_size() - 1 returns the most recent frame interval.
+ base::TimeDelta RecentFrameInterval(size_t n) const;
+
+ // This is a heuristic that can be used to ignore frames in a reasonable way.
+ // Returns true if the given frame interval is too fast or too slow, based on
+ // constant thresholds.
+ bool IsBadFrameInterval(
+ base::TimeDelta interval_between_consecutive_frames) const;
+
+ void GetMinAndMaxFPS(double* min_fps, double* max_fps) const;
+ double GetAverageFPS() const;
+
+ typedef RingBuffer<base::TimeTicks, 136> RingBufferType;
+ RingBufferType::Iterator begin() const { return ring_buffer_.Begin(); }
+ RingBufferType::Iterator end() const { return ring_buffer_.End(); }
+
+ private:
+ explicit FrameRateCounter(bool has_impl_thread);
+
+ RingBufferType ring_buffer_;
+
+ bool has_impl_thread_;
+ int dropped_frame_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameRateCounter);
+};
+
+} // namespace cc
+
+#endif // CC_TREES_FRAME_RATE_COUNTER_H_
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 942d5938681..e8a6f4b0c07 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -29,19 +29,18 @@
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
-#include "cc/debug/devtools_instrumentation.h"
-#include "cc/debug/frame_viewer_instrumentation.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/input/layer_selection_bound.h"
#include "cc/input/page_scale_animation.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
-#include "cc/layers/layer_iterator.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/resources/ui_resource_manager.h"
+#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host_client.h"
@@ -161,6 +160,8 @@ void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) {
proxy_ = std::move(proxy);
proxy_->Start();
+ UpdateDeferCommitsInternal();
+
mutator_host_->SetSupportsScrollAnimations(proxy_->SupportsImplScrolling());
}
@@ -315,6 +316,11 @@ void LayerTreeHost::FinishCommitOnImplThread(
sync_tree->SetDeviceScaleFactor(device_scale_factor_);
host_impl->SetDebugState(debug_state_);
+ if (did_navigate_) {
+ did_navigate_ = false;
+ host_impl->ClearImageCacheOnNavigation();
+ }
+
sync_tree->set_ui_resource_request_queue(
ui_resource_manager_->TakeUIResourcesRequests());
@@ -340,6 +346,11 @@ void LayerTreeHost::FinishCommitOnImplThread(
mutator_host_->PushPropertiesTo(host_impl->mutator_host());
}
+ // Transfer image decode requests to the impl thread.
+ for (auto& request : queued_image_decodes_)
+ host_impl->QueueImageDecode(std::move(request.first), request.second);
+ queued_image_decodes_.clear();
+
micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
property_trees_.ResetAllChangeTracking();
}
@@ -349,7 +360,12 @@ void LayerTreeHost::WillCommit() {
client_->WillCommit();
}
-void LayerTreeHost::UpdateHudLayer() {}
+
+void LayerTreeHost::UpdateDeferCommitsInternal() {
+ proxy_->SetDeferCommits(defer_commits_ ||
+ (settings_.enable_surface_synchronization &&
+ !local_surface_id_.is_valid()));
+}
void LayerTreeHost::CommitComplete() {
source_frame_number_++;
@@ -427,7 +443,10 @@ void LayerTreeHost::DidLoseCompositorFrameSink() {
}
void LayerTreeHost::SetDeferCommits(bool defer_commits) {
- proxy_->SetDeferCommits(defer_commits);
+ if (defer_commits_ == defer_commits)
+ return;
+ defer_commits_ = defer_commits;
+ UpdateDeferCommitsInternal();
}
DISABLE_CFI_PERF
@@ -464,9 +483,9 @@ void LayerTreeHost::SetNextCommitWaitsForActivation() {
proxy_->SetNextCommitWaitsForActivation();
}
-void LayerTreeHost::SetNextCommitForcesRedraw() {
+void LayerTreeHost::SetNeedsCommitWithForcedRedraw() {
next_commit_forces_redraw_ = true;
- proxy_->SetNeedsUpdateLayers();
+ proxy_->SetNeedsCommit();
}
void LayerTreeHost::SetAnimationEvents(
@@ -581,7 +600,7 @@ bool LayerTreeHost::UpdateLayers() {
->Add(timer.Elapsed().InMicroseconds());
}
- return result || next_commit_forces_redraw_;
+ return result;
}
void LayerTreeHost::DidCompletePageScaleAnimation() {
@@ -630,7 +649,6 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
"source_frame_number", SourceFrameNumber());
UpdateHudLayer(debug_state_.ShowHudInfo());
- UpdateHudLayer();
Layer* root_scroll =
PropertyTreeBuilder::FindFirstScrollableLayer(root_layer);
@@ -641,6 +659,16 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
if (hud_layer_) {
hud_layer_->PrepareForCalculateDrawProperties(device_viewport_size_,
device_scale_factor_);
+ // The HUD layer is managed outside the layer list sent to LayerTreeHost
+ // and needs to have its property tree state set.
+ if (settings_.use_layer_lists && root_layer_.get()) {
+ hud_layer_->SetTransformTreeIndex(root_layer_->transform_tree_index());
+ hud_layer_->SetEffectTreeIndex(root_layer_->effect_tree_index());
+ hud_layer_->SetClipTreeIndex(root_layer_->clip_tree_index());
+ hud_layer_->SetScrollTreeIndex(root_layer_->scroll_tree_index());
+ hud_layer_->set_property_tree_sequence_number(
+ root_layer_->property_tree_sequence_number());
+ }
}
gfx::Transform identity_transform;
@@ -654,7 +682,6 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
TRACE_EVENT0(
TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
"LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees");
- PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
bool can_render_to_separate_surface = true;
PropertyTrees* property_trees = &property_trees_;
if (!settings_.use_layer_lists) {
@@ -675,7 +702,7 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
TRACE_EVENT_SCOPE_THREAD, "property_trees",
property_trees->AsTracedValue());
}
- draw_property_utils::UpdatePropertyTrees(property_trees,
+ draw_property_utils::UpdatePropertyTrees(this, property_trees,
can_render_to_separate_surface);
draw_property_utils::FindLayersThatNeedUpdates(this, property_trees,
&update_layer_list);
@@ -732,6 +759,16 @@ void LayerTreeHost::ApplyViewportDeltas(ScrollAndScaleSet* info) {
SetNeedsUpdateLayers();
}
+void LayerTreeHost::RecordWheelAndTouchScrollingCount(ScrollAndScaleSet* info) {
+ bool has_scrolled_by_wheel = info->has_scrolled_by_wheel;
+ bool has_scrolled_by_touch = info->has_scrolled_by_touch;
+
+ if (has_scrolled_by_wheel || has_scrolled_by_touch) {
+ client_->RecordWheelAndTouchScrollingCount(has_scrolled_by_wheel,
+ has_scrolled_by_touch);
+ }
+}
+
void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
for (auto& swap_promise : info->swap_promises) {
TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow",
@@ -762,6 +799,8 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
// controls from clamping the layout viewport both on the compositor and
// on the main thread.
ApplyViewportDeltas(info);
+
+ RecordWheelAndTouchScrollingCount(info);
}
const base::WeakPtr<InputHandler>& LayerTreeHost::GetInputHandler()
@@ -839,6 +878,7 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
ResetGpuRasterizationTracking();
SetNeedsFullTreeSync();
+ did_navigate_ = true;
}
void LayerTreeHost::RegisterViewportLayers(
@@ -964,11 +1004,11 @@ void LayerTreeHost::SetPaintedDeviceScaleFactor(
SetNeedsCommit();
}
-void LayerTreeHost::SetDeviceColorSpace(
- const gfx::ColorSpace& device_color_space) {
- if (device_color_space_ == device_color_space)
+void LayerTreeHost::SetRasterColorSpace(
+ const gfx::ColorSpace& raster_color_space) {
+ if (raster_color_space_ == raster_color_space)
return;
- device_color_space_ = device_color_space;
+ raster_color_space_ = raster_color_space;
LayerTreeHostCommon::CallFunctionForEveryLayer(
this, [](Layer* layer) { layer->SetNeedsDisplay(); });
}
@@ -980,6 +1020,14 @@ void LayerTreeHost::SetContentSourceId(uint32_t id) {
SetNeedsCommit();
}
+void LayerTreeHost::SetLocalSurfaceId(const LocalSurfaceId& local_surface_id) {
+ if (local_surface_id_ == local_surface_id)
+ return;
+ local_surface_id_ = local_surface_id;
+ UpdateDeferCommitsInternal();
+ SetNeedsCommit();
+}
+
void LayerTreeHost::RegisterLayer(Layer* layer) {
DCHECK(!LayerById(layer->id()));
DCHECK(!in_paint_layer_contents_);
@@ -1038,10 +1086,6 @@ bool LayerTreeHost::LayerNeedsPushPropertiesForTesting(Layer* layer) const {
layers_that_should_push_properties_.end();
}
-void LayerTreeHost::SetNeedsMetaInfoRecomputation(bool needs_recomputation) {
- needs_meta_info_recomputation_ = needs_recomputation;
-}
-
void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) {
DCHECK(CommitRequested());
page_scale_factor_ = page_scale;
@@ -1070,8 +1114,6 @@ void LayerTreeHost::UpdateHudLayer(bool show_hud_info) {
void LayerTreeHost::SetNeedsFullTreeSync() {
needs_full_tree_sync_ = true;
- needs_meta_info_recomputation_ = true;
-
property_trees_.needs_rebuild = true;
SetNeedsCommit();
}
@@ -1148,10 +1190,12 @@ void LayerTreeHost::PushPropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_);
- tree_impl->SetDeviceColorSpace(device_color_space_);
+ tree_impl->SetRasterColorSpace(raster_color_space_);
tree_impl->set_content_source_id(content_source_id_);
+ tree_impl->set_local_surface_id(local_surface_id_);
+
if (pending_page_scale_animation_) {
tree_impl->SetPendingPageScaleAnimation(
std::move(pending_page_scale_animation_));
@@ -1196,7 +1240,6 @@ void LayerTreeHost::SetElementIdsForTesting() {
}
void LayerTreeHost::BuildPropertyTreesForTesting() {
- PropertyTreeBuilder::PreCalculateMetaInformation(root_layer());
gfx::Transform identity_transform;
PropertyTreeBuilder::BuildPropertyTrees(
root_layer(), page_scale_layer(), inner_viewport_scroll_layer(),
@@ -1235,12 +1278,10 @@ void LayerTreeHost::SetElementOpacityMutated(ElementId element_id,
DCHECK_LE(opacity, 1.f);
layer->OnOpacityAnimated(opacity);
- if (property_trees_.IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
- layer->id())) {
- DCHECK_EQ(layer->effect_tree_index(),
- property_trees_.layer_id_to_effect_node_index[layer->id()]);
- EffectNode* node =
- property_trees_.effect_tree.Node(layer->effect_tree_index());
+ if (EffectNode* node =
+ property_trees_.effect_tree.UpdateNodeFromOwningLayerId(
+ layer->id())) {
+ DCHECK_EQ(layer->effect_tree_index(), node->id);
if (node->opacity == opacity)
return;
@@ -1259,12 +1300,10 @@ void LayerTreeHost::SetElementTransformMutated(
DCHECK(layer);
layer->OnTransformAnimated(transform);
- if (property_trees_.IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
- layer->id())) {
- DCHECK_EQ(layer->transform_tree_index(),
- property_trees_.layer_id_to_transform_node_index[layer->id()]);
- TransformNode* node =
- property_trees_.transform_tree.Node(layer->transform_tree_index());
+ if (TransformNode* node =
+ property_trees_.transform_tree.UpdateNodeFromOwningLayerId(
+ layer->id())) {
+ DCHECK_EQ(layer->transform_tree_index(), node->id);
if (node->local == transform)
return;
@@ -1291,9 +1330,79 @@ void LayerTreeHost::ElementIsAnimatingChanged(
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) {
- Layer* layer = LayerByElementId(element_id);
- if (layer)
- layer->OnIsAnimatingChanged(mask, state);
+ // TODO(weiliangc): Most of the code is duplicated with LayerTeeHostImpl
+ // version of function. Should try to share code.
+ DCHECK_EQ(ElementListType::ACTIVE, list_type);
+
+ for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
+ property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
+ if (!mask.currently_running[property] &&
+ !mask.potentially_animating[property])
+ continue;
+
+ switch (property) {
+ case TargetProperty::TRANSFORM:
+ if (TransformNode* transform_node =
+ property_trees()->transform_tree.FindNodeFromElementId(
+ element_id)) {
+ if (mask.currently_running[property])
+ transform_node->is_currently_animating =
+ state.currently_running[property];
+ if (mask.potentially_animating[property]) {
+ transform_node->has_potential_animation =
+ state.potentially_animating[property];
+ transform_node->has_only_translation_animations =
+ mutator_host()->HasOnlyTranslationTransforms(element_id,
+ list_type);
+ property_trees()->transform_tree.set_needs_update(true);
+ }
+ } else {
+ if (state.currently_running[property] ||
+ state.potentially_animating[property])
+ DCHECK(property_trees()->needs_rebuild)
+ << "Attempting to animate non existent transform node";
+ }
+ break;
+ case TargetProperty::OPACITY:
+ if (EffectNode* effect_node =
+ property_trees()->effect_tree.FindNodeFromElementId(
+ element_id)) {
+ if (mask.currently_running[property])
+ effect_node->is_currently_animating_opacity =
+ state.currently_running[property];
+ if (mask.potentially_animating[property]) {
+ effect_node->has_potential_opacity_animation =
+ state.potentially_animating[property];
+ property_trees()->effect_tree.set_needs_update(true);
+ }
+ } else {
+ if (state.currently_running[property] ||
+ state.potentially_animating[property])
+ DCHECK(property_trees()->needs_rebuild)
+ << "Attempting to animate opacity on non existent effect node";
+ }
+ break;
+ case TargetProperty::FILTER:
+ if (EffectNode* effect_node =
+ property_trees()->effect_tree.FindNodeFromElementId(
+ element_id)) {
+ if (mask.currently_running[property])
+ effect_node->is_currently_animating_filter =
+ state.currently_running[property];
+ if (mask.potentially_animating[property])
+ effect_node->has_potential_filter_animation =
+ state.potentially_animating[property];
+ } else {
+ if (state.currently_running[property] ||
+ state.potentially_animating[property])
+ DCHECK(property_trees()->needs_rebuild)
+ << "Attempting to animate filter on non existent effect node";
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
@@ -1303,6 +1412,14 @@ gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
return layer->ScrollOffsetForAnimation();
}
+void LayerTreeHost::QueueImageDecode(
+ sk_sp<const SkImage> image,
+ const base::Callback<void(bool)>& callback) {
+ TRACE_EVENT0("cc", "LayerTreeHost::QueueImageDecode");
+ queued_image_decodes_.emplace_back(std::move(image), callback);
+ SetNeedsCommit();
+}
+
LayerListIterator<Layer> LayerTreeHost::begin() const {
return LayerListIterator<Layer>(root_layer_.get());
}
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index 9a5deabf7aa..bf5520e2a39 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -20,9 +20,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
-#include "cc/base/cc_export.h"
-#include "cc/debug/micro_benchmark.h"
-#include "cc/debug/micro_benchmark_controller.h"
+#include "cc/benchmarks/micro_benchmark.h"
+#include "cc/benchmarks/micro_benchmark_controller.h"
+#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
#include "cc/input/event_listener_properties.h"
#include "cc/input/input_handler.h"
@@ -45,6 +45,8 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/rect.h"
+class SkImage;
+
namespace cc {
class HeadsUpDisplayLayer;
class Layer;
@@ -191,7 +193,7 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
// Requests a main frame (including layer updates) and ensures that this main
// frame results in a redraw for the complete viewport when producing the
// CompositorFrame.
- void SetNextCommitForcesRedraw();
+ void SetNeedsCommitWithForcedRedraw();
// Input Handling ---------------------------------------------
@@ -312,9 +314,14 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
void SetContentSourceId(uint32_t);
uint32_t content_source_id() const { return content_source_id_; }
- void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
- const gfx::ColorSpace& device_color_space() const {
- return device_color_space_;
+ // If this LayerTreeHost needs a valid LocalSurfaceId then commits will be
+ // deferred until a valid LocalSurfaceId is provided.
+ void SetLocalSurfaceId(const LocalSurfaceId& local_surface_id);
+ const LocalSurfaceId& local_surface_id() const { return local_surface_id_; }
+
+ void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space);
+ const gfx::ColorSpace& raster_color_space() const {
+ return raster_color_space_;
}
// Used externally by blink for setting the PropertyTrees when
@@ -339,12 +346,6 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
std::unordered_set<Layer*>& LayersThatShouldPushProperties();
bool LayerNeedsPushPropertiesForTesting(Layer* layer) const;
- virtual void SetNeedsMetaInfoRecomputation(
- bool needs_meta_info_recomputation);
- bool needs_meta_info_recomputation() const {
- return needs_meta_info_recomputation_;
- }
-
void SetPageScaleFromImplSide(float page_scale);
void SetElasticOverscrollFromImplSide(gfx::Vector2dF elastic_overscroll);
gfx::Vector2dF elastic_overscroll() const { return elastic_overscroll_; }
@@ -457,6 +458,9 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
gfx::ScrollOffset GetScrollOffsetForAnimation(
ElementId element_id) const override;
+ void QueueImageDecode(sk_sp<const SkImage> image,
+ const base::Callback<void(bool)>& callback);
+
protected:
LayerTreeHost(InitParams* params, CompositorMode mode);
@@ -496,15 +500,13 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
enum { kNumFramesToConsiderBeforeGpuRasterization = 60 };
void ApplyViewportDeltas(ScrollAndScaleSet* info);
+ void RecordWheelAndTouchScrollingCount(ScrollAndScaleSet* info);
void ApplyPageScaleDeltaFromImplSide(float page_scale_delta);
void InitializeProxy(std::unique_ptr<Proxy> proxy);
bool DoUpdateLayers(Layer* root_layer);
- void UpdateHudLayer();
-
- bool AnimateLayersRecursive(Layer* current, base::TimeTicks time);
- void CalculateLCDTextMetricsCallback(Layer* layer);
+ void UpdateDeferCommitsInternal();
const CompositorMode compositor_mode_;
@@ -571,9 +573,11 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
float page_scale_factor_ = 1.f;
float min_page_scale_factor_ = 1.f;
float max_page_scale_factor_ = 1.f;
- gfx::ColorSpace device_color_space_;
+ gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
+ LocalSurfaceId local_surface_id_;
+ bool defer_commits_ = false;
SkColor background_color_ = SK_ColorWHITE;
bool has_transparent_background_ = false;
@@ -591,7 +595,6 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
PropertyTrees property_trees_;
bool needs_full_tree_sync_ = true;
- bool needs_meta_info_recomputation_ = true;
gfx::Vector2dF elastic_overscroll_;
@@ -610,6 +613,11 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
MutatorHost* mutator_host_;
+ std::vector<std::pair<sk_sp<const SkImage>, base::Callback<void(bool)>>>
+ queued_image_decodes_;
+
+ bool did_navigate_ = false;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
};
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index c0fcb4bef14..84416d60ef0 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -43,6 +43,9 @@ class LayerTreeHostClient {
const gfx::Vector2dF& elastic_overscroll_delta,
float page_scale,
float top_controls_delta) = 0;
+ virtual void RecordWheelAndTouchScrollingCount(
+ bool has_scrolled_by_wheel,
+ bool has_scrolled_by_touch) = 0;
// Request an CompositorFrameSink from the client. When the client has one it
// should call LayerTreeHost::SetCompositorFrameSink. This will result in
// either DidFailToInitializeCompositorFrameSink or
@@ -55,6 +58,10 @@ class LayerTreeHostClient {
virtual void DidCommitAndDrawFrame() = 0;
virtual void DidReceiveCompositorFrameAck() = 0;
virtual void DidCompletePageScaleAnimation() = 0;
+ // The only time a subframe ever gets its own LayerTree is when the subframe
+ // renders in a different process its ancestors; this returns true in
+ // that case.
+ virtual bool IsForSubframe() = 0;
protected:
virtual ~LayerTreeHostClient() {}
diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc
index 2e4ded747af..8d09c07ec1d 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -14,7 +14,6 @@
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
-#include "cc/layers/layer_iterator.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host.h"
@@ -80,8 +79,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
int max_texture_size,
bool can_render_to_separate_surface,
bool can_adjust_raster_scales,
- bool verify_clip_tree_calculations,
- bool verify_visible_rect_calculations,
+ bool use_layer_lists,
LayerImplList* render_surface_layer_list,
PropertyTrees* property_trees)
: root_layer(root_layer),
@@ -98,8 +96,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
max_texture_size(max_texture_size),
can_render_to_separate_surface(can_render_to_separate_surface),
can_adjust_raster_scales(can_adjust_raster_scales),
- verify_clip_tree_calculations(verify_clip_tree_calculations),
- verify_visible_rect_calculations(verify_visible_rect_calculations),
+ use_layer_lists(use_layer_lists),
render_surface_layer_list(render_surface_layer_list),
property_trees(property_trees) {}
@@ -122,8 +119,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
std::numeric_limits<int>::max() / 2,
true,
false,
- true,
- true,
+ false,
render_surface_layer_list,
GetPropertyTrees(root_layer)) {
DCHECK(root_layer);
@@ -183,8 +179,10 @@ bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==(
}
ScrollAndScaleSet::ScrollAndScaleSet()
- : page_scale_delta(1.f), top_controls_delta(0.f) {
-}
+ : page_scale_delta(1.f),
+ top_controls_delta(0.f),
+ has_scrolled_by_wheel(false),
+ has_scrolled_by_touch(false) {}
ScrollAndScaleSet::~ScrollAndScaleSet() {}
@@ -286,11 +284,23 @@ static void ComputeInitialRenderSurfaceLayerList(
LayerTreeImpl* layer_tree_impl,
PropertyTrees* property_trees,
LayerImplList* render_surface_layer_list,
- bool can_render_to_separate_surface) {
+ bool can_render_to_separate_surface,
+ bool use_layer_lists) {
// Add all non-skipped surfaces to the initial render surface layer list. Add
// all non-skipped layers to the layer list of their target surface, and
// add their content rect to their target surface's accumulated content rect.
for (LayerImpl* layer : *layer_tree_impl) {
+ DCHECK(layer);
+
+ // TODO(crbug.com/726423): LayerImpls should never have invalid PropertyTree
+ // indices.
+ if (!layer)
+ continue;
+
+ layer->set_is_drawn_render_surface_layer_list_member(false);
+ if (!layer->HasValidPropertyTreeIndices())
+ continue;
+
RenderSurfaceImpl* render_surface = layer->GetRenderSurface();
if (render_surface) {
render_surface->ClearLayerLists();
@@ -326,8 +336,8 @@ static void ComputeInitialRenderSurfaceLayerList(
contributes_to_drawn_surface);
}
- draw_property_utils::ComputeSurfaceDrawProperties(property_trees,
- render_surface);
+ draw_property_utils::ComputeSurfaceDrawProperties(
+ property_trees, render_surface, use_layer_lists);
// Ignore occlusion from outside the surface when surface contents need to
// be fully drawn. Layers with copy-request need to be complete. We could
@@ -437,6 +447,7 @@ static void CalculateRenderSurfaceLayerList(
PropertyTrees* property_trees,
LayerImplList* render_surface_layer_list,
const bool can_render_to_separate_surface,
+ const bool use_layer_lists,
const int max_texture_size) {
// This calculates top level Render Surface Layer List, and Layer List for all
// Render Surfaces.
@@ -447,9 +458,9 @@ static void CalculateRenderSurfaceLayerList(
// First compute an RSLL that might include surfaces that later turn out to
// have an empty content rect. After surface content rects are computed,
// produce a final RSLL that omits empty surfaces.
- ComputeInitialRenderSurfaceLayerList(layer_tree_impl, property_trees,
- &initial_render_surface_list,
- can_render_to_separate_surface);
+ ComputeInitialRenderSurfaceLayerList(
+ layer_tree_impl, property_trees, &initial_render_surface_list,
+ can_render_to_separate_surface, use_layer_lists);
ComputeSurfaceContentRects(layer_tree_impl, property_trees,
&initial_render_surface_list, max_texture_size);
ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees,
@@ -477,15 +488,18 @@ void CalculateDrawPropertiesInternal(
"LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
}
- draw_property_utils::BuildPropertyTreesAndComputeVisibleRects(
+ PropertyTreeBuilder::BuildPropertyTrees(
inputs->root_layer, inputs->page_scale_layer,
inputs->inner_viewport_scroll_layer,
inputs->outer_viewport_scroll_layer,
inputs->elastic_overscroll_application_layer,
inputs->elastic_overscroll, inputs->page_scale_factor,
inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size),
- inputs->device_transform, inputs->can_render_to_separate_surface,
- inputs->property_trees, &visible_layer_list);
+ inputs->device_transform, inputs->property_trees);
+ draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
+ inputs->root_layer, inputs->property_trees,
+ inputs->can_render_to_separate_surface,
+ inputs->can_adjust_raster_scales);
// Property trees are normally constructed on the main thread and
// passed to compositor thread. Source to parent updates on them are not
@@ -529,9 +543,10 @@ void CalculateDrawPropertiesInternal(
property_trees->transform_tree.SetRootTransformsAndScales(
inputs->device_scale_factor, page_scale_factor_for_root,
inputs->device_transform, inputs->root_layer->position());
- draw_property_utils::ComputeVisibleRects(
+ draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
inputs->root_layer, inputs->property_trees,
- inputs->can_render_to_separate_surface, &visible_layer_list);
+ inputs->can_render_to_separate_surface,
+ inputs->can_adjust_raster_scales);
break;
}
}
@@ -541,24 +556,18 @@ void CalculateDrawPropertiesInternal(
"LayerTreeHostCommon::CalculateDrawProperties");
}
+ draw_property_utils::FindLayersThatNeedUpdates(
+ inputs->root_layer->layer_tree_impl(), inputs->property_trees,
+ &visible_layer_list);
DCHECK(inputs->can_render_to_separate_surface ==
inputs->property_trees->non_root_surfaces_enabled);
- for (LayerImpl* layer : visible_layer_list) {
- draw_property_utils::ComputeLayerDrawProperties(layer,
- inputs->property_trees);
- }
+ draw_property_utils::ComputeDrawPropertiesOfVisibleLayers(
+ &visible_layer_list, inputs->property_trees);
CalculateRenderSurfaceLayerList(
inputs->root_layer->layer_tree_impl(), inputs->property_trees,
inputs->render_surface_layer_list, inputs->can_render_to_separate_surface,
- inputs->max_texture_size);
-
- if (inputs->verify_clip_tree_calculations)
- draw_property_utils::VerifyClipTreeCalculations(visible_layer_list,
- inputs->property_trees);
- if (inputs->verify_visible_rect_calculations)
- draw_property_utils::VerifyVisibleRectsCalculations(visible_layer_list,
- inputs->property_trees);
+ inputs->use_layer_lists, inputs->max_texture_size);
if (should_measure_property_tree_performance) {
TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
@@ -585,8 +594,9 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
inputs->page_scale_factor, inputs->device_scale_factor,
gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
property_trees);
- draw_property_utils::UpdatePropertyTrees(property_trees,
- can_render_to_separate_surface);
+ draw_property_utils::UpdatePropertyTrees(
+ inputs->root_layer->layer_tree_host(), property_trees,
+ can_render_to_separate_surface);
draw_property_utils::FindLayersThatNeedUpdates(
inputs->root_layer->layer_tree_host(), property_trees,
&update_layer_list);
@@ -641,8 +651,6 @@ void LayerTreeHostCommon::CalculateDrawProperties(
void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
CalcDrawPropsImplInputsForTesting* inputs) {
- PropertyTreeBuilder::PreCalculateMetaInformationForTesting(
- inputs->root_layer);
CalculateDrawPropertiesInternal(inputs, BUILD_PROPERTY_TREES_IF_NEEDED);
}
diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h
index de96d955c5a..dd668caa88e 100644
--- a/chromium/cc/trees/layer_tree_host_common.h
+++ b/chromium/cc/trees/layer_tree_host_common.h
@@ -13,7 +13,7 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_impl.h"
@@ -74,8 +74,7 @@ class CC_EXPORT LayerTreeHostCommon {
int max_texture_size,
bool can_render_to_separate_surface,
bool can_adjust_raster_scales,
- bool verify_clip_tree_calculations,
- bool verify_visible_rect_calculations,
+ bool use_layer_lists,
LayerImplList* render_surface_layer_list,
PropertyTrees* property_trees);
@@ -92,8 +91,7 @@ class CC_EXPORT LayerTreeHostCommon {
int max_texture_size;
bool can_render_to_separate_surface;
bool can_adjust_raster_scales;
- bool verify_clip_tree_calculations;
- bool verify_visible_rect_calculations;
+ bool use_layer_lists;
LayerImplList* render_surface_layer_list;
PropertyTrees* property_trees;
};
@@ -177,6 +175,8 @@ struct CC_EXPORT ScrollAndScaleSet {
float top_controls_delta;
std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars;
std::vector<std::unique_ptr<SwapPromise>> swap_promises;
+ bool has_scrolled_by_wheel;
+ bool has_scrolled_by_touch;
private:
DISALLOW_COPY_AND_ASSIGN(ScrollAndScaleSet);
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index 132872c5a67..89946eea48a 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -14,7 +14,7 @@
#include "base/strings/string_piece.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
-#include "cc/debug/lap_timer.h"
+#include "cc/base/lap_timer.h"
#include "cc/layers/layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -114,9 +114,8 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest {
active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()),
active_tree->OverscrollElasticityLayer(), max_texture_size,
can_render_to_separate_surface,
+ false, // don't use layer lists for perf tests
host_impl->settings().layer_transforms_should_scale_layer_contents,
- false, // do not verify_clip_tree_calculation for perf tests
- false, // do not verify_visible_rect_calculation for perf tests
&update_list, active_tree->property_trees());
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 45782b01bf6..e6f69f6dd99 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -20,10 +20,10 @@
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/content_layer_client.h"
+#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
-#include "cc/layers/layer_iterator.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/layers/texture_layer_impl.h"
#include "cc/output/copy_output_request.h"
@@ -62,7 +62,6 @@ namespace {
class VerifyTreeCalcsLayerTreeSettings : public LayerTreeSettings {
public:
VerifyTreeCalcsLayerTreeSettings() {
- verify_clip_tree_calculations = true;
}
};
@@ -104,8 +103,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
Layer* page_scale_layer,
Layer* inner_viewport_scroll_layer,
Layer* outer_viewport_scroll_layer) {
- PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
-
EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f));
gfx::Size device_viewport_size =
gfx::Size(root_layer->bounds().width() * device_scale_factor,
@@ -124,14 +121,12 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
- void ExecuteCalculateDrawProperties(
- LayerImpl* root_layer,
- float device_scale_factor,
- float page_scale_factor,
- LayerImpl* page_scale_layer,
- LayerImpl* inner_viewport_scroll_layer,
- LayerImpl* outer_viewport_scroll_layer,
- bool skip_verify_visible_rect_calculations = false) {
+ void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
+ float device_scale_factor,
+ float page_scale_factor,
+ LayerImpl* page_scale_layer,
+ LayerImpl* inner_viewport_scroll_layer,
+ LayerImpl* outer_viewport_scroll_layer) {
if (device_scale_factor !=
root_layer->layer_tree_impl()->device_scale_factor())
root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -158,8 +153,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
inputs.can_adjust_raster_scales = true;
- if (skip_verify_visible_rect_calculations)
- inputs.verify_visible_rect_calculations = false;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
@@ -189,8 +182,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(Layer* root_layer) {
DCHECK(root_layer->layer_tree_host());
- PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
-
bool can_render_to_separate_surface = true;
const Layer* page_scale_layer =
@@ -216,26 +207,25 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
outer_viewport_scroll_layer, overscroll_elasticity_layer,
elastic_overscroll, page_scale_factor, device_scale_factor,
gfx::Rect(device_viewport_size), gfx::Transform(), property_trees);
- draw_property_utils::UpdatePropertyTrees(property_trees,
+ draw_property_utils::UpdatePropertyTrees(root_layer->layer_tree_host(),
+ property_trees,
can_render_to_separate_surface);
draw_property_utils::FindLayersThatNeedUpdates(
root_layer->layer_tree_host(), property_trees, &update_layer_list_);
}
void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(
- LayerImpl* root_layer,
- bool skip_verify_visible_rect_calculations = false) {
+ LayerImpl* root_layer) {
DCHECK(root_layer->layer_tree_impl());
- PropertyTreeBuilder::PreCalculateMetaInformationForTesting(root_layer);
-
bool can_render_to_separate_surface = true;
+ bool can_adjust_raster_scales = true;
- LayerImpl* page_scale_layer = nullptr;
+ const LayerImpl* page_scale_layer = nullptr;
LayerImpl* inner_viewport_scroll_layer =
root_layer->layer_tree_impl()->InnerViewportScrollLayer();
LayerImpl* outer_viewport_scroll_layer =
root_layer->layer_tree_impl()->OuterViewportScrollLayer();
- LayerImpl* overscroll_elasticity_layer =
+ const LayerImpl* overscroll_elasticity_layer =
root_layer->layer_tree_impl()->OverscrollElasticityLayer();
gfx::Vector2dF elastic_overscroll =
root_layer->layer_tree_impl()->elastic_overscroll()->Current(
@@ -249,18 +239,19 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
root_layer->layer_tree_impl()->BuildLayerListForTesting();
PropertyTrees* property_trees =
root_layer->layer_tree_impl()->property_trees();
- draw_property_utils::BuildPropertyTreesAndComputeVisibleRects(
+ PropertyTreeBuilder::BuildPropertyTrees(
root_layer, page_scale_layer, inner_viewport_scroll_layer,
outer_viewport_scroll_layer, overscroll_elasticity_layer,
elastic_overscroll, page_scale_factor, device_scale_factor,
- gfx::Rect(device_viewport_size), gfx::Transform(),
- can_render_to_separate_surface, property_trees,
+ gfx::Rect(device_viewport_size), gfx::Transform(), property_trees);
+ draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
+ root_layer, property_trees, can_render_to_separate_surface,
+ can_adjust_raster_scales);
+ draw_property_utils::FindLayersThatNeedUpdates(
+ root_layer->layer_tree_impl(), property_trees,
update_layer_list_impl_.get());
- draw_property_utils::VerifyClipTreeCalculations(*update_layer_list_impl_,
- property_trees);
- if (!skip_verify_visible_rect_calculations)
- draw_property_utils::VerifyVisibleRectsCalculations(
- *update_layer_list_impl_, property_trees);
+ draw_property_utils::ComputeDrawPropertiesOfVisibleLayers(
+ update_layer_list_impl(), property_trees);
}
void ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(
@@ -279,6 +270,22 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
+ void ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales(
+ LayerImpl* root_layer) {
+ gfx::Size device_viewport_size =
+ gfx::Size(root_layer->bounds().width(), root_layer->bounds().height());
+ render_surface_layer_list_impl_.reset(new LayerImplList);
+
+ DCHECK(!root_layer->bounds().IsEmpty());
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root_layer, device_viewport_size,
+ render_surface_layer_list_impl_.get());
+ inputs.can_render_to_separate_surface = true;
+ inputs.can_adjust_raster_scales = false;
+
+ LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
+ }
+
bool UpdateLayerListImplContains(int id) const {
for (auto* layer : *update_layer_list_impl_) {
if (layer->id() == id)
@@ -1125,18 +1132,16 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) {
LayerImpl* page_scale_layer = nullptr;
LayerImpl* inner_viewport_scroll_layer = nullptr;
LayerImpl* outer_viewport_scroll_layer = nullptr;
- // Visible rects computed by combining clips in target space and root space
- // don't match because of rotation transforms. So, we skip
- // verify_visible_rect_calculations.
- bool skip_verify_visible_rect_calculations = true;
ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor,
page_scale_layer, inner_viewport_scroll_layer,
- outer_viewport_scroll_layer,
- skip_verify_visible_rect_calculations);
+ outer_viewport_scroll_layer);
- // Mapping grand_child's bounds to target space produces a non-empty rect
- // that is fully contained within the target's bounds, so grand_child should
- // be considered fully visible.
+ // Mapping grand_child's bounds to screen space produces an empty rect, but
+ // only because it is turned sideways. The entire rect is contained inside
+ // the clip, and is only empty so long as the numerical precision of the
+ // transform is effectively perfect. Currently we do the calculation the
+ // other way around, and the Projection of the screen space clip into layer
+ // space includes the entire bounds.
EXPECT_EQ(gfx::Rect(grand_child->bounds()),
grand_child->visible_layer_rect());
}
@@ -1434,6 +1439,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->test_properties()->background_filters = filters;
child->SetBounds(gfx::Size(10, 10));
child->SetDrawsContent(true);
+ root->layer_tree_impl()->SetElementIdsForTesting();
{
LayerImplList render_surface_layer_list;
@@ -1455,10 +1461,9 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_TRUE(node->is_drawn);
// When root is transparent, the layer should not be drawn.
- effect_tree.OnOpacityAnimated(0.f, root->effect_tree_index(),
- root->layer_tree_impl());
- effect_tree.OnOpacityAnimated(1.f, render_surface1->effect_tree_index(),
- root->layer_tree_impl());
+ root->layer_tree_impl()->SetOpacityMutated(root->element_id(), 0.f);
+ root->layer_tree_impl()->SetOpacityMutated(render_surface1->element_id(),
+ 1.f);
render_surface1->set_visible_layer_rect(gfx::Rect());
{
LayerImplList render_surface_layer_list;
@@ -1575,13 +1580,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) {
ExecuteCalculateDrawProperties(root);
// Since the child layer has a blend mode other than normal, it should get
- // its own render surface. Also, layer's draw_properties should contain the
- // default blend mode, since the render surface becomes responsible for
- // applying the blend mode.
+ // its own render surface.
ASSERT_TRUE(child->GetRenderSurface());
EXPECT_EQ(1.0f, child->draw_opacity());
EXPECT_EQ(0.5f, child->GetRenderSurface()->draw_opacity());
- EXPECT_EQ(SkBlendMode::kSrcOver, child->draw_blend_mode());
+ EXPECT_EQ(SkBlendMode::kMultiply, child->GetRenderSurface()->BlendMode());
}
TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) {
@@ -2552,7 +2555,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
gfx::Point3F(0.25f, 0.f, 0.f);
root->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting();
- SetElementIdsForTesting();
// Put an animated opacity on the render surface.
AddOpacityTransitionToElementWithPlayer(
@@ -2966,6 +2968,21 @@ TEST_F(LayerTreeHostCommonDrawRectsTest,
drawing_layer->drawable_content_rect());
}
+static bool ProjectionClips(const gfx::Transform& map_transform,
+ const gfx::RectF& mapped_rect) {
+ gfx::Transform inverse(Inverse(map_transform));
+ bool clipped = false;
+ if (!clipped)
+ MathUtil::ProjectPoint(inverse, mapped_rect.top_right(), &clipped);
+ if (!clipped)
+ MathUtil::ProjectPoint(inverse, mapped_rect.origin(), &clipped);
+ if (!clipped)
+ MathUtil::ProjectPoint(inverse, mapped_rect.bottom_right(), &clipped);
+ if (!clipped)
+ MathUtil::ProjectPoint(inverse, mapped_rect.bottom_left(), &clipped);
+ return clipped;
+}
+
TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) {
// To determine visible rect in layer space, there needs to be an
// un-projection from surface space to layer space. When the original
@@ -2988,12 +3005,9 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) {
// Sanity check that un-projection does indeed cause w < 0, otherwise this
// code is not testing the intended scenario.
- bool clipped;
gfx::RectF clipped_rect = MathUtil::MapClippedRect(
layer_to_surface_transform, gfx::RectF(layer_content_rect));
- MathUtil::ProjectQuad(
- Inverse(layer_to_surface_transform), gfx::QuadF(clipped_rect), &clipped);
- ASSERT_TRUE(clipped);
+ ASSERT_TRUE(ProjectionClips(layer_to_surface_transform, clipped_rect));
// Only the corner of the layer is not visible on the surface because of being
// clipped. But, the net result of rounding visible region to an axis-aligned
@@ -4011,7 +4025,8 @@ TEST_F(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* clip_parent = AddChildToRoot<LayerImpl>();
- LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* clip_layer = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_layer);
LayerImpl* clip_child = AddChild<LayerImpl>(render_surface1);
LayerImpl* render_surface2 = AddChild<LayerImpl>(clip_child);
@@ -4023,6 +4038,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
base::MakeUnique<std::set<LayerImpl*>>();
clip_parent->test_properties()->clip_children->insert(clip_child);
+ clip_layer->SetBounds(gfx::Size(50, 50));
+
render_surface1->SetBounds(gfx::Size(20, 20));
render_surface1->SetDrawsContent(true);
render_surface1->test_properties()->force_render_surface = true;
@@ -4036,11 +4053,17 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
render_surface2->test_properties()->force_render_surface = true;
clip_parent->SetMasksToBounds(true);
+ clip_layer->SetMasksToBounds(true);
render_surface1->SetMasksToBounds(true);
- ExecuteCalculateDrawProperties(root);
+ float device_scale_factor = 1.f;
+ ExecuteCalculateDrawProperties(root, device_scale_factor);
EXPECT_EQ(gfx::Rect(50, 50),
render_surface2->GetRenderSurface()->clip_rect());
+ device_scale_factor = 2.f;
+ ExecuteCalculateDrawProperties(root, device_scale_factor);
+ EXPECT_EQ(gfx::Rect(100, 100),
+ render_surface2->GetRenderSurface()->clip_rect());
}
TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) {
@@ -5055,7 +5078,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
scoped_refptr<AnimationTimeline> timeline =
AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
host_impl.animation_host()->AddAnimationTimeline(timeline);
- host_impl.pending_tree()->SetElementIdsForTesting();
ElementId child_element_id =
host_impl.pending_tree()->LayerById(child_id)->element_id();
@@ -5723,7 +5745,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
clip_child->test_properties()->clip_parent = clip_parent;
std::unique_ptr<std::set<LayerImpl*>> clip_children(new std::set<LayerImpl*>);
clip_children->insert(clip_child);
- clip_parent->test_properties()->clip_children.reset(clip_children.release());
+ clip_parent->test_properties()->clip_children = std::move(clip_children);
intervening->SetMasksToBounds(true);
clip_parent->SetMasksToBounds(true);
@@ -5812,37 +5834,40 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
EXPECT_TRUE(render_surface1->GetRenderSurface());
EXPECT_TRUE(render_surface2->GetRenderSurface());
- // Since the render surfaces could have expanded, they should not clip (their
- // bounds would no longer be reliable). We should resort to layer clipping
- // in this case.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
+ // render_surface1 should apply the clip from clip_parent. Though there is a
+ // clip child, render_surface1 can apply the clip as there are no clips
+ // between the clip parent and render_surface1
+ EXPECT_EQ(gfx::Rect(1, 1, 40, 40),
render_surface1->GetRenderSurface()->clip_rect());
- EXPECT_FALSE(render_surface1->GetRenderSurface()->is_clipped());
+ EXPECT_TRUE(render_surface1->GetRenderSurface()->is_clipped());
+ EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
+ EXPECT_FALSE(render_surface1->is_clipped());
+
+ // render_surface2 could have expanded, as there is a clip between
+ // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
+ // So, it should not be clipped (their bounds would no longer be reliable).
+ // We should resort to layer clipping in this case.
EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
render_surface2->GetRenderSurface()->clip_rect());
EXPECT_FALSE(render_surface2->GetRenderSurface()->is_clipped());
- // NB: clip rects are in target space.
- EXPECT_EQ(gfx::Rect(0, 0, 40, 40), render_surface1->clip_rect());
- EXPECT_TRUE(render_surface1->is_clipped());
-
// This value is inherited from the clipping ancestor layer, 'intervening'.
EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
EXPECT_TRUE(render_surface2->is_clipped());
- // The content rects of both render surfaces should both have expanded to
- // contain the clip child.
+ // The content rects of render_surface2 should have expanded to contain the
+ // clip child.
EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
render_surface1->GetRenderSurface()->content_rect());
- EXPECT_EQ(gfx::Rect(-1, -1, 40, 40),
+ EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
render_surface2->GetRenderSurface()->content_rect());
// The clip child should have inherited the clip parent's clip (projected to
- // the right space, of course), and should have the correctly sized visible
- // content rect.
- EXPECT_EQ(gfx::Rect(-1, -1, 40, 40), clip_child->clip_rect());
+ // the right space, of course), but as render_surface1 already applies that
+ // clip, clip_child need not apply it again.
+ EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
EXPECT_EQ(gfx::Rect(9, 9, 40, 40), clip_child->visible_layer_rect());
- EXPECT_TRUE(clip_child->is_clipped());
+ EXPECT_FALSE(clip_child->is_clipped());
}
TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
@@ -5895,37 +5920,39 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
EXPECT_TRUE(render_surface1->GetRenderSurface());
EXPECT_TRUE(render_surface2->GetRenderSurface());
- // Since the render surfaces could have expanded, they should not clip (their
- // bounds would no longer be reliable). We should resort to layer clipping
- // in this case.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
+ // render_surface1 should apply the clip from clip_parent. Though there is a
+ // clip child, render_surface1 can apply the clip as there are no clips
+ // between the clip parent and render_surface1
+ EXPECT_EQ(gfx::Rect(3, 3, 40, 40),
render_surface1->GetRenderSurface()->clip_rect());
- EXPECT_FALSE(render_surface1->GetRenderSurface()->is_clipped());
+ EXPECT_TRUE(render_surface1->GetRenderSurface()->is_clipped());
+ EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
+ EXPECT_FALSE(render_surface1->is_clipped());
+
+ // render_surface2 could have expanded, as there is a clip between
+ // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
+ // So, it should not be clipped (their bounds would no longer be reliable).
+ // We should resort to layer clipping in this case.
EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
render_surface2->GetRenderSurface()->clip_rect());
EXPECT_FALSE(render_surface2->GetRenderSurface()->is_clipped());
-
- // NB: clip rects are in target space.
- EXPECT_EQ(gfx::Rect(0, 0, 40, 40), render_surface1->clip_rect());
- EXPECT_TRUE(render_surface1->is_clipped());
-
// This value is inherited from the clipping ancestor layer, 'intervening'.
- EXPECT_EQ(gfx::Rect(2, 2, 3, 3), render_surface2->clip_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
EXPECT_TRUE(render_surface2->is_clipped());
- // The content rects of both render surfaces should both have expanded to
- // contain the clip child.
+ // The content rects of render_surface2 should have expanded to contain the
+ // clip child.
EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
render_surface1->GetRenderSurface()->content_rect());
- EXPECT_EQ(gfx::Rect(2, 2, 40, 40),
+ EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
render_surface2->GetRenderSurface()->content_rect());
// The clip child should have inherited the clip parent's clip (projected to
- // the right space, of course), and should have the correctly sized visible
- // content rect.
- EXPECT_EQ(gfx::Rect(2, 2, 40, 40), clip_child->clip_rect());
+ // the right space, of course), but as render_surface1 already applies that
+ // clip, clip_child need not apply it again.
+ EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
EXPECT_EQ(gfx::Rect(12, 12, 40, 40), clip_child->visible_layer_rect());
- EXPECT_TRUE(clip_child->is_clipped());
+ EXPECT_FALSE(clip_child->is_clipped());
}
TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
@@ -5977,17 +6004,19 @@ TEST_F(LayerTreeHostCommonTest,
//
// root (a render surface)
// + clip_parent (masks to bounds)
- // + render_surface1
- // + clip_child
- // + render_surface2
- // + non_clip_child
+ // + clip_layer (masks to bounds)
+ // + render_surface1
+ // + clip_child
+ // + render_surface2
+ // + non_clip_child
//
// In this example render_surface2 should be unaffected by clip_child.
LayerImpl* root = root_layer_for_testing();
LayerImpl* clip_parent = AddChildToRoot<LayerImpl>();
- LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* clip_layer = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_layer);
LayerImpl* clip_child = AddChild<LayerImpl>(render_surface1);
- LayerImpl* render_surface2 = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* render_surface2 = AddChild<LayerImpl>(clip_layer);
LayerImpl* non_clip_child = AddChild<LayerImpl>(render_surface2);
clip_child->test_properties()->clip_parent = clip_parent;
@@ -5996,7 +6025,7 @@ TEST_F(LayerTreeHostCommonTest,
clip_parent->test_properties()->clip_children->insert(clip_child);
clip_parent->SetMasksToBounds(true);
- render_surface1->SetMasksToBounds(true);
+ clip_layer->SetMasksToBounds(true);
render_surface1->SetDrawsContent(true);
clip_child->SetDrawsContent(true);
@@ -6005,6 +6034,7 @@ TEST_F(LayerTreeHostCommonTest,
root->SetBounds(gfx::Size(15, 15));
clip_parent->SetBounds(gfx::Size(10, 10));
+ clip_layer->SetBounds(gfx::Size(10, 10));
render_surface1->SetPosition(gfx::PointF(5, 5));
render_surface1->SetBounds(gfx::Size(5, 5));
render_surface1->test_properties()->force_render_surface = true;
@@ -6020,7 +6050,7 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_TRUE(render_surface1->GetRenderSurface());
EXPECT_TRUE(render_surface2->GetRenderSurface());
- EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface1->clip_rect());
+ EXPECT_EQ(gfx::Rect(-5, -5, 10, 10), render_surface1->clip_rect());
EXPECT_TRUE(render_surface1->is_clipped());
// The render surface should not clip (it has unclipped descendants), instead
@@ -6043,10 +6073,6 @@ TEST_F(LayerTreeHostCommonTest,
// It also shouldn't have grown to accomodate the clip child.
EXPECT_EQ(gfx::Rect(0, 0, 5, 5),
render_surface2->GetRenderSurface()->content_rect());
-
- // Sanity check our num_unclipped_descendants values.
- EXPECT_EQ(1u, render_surface1->test_properties()->num_unclipped_descendants);
- EXPECT_EQ(0u, render_surface2->test_properties()->num_unclipped_descendants);
}
TEST_F(LayerTreeHostCommonTest,
@@ -6121,7 +6147,6 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
{
LayerImplList render_surface_layer_list;
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root_layer);
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_layer_list);
inputs.can_render_to_separate_surface = true;
@@ -6132,15 +6157,16 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
int count_represents_target_render_surface = 0;
int count_represents_contributing_render_surface = 0;
int count_represents_itself = 0;
- LayerIterator end = LayerIterator::End(&render_surface_layer_list);
- for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list);
- it != end; ++it) {
- if (it.represents_target_render_surface())
+ for (EffectTreeLayerListIterator it(host_impl.active_tree());
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
+ if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
count_represents_target_render_surface++;
- if (it.represents_contributing_render_surface())
+ } else if (it.state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
count_represents_contributing_render_surface++;
- if (it.represents_itself())
+ } else {
count_represents_itself++;
+ }
}
// Two render surfaces.
@@ -6163,15 +6189,16 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
int count_represents_target_render_surface = 0;
int count_represents_contributing_render_surface = 0;
int count_represents_itself = 0;
- LayerIterator end = LayerIterator::End(&render_surface_layer_list);
- for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list);
- it != end; ++it) {
- if (it.represents_target_render_surface())
+ for (EffectTreeLayerListIterator it(host_impl.active_tree());
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
+ if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
count_represents_target_render_surface++;
- if (it.represents_contributing_render_surface())
+ } else if (it.state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
count_represents_contributing_render_surface++;
- if (it.represents_itself())
+ } else {
count_represents_itself++;
+ }
}
// Only root layer has a render surface.
@@ -6368,6 +6395,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) {
render_surface2->test_properties()->double_sided = false;
render_surface2->test_properties()->force_render_surface = true;
render_surface2->test_properties()->sorting_context_id = 1;
+ SetElementIdsForTesting();
ExecuteCalculateDrawProperties(root);
const EffectTree& tree =
@@ -6377,21 +6405,18 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) {
EXPECT_TRUE(tree.Node(render_surface2->effect_tree_index())
->hidden_by_backface_visibility);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- gfx::Transform(), back_facing->transform_tree_index(),
- root->layer_tree_impl());
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- rotate_about_y, render_surface2->transform_tree_index(),
- root->layer_tree_impl());
+ root->layer_tree_impl()->SetTransformMutated(back_facing->element_id(),
+ gfx::Transform());
+ root->layer_tree_impl()->SetTransformMutated(render_surface2->element_id(),
+ rotate_about_y);
ExecuteCalculateDrawProperties(root);
EXPECT_FALSE(tree.Node(render_surface1->effect_tree_index())
->hidden_by_backface_visibility);
EXPECT_TRUE(tree.Node(render_surface2->effect_tree_index())
->hidden_by_backface_visibility);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- rotate_about_y, render_surface1->transform_tree_index(),
- root->layer_tree_impl());
+ root->layer_tree_impl()->SetTransformMutated(render_surface1->element_id(),
+ rotate_about_y);
ExecuteCalculateDrawProperties(root);
EXPECT_TRUE(tree.Node(render_surface1->effect_tree_index())
->hidden_by_backface_visibility);
@@ -6484,50 +6509,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) {
EXPECT_TRANSFORMATION_MATRIX_EQ(scroll_child->DrawTransform(), scale);
}
-TEST_F(LayerTreeHostCommonTest, TargetBetweenScrollChildandScrollParentTarget) {
- LayerImpl* root = root_layer_for_testing();
- LayerImpl* scroll_child_target = AddChildToRoot<LayerImpl>();
- LayerImpl* scroll_child = AddChild<LayerImpl>(scroll_child_target);
- LayerImpl* child_of_scroll_child = AddChild<LayerImpl>(scroll_child);
- LayerImpl* intervening_target = AddChild<LayerImpl>(scroll_child_target);
- LayerImpl* clip = AddChild<LayerImpl>(intervening_target);
- LayerImpl* scroll_parent_target = AddChild<LayerImpl>(clip);
- LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_target);
-
- scroll_parent->SetDrawsContent(true);
- child_of_scroll_child->SetDrawsContent(true);
-
- scroll_child->test_properties()->scroll_parent = scroll_parent;
- scroll_parent->test_properties()->scroll_children =
- base::MakeUnique<std::set<LayerImpl*>>();
- scroll_parent->test_properties()->scroll_children->insert(scroll_child);
-
- root->SetBounds(gfx::Size(50, 50));
- scroll_child_target->SetBounds(gfx::Size(50, 50));
- scroll_child_target->SetMasksToBounds(true);
- scroll_child_target->test_properties()->force_render_surface = true;
- scroll_child->SetBounds(gfx::Size(50, 50));
- child_of_scroll_child->SetBounds(gfx::Size(50, 50));
- child_of_scroll_child->test_properties()->force_render_surface = true;
- intervening_target->SetBounds(gfx::Size(50, 50));
- intervening_target->test_properties()->force_render_surface = true;
- clip->SetBounds(gfx::Size(50, 50));
- clip->SetMasksToBounds(true);
- scroll_parent_target->SetBounds(gfx::Size(50, 50));
- scroll_parent_target->SetMasksToBounds(true);
- scroll_parent_target->test_properties()->force_render_surface = true;
- scroll_parent->SetBounds(gfx::Size(50, 50));
-
- ExecuteCalculateDrawProperties(root);
- PropertyTrees* property_trees = root->layer_tree_impl()->property_trees();
- ClipNode* clip_node =
- property_trees->clip_tree.Node(child_of_scroll_child->clip_tree_index());
- ClipNode* parent_clip_node = property_trees->clip_tree.parent(clip_node);
- DCHECK_GT(parent_clip_node->target_transform_id,
- property_trees->transform_tree.TargetId(
- child_of_scroll_child->transform_tree_index()));
-}
-
TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* parent = AddChildToRoot<LayerImpl>();
@@ -7138,6 +7119,9 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) {
host()->SetRootLayer(root);
scroller->SetScrollClipLayerId(container->id());
+ // The sticky layer has already been scrolled on the main thread side, and has
+ // stuck. This test then checks that further changes from cc-only scrolling
+ // are handled correctly.
LayerStickyPositionConstraint sticky_position;
sticky_position.is_sticky = true;
sticky_position.is_anchored_top = true;
@@ -7915,6 +7899,106 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) {
sticky_pos_impl->ScreenSpaceTransform().To2dTranslation());
}
+TEST_F(LayerTreeHostCommonTest, StickyPositionNested) {
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> container = Layer::Create();
+ scoped_refptr<Layer> scroller = Layer::Create();
+ scoped_refptr<Layer> outer_sticky = Layer::Create();
+ scoped_refptr<Layer> inner_sticky = Layer::Create();
+
+ root->AddChild(container);
+ container->AddChild(scroller);
+ scroller->AddChild(outer_sticky);
+ outer_sticky->AddChild(inner_sticky);
+ host()->SetRootLayer(root);
+ scroller->SetScrollClipLayerId(container->id());
+
+ root->SetBounds(gfx::Size(100, 100));
+ container->SetBounds(gfx::Size(100, 100));
+ scroller->SetBounds(gfx::Size(100, 1000));
+ outer_sticky->SetBounds(gfx::Size(10, 50));
+ outer_sticky->SetPosition(gfx::PointF(0, 50));
+ inner_sticky->SetBounds(gfx::Size(10, 10));
+ inner_sticky->SetPosition(gfx::PointF(0, 0));
+
+ LayerStickyPositionConstraint outer_sticky_pos;
+ outer_sticky_pos.is_sticky = true;
+ outer_sticky_pos.is_anchored_top = true;
+ outer_sticky_pos.top_offset = 10.0f;
+ outer_sticky_pos.parent_relative_sticky_box_offset = gfx::Point(0, 50);
+ outer_sticky_pos.scroll_container_relative_sticky_box_rect =
+ gfx::Rect(0, 50, 10, 50);
+ outer_sticky_pos.scroll_container_relative_containing_block_rect =
+ gfx::Rect(0, 0, 50, 400);
+ outer_sticky->SetStickyPositionConstraint(outer_sticky_pos);
+
+ LayerStickyPositionConstraint inner_sticky_pos;
+ inner_sticky_pos.is_sticky = true;
+ inner_sticky_pos.is_anchored_top = true;
+ inner_sticky_pos.top_offset = 25.0f;
+ inner_sticky_pos.parent_relative_sticky_box_offset = gfx::Point(0, 0);
+ inner_sticky_pos.scroll_container_relative_sticky_box_rect =
+ gfx::Rect(0, 50, 10, 10);
+ inner_sticky_pos.scroll_container_relative_containing_block_rect =
+ gfx::Rect(0, 50, 10, 50);
+ inner_sticky_pos.nearest_layer_shifting_containing_block = outer_sticky->id();
+ inner_sticky->SetStickyPositionConstraint(inner_sticky_pos);
+
+ ExecuteCalculateDrawProperties(root.get());
+ host()->host_impl()->CreatePendingTree();
+ host()->CommitAndCreatePendingTree();
+ host()->host_impl()->ActivateSyncTree();
+ LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
+
+ LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
+ LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id());
+ LayerImpl* outer_sticky_impl = layer_tree_impl->LayerById(outer_sticky->id());
+ LayerImpl* inner_sticky_impl = layer_tree_impl->LayerById(inner_sticky->id());
+
+ ExecuteCalculateDrawProperties(root_impl);
+
+ // Before any scrolling is done, the sticky elements should still be at their
+ // original positions.
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 50.f),
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 50.f),
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+
+ // Scroll less than the sticking point. Both sticky elements should move with
+ // scroll as we haven't gotten to the sticky item locations yet.
+ SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f));
+ ExecuteCalculateDrawProperties(root_impl);
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 45.f),
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 45.f),
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+
+ // Scroll such that the inner sticky should stick, but the outer one should
+ // keep going as it hasn't reached its position yet.
+ SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f));
+ ExecuteCalculateDrawProperties(root_impl);
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 20.f),
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 25.f),
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+
+ // Keep going, both should stick.
+ SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 100.f));
+ ExecuteCalculateDrawProperties(root_impl);
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 10.f),
+ outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+ EXPECT_VECTOR2DF_EQ(
+ gfx::Vector2dF(0.f, 25.f),
+ inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
+}
+
TEST_F(LayerTreeHostCommonTest, NonFlatContainerForFixedPosLayer) {
scoped_refptr<Layer> root = Layer::Create();
scoped_refptr<Layer> container = Layer::Create();
@@ -8266,20 +8350,18 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
EXPECT_EQ(0.f, GetStartingAnimationScale(grand_child_raw));
}
-static void GatherDrawnLayers(const LayerImplList* rsll,
+static void GatherDrawnLayers(LayerTreeImpl* tree_impl,
std::set<LayerImpl*>* drawn_layers) {
- for (LayerIterator it = LayerIterator::Begin(rsll),
- end = LayerIterator::End(rsll);
- it != end; ++it) {
- LayerImpl* layer = *it;
- if (it.represents_itself())
- drawn_layers->insert(layer);
-
- if (!it.represents_contributing_render_surface())
+ for (EffectTreeLayerListIterator it(tree_impl);
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
+ if (it.state() == EffectTreeLayerListIterator::State::LAYER)
+ drawn_layers->insert(it.current_layer());
+
+ if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE)
continue;
- if (layer->GetRenderSurface()->MaskLayer())
- drawn_layers->insert(layer->GetRenderSurface()->MaskLayer());
+ if (it.current_render_surface()->MaskLayer())
+ drawn_layers->insert(it.current_render_surface()->MaskLayer());
}
}
@@ -8328,7 +8410,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
std::set<LayerImpl*> expected;
std::set<LayerImpl*> actual;
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
// If we force render surface, but none of the layers are in the layer list,
@@ -8346,7 +8428,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.clear();
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
// However, if we say that this layer also draws content, it will appear in
@@ -8365,7 +8447,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(grand_child1_raw);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
// Now child is forced to have a render surface, and one if its children draws
@@ -8388,7 +8470,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(grand_child2_raw);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
// Add a mask layer to child.
@@ -8415,7 +8497,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(child_raw->test_properties()->mask_layer);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
ExecuteCalculateDrawProperties(grand_parent_raw);
@@ -8433,7 +8515,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(child_raw->test_properties()->mask_layer);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true;
@@ -8453,7 +8535,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.clear();
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
// Child itself draws means that we should have the child and the mask in the
@@ -8474,7 +8556,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(child_raw);
expected.insert(child_raw->test_properties()->mask_layer);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
child_raw->test_properties()->SetMaskLayer(nullptr);
@@ -8503,7 +8585,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
expected.insert(grand_child2_raw);
actual.clear();
- GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ GatherDrawnLayers(host_impl.active_tree(), &actual);
EXPECT_EQ(expected, actual);
}
@@ -8679,11 +8761,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) {
// Correctly updates animation scale when layer property changes.
child1_layer->test_properties()->transform = gfx::Transform();
- root_layer->layer_tree_impl()
- ->property_trees()
- ->transform_tree.OnTransformAnimated(gfx::Transform(),
- child1_layer->transform_tree_index(),
- root_layer->layer_tree_impl());
+ root_layer->layer_tree_impl()->SetTransformMutated(child1_layer->element_id(),
+ gfx::Transform());
root_layer->layer_tree_impl()->property_trees()->needs_rebuild = false;
ExecuteCalculateDrawProperties(root_layer);
EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2_layer));
@@ -8959,32 +9038,19 @@ TEST_F(LayerTreeHostCommonTest,
gfx::Transform zero_matrix;
zero_matrix.Scale3d(0.f, 0.f, 0.f);
- root->layer_tree_impl()->property_trees()->transform_tree.OnTransformAnimated(
- zero_matrix, animated->transform_tree_index(), root->layer_tree_impl());
- // While computing visible rects by combining clips in screen space, we set
- // the entire layer as visible if the screen space transform is singular. This
- // is not always true when we combine clips in target space because if the
- // intersection of combined_clip in taret space with layer_rect projected to
- // target space is empty, we set it to an empty rect.
- bool skip_verify_visible_rect_calculations = true;
- ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(
- root, skip_verify_visible_rect_calculations);
-
- // The animated layer maps to the empty rect in clipped target space, so is
- // treated as having an empty visible rect.
- EXPECT_EQ(gfx::Rect(), animated->visible_layer_rect());
+ root->layer_tree_impl()->SetTransformMutated(animated->element_id(),
+ zero_matrix);
+ ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root);
// The animated layer will be treated as fully visible when we combine clips
// in screen space.
- gfx::Rect visible_rect = draw_property_utils::ComputeLayerVisibleRectDynamic(
- root->layer_tree_impl()->property_trees(), animated);
- EXPECT_EQ(gfx::Rect(120, 120), visible_rect);
+ EXPECT_EQ(gfx::Rect(120, 120), animated->visible_layer_rect());
// This time, flattening does not make |animated|'s transform invertible. This
// means the clip cannot be projected into |surface|'s space, so we treat
// |surface| and layers that draw into it as having empty visible rect.
- EXPECT_EQ(gfx::Rect(), surface->visible_layer_rect());
- EXPECT_EQ(gfx::Rect(), descendant_of_animation->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), surface->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(200, 200), descendant_of_animation->visible_layer_rect());
}
// Verify that having animated opacity but current opacity 1 still creates
@@ -9473,8 +9539,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) {
EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect());
child_ptr->test_properties()->hide_layer_and_subtree = false;
- child_ptr->layer_tree_impl()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.f, child_ptr->effect_tree_index(), child_ptr->layer_tree_impl());
+ child_ptr->test_properties()->opacity = 0.f;
+ host_impl.active_tree()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr);
EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect());
child_ptr->test_properties()->opacity = 1.f;
@@ -9715,9 +9781,8 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) {
CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback)));
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
- EXPECT_EQ(parent->num_unclipped_descendants(), 1u);
-
EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0);
+
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0);
}
@@ -9781,14 +9846,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) {
LayerImpl* page_scale_layer = nullptr;
LayerImpl* inner_viewport_scroll_layer = nullptr;
LayerImpl* outer_viewport_scroll_layer = nullptr;
- // Visible rects computed by combining clips in target space and root space
- // don't match because of rotation transforms. So, we skip
- // verify_visible_rect_calculations.
- bool skip_verify_visible_rect_calculations = true;
ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor,
page_scale_layer, inner_viewport_scroll_layer,
- outer_viewport_scroll_layer,
- skip_verify_visible_rect_calculations);
+ outer_viewport_scroll_layer);
TransformTree& transform_tree =
root->layer_tree_impl()->property_trees()->transform_tree;
@@ -9802,15 +9862,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) {
EXPECT_TRUE(render_surface->GetRenderSurface());
EXPECT_FALSE(test_layer->GetRenderSurface());
- ClipTree& clip_tree = root->layer_tree_impl()->property_trees()->clip_tree;
- ClipNode* clip_node = clip_tree.Node(render_surface->clip_tree_index());
- EXPECT_EQ(clip_node->clip_type, ClipNode::ClipType::NONE);
- EXPECT_EQ(gfx::Rect(20, 20), test_layer->visible_layer_rect());
-
- // Also test the visible rects computed by combining clips in root space.
- gfx::Rect visible_rect = draw_property_utils::ComputeLayerVisibleRectDynamic(
- root->layer_tree_impl()->property_trees(), test_layer);
- EXPECT_EQ(gfx::Rect(30, 20), visible_rect);
+ EXPECT_EQ(gfx::Rect(30, 20), test_layer->visible_layer_rect());
}
TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) {
@@ -9860,6 +9912,7 @@ TEST_F(LayerTreeHostCommonTest,
clip_parent->SetMasksToBounds(true);
between_clip_parent_and_child->test_properties()->transform = translate;
between_clip_parent_and_child->SetBounds(gfx::Size(30, 30));
+ between_clip_parent_and_child->SetMasksToBounds(true);
render_surface->SetBounds(gfx::Size(30, 30));
render_surface->test_properties()->force_render_surface = true;
test_layer->SetBounds(gfx::Size(30, 30));
@@ -9979,7 +10032,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* unclipped_surface = AddChildToRoot<LayerImpl>();
LayerImpl* clip_parent = AddChild<LayerImpl>(unclipped_surface);
- LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* clip_layer = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_layer);
LayerImpl* unclipped_desc_surface2 =
AddChild<LayerImpl>(unclipped_desc_surface);
LayerImpl* clip_child = AddChild<LayerImpl>(unclipped_desc_surface2);
@@ -9992,8 +10046,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) {
unclipped_surface->test_properties()->force_render_surface = true;
clip_parent->SetBounds(gfx::Size(50, 50));
clip_parent->SetMasksToBounds(true);
+ clip_layer->SetMasksToBounds(true);
+ clip_layer->SetBounds(gfx::Size(100, 100));
unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
- unclipped_desc_surface->SetMasksToBounds(true);
unclipped_desc_surface->SetDrawsContent(true);
unclipped_desc_surface->test_properties()->force_render_surface = true;
unclipped_desc_surface2->SetBounds(gfx::Size(60, 60));
@@ -10014,7 +10069,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) {
unclipped_surface->GetRenderSurface()->content_rect());
EXPECT_EQ(gfx::Rect(50, 50),
unclipped_desc_surface->GetRenderSurface()->content_rect());
- EXPECT_EQ(gfx::Rect(50, 50),
+ EXPECT_EQ(gfx::Rect(60, 60),
unclipped_desc_surface2->GetRenderSurface()->content_rect());
EXPECT_EQ(gfx::Rect(50, 50),
clipped_surface->GetRenderSurface()->content_rect());
@@ -10125,13 +10180,16 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* clip_layer = AddChild<LayerImpl>(root);
LayerImpl* clip_parent = AddChild<LayerImpl>(clip_layer);
- LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* clip_parent_child = AddChild<LayerImpl>(clip_parent);
+ LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_parent_child);
LayerImpl* clip_child = AddChild<LayerImpl>(unclipped_desc_surface);
root->SetBounds(gfx::Size(100, 100));
clip_layer->SetBounds(gfx::Size(20, 20));
clip_layer->SetMasksToBounds(true);
clip_parent->SetBounds(gfx::Size(50, 50));
+ clip_parent_child->SetBounds(gfx::Size(20, 20));
+ clip_parent_child->SetMasksToBounds(true);
unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
unclipped_desc_surface->SetDrawsContent(true);
unclipped_desc_surface->test_properties()->force_render_surface = true;
@@ -10219,22 +10277,27 @@ TEST_F(LayerTreeHostCommonTest, SubtreeIsHiddenTest) {
test->test_properties()->force_render_surface = true;
ExecuteCalculateDrawProperties(root);
- EXPECT_TRUE(test->IsHidden());
+ EXPECT_EQ(0.f,
+ test->GetRenderSurface()->OwningEffectNode()->screen_space_opacity);
hidden->test_properties()->hide_layer_and_subtree = false;
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
- EXPECT_FALSE(test->IsHidden());
+ EXPECT_EQ(1.f,
+ test->GetRenderSurface()->OwningEffectNode()->screen_space_opacity);
}
TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) {
LayerImpl* root = root_layer_for_testing();
- LayerImpl* render_surface1 = AddChild<LayerImpl>(root);
+ LayerImpl* clip_layer = AddChild<LayerImpl>(root);
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_layer);
LayerImpl* render_surface2 = AddChild<LayerImpl>(render_surface1);
LayerImpl* clip_child = AddChild<LayerImpl>(render_surface2);
root->SetBounds(gfx::Size(30, 30));
root->SetMasksToBounds(true);
+ clip_layer->SetBounds(gfx::Size(30, 30));
+ clip_layer->SetMasksToBounds(true);
render_surface1->SetPosition(gfx::PointF(10, 10));
render_surface1->SetBounds(gfx::Size(30, 30));
render_surface1->SetDrawsContent(true);
@@ -10243,6 +10306,7 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) {
render_surface2->SetDrawsContent(true);
render_surface2->test_properties()->force_render_surface = true;
clip_child->SetBounds(gfx::Size(30, 30));
+ clip_child->SetDrawsContent(true);
clip_child->test_properties()->clip_parent = root;
root->test_properties()->clip_children =
@@ -10252,9 +10316,6 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) {
ExecuteCalculateDrawProperties(root);
EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect());
- // A clip node is created for every render surface and for layers that have
- // local clip. So, here it should be craeted for every layer.
- EXPECT_EQ(root->layer_tree_impl()->property_trees()->clip_tree.size(), 5u);
}
TEST_F(LayerTreeHostCommonTest, MaskLayerDrawProperties) {
@@ -10443,8 +10504,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) {
EXPECT_TRUE(property_trees->needs_rebuild);
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
- EXPECT_NE(property_trees->layer_id_to_effect_node_index.find(child->id()),
- property_trees->layer_id_to_effect_node_index.end());
+ EXPECT_NE(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()),
+ nullptr);
// child already has an effect node. Changing its opacity shouldn't trigger
// a property trees rebuild.
@@ -10453,8 +10514,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) {
EXPECT_FALSE(property_trees->needs_rebuild);
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
- EXPECT_NE(property_trees->layer_id_to_effect_node_index.find(child->id()),
- property_trees->layer_id_to_effect_node_index.end());
+ EXPECT_NE(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()),
+ nullptr);
// Changing the opacity from non-1 value to 1 should trigger a rebuild of
// property trees as the effect node may no longer be needed.
@@ -10463,8 +10524,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) {
EXPECT_TRUE(property_trees->needs_rebuild);
ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
- EXPECT_EQ(property_trees->layer_id_to_effect_node_index.find(child->id()),
- property_trees->layer_id_to_effect_node_index.end());
+ EXPECT_EQ(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()),
+ nullptr);
}
TEST_F(LayerTreeHostCommonTest, OpacityAnimationsTrackingTest) {
@@ -10685,6 +10746,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_root1.user_scrollable_vertical = true;
scroll_root1.transform_id = root1->transform_tree_index();
expected_scroll_tree.Insert(scroll_root1, 0);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ root1->id());
// The node owned by parent2
ScrollNode scroll_parent2;
@@ -10701,6 +10764,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_parent2.user_scrollable_vertical = true;
scroll_parent2.transform_id = parent2->transform_tree_index();
expected_scroll_tree.Insert(scroll_parent2, 1);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ parent2->id());
// The node owned by child6
ScrollNode scroll_child6;
@@ -10713,6 +10778,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_child6.user_scrollable_vertical = true;
scroll_child6.transform_id = child6->transform_tree_index();
expected_scroll_tree.Insert(scroll_child6, 2);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ child6->id());
// The node owned by child7, child7 also owns a transform node
ScrollNode scroll_child7;
@@ -10725,6 +10792,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_child7.user_scrollable_vertical = true;
scroll_child7.transform_id = child7->transform_tree_index();
expected_scroll_tree.Insert(scroll_child7, 1);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ child7->id());
// The node owned by grand_child11, grand_child11 also owns a transform node
ScrollNode scroll_grand_child11;
@@ -10735,6 +10804,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_grand_child11.user_scrollable_vertical = true;
scroll_grand_child11.transform_id = grand_child11->transform_tree_index();
expected_scroll_tree.Insert(scroll_grand_child11, 4);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ grand_child11->id());
// The node owned by parent5
ScrollNode scroll_parent5;
@@ -10747,6 +10818,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
scroll_parent5.user_scrollable_vertical = true;
scroll_parent5.transform_id = parent5->transform_tree_index();
expected_scroll_tree.Insert(scroll_parent5, 1);
+ expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
+ parent5->id());
expected_scroll_tree.SetScrollOffset(parent2->id(), gfx::ScrollOffset(0, 0));
expected_scroll_tree.SetScrollOffset(child7->id(), gfx::ScrollOffset(0, 0));
@@ -10766,5 +10839,38 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
EXPECT_EQ(scroll_root1.id, grand_child12->scroll_tree_index());
}
+TEST_F(LayerTreeHostCommonTest, CanAdjustRasterScaleTest) {
+ LayerImpl* root = root_layer_for_testing();
+ LayerImpl* render_surface = AddChild<LayerImpl>(root);
+ LayerImpl* child = AddChild<LayerImpl>(render_surface);
+
+ root->SetBounds(gfx::Size(50, 50));
+
+ render_surface->SetBounds(gfx::Size(10, 10));
+ render_surface->test_properties()->force_render_surface = true;
+ gfx::Transform transform;
+ transform.Scale(5.f, 5.f);
+ render_surface->test_properties()->transform = transform;
+
+ child->SetDrawsContent(true);
+ child->SetMasksToBounds(true);
+ child->SetBounds(gfx::Size(10, 10));
+
+ ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales(root);
+
+ // Check surface draw properties.
+ EXPECT_EQ(gfx::Rect(10, 10),
+ render_surface->GetRenderSurface()->content_rect());
+ EXPECT_EQ(transform, render_surface->GetRenderSurface()->draw_transform());
+ EXPECT_EQ(gfx::RectF(50.0f, 50.0f),
+ render_surface->GetRenderSurface()->DrawableContentRect());
+
+ // Check child layer draw properties.
+ EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
+ EXPECT_EQ(gfx::Transform(), child->DrawTransform());
+ EXPECT_EQ(gfx::Rect(10, 10), child->clip_rect());
+ EXPECT_EQ(gfx::Rect(10, 10), child->drawable_content_rect());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index ecfd4d84487..05e4e3add0a 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -24,13 +24,10 @@
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
-#include "cc/debug/benchmark_instrumentation.h"
-#include "cc/debug/debug_rect_history.h"
-#include "cc/debug/devtools_instrumentation.h"
-#include "cc/debug/frame_rate_counter.h"
-#include "cc/debug/frame_viewer_instrumentation.h"
+#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/debug/traced_value.h"
#include "cc/input/browser_controls_offset_manager.h"
@@ -40,9 +37,9 @@
#include "cc/input/scroll_state.h"
#include "cc/input/scrollbar_animation_controller.h"
#include "cc/layers/append_quads_data.h"
+#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer_impl.h"
-#include "cc/layers/layer_iterator.h"
#include "cc/layers/painted_scrollbar_layer_impl.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/layers/scrollbar_layer_impl_base.h"
@@ -67,18 +64,23 @@
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/tiles/eviction_tile_priority_queue.h"
+#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/tiles/gpu_image_decode_cache.h"
#include "cc/tiles/picture_layer_tiling.h"
#include "cc/tiles/raster_tile_priority_queue.h"
#include "cc/tiles/software_image_decode_cache.h"
#include "cc/trees/damage_tracker.h"
+#include "cc/trees/debug_rect_history.h"
#include "cc/trees/draw_property_utils.h"
+#include "cc/trees/effect_node.h"
+#include "cc/trees/frame_rate_counter.h"
#include "cc/trees/latency_info_swap_promise_monitor.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/mutator_host.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/single_thread_proxy.h"
+#include "cc/trees/transform_node.h"
#include "cc/trees/tree_synchronizer.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
@@ -237,7 +239,11 @@ LayerTreeHostImpl::LayerTreeHostImpl(
requires_high_res_to_draw_(false),
is_likely_to_require_a_draw_(false),
has_valid_compositor_frame_sink_(false),
- mutator_(nullptr) {
+ mutator_(nullptr),
+ scroll_animating_latched_node_id_(ScrollTree::kInvalidNodeId),
+ has_scrolled_by_wheel_(false),
+ has_scrolled_by_touch_(false),
+ touchpad_and_wheel_scroll_latching_enabled_(false) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
@@ -598,13 +604,12 @@ EventListenerProperties LayerTreeHostImpl::GetEventListenerProperties(
// Return true if scrollable node for 'ancestor' is the same as 'child' or an
// ancestor along the scroll tree.
-bool IsScrolledBy(LayerImpl* child, ScrollNode* ancestor) {
+bool LayerTreeHostImpl::IsScrolledBy(LayerImpl* child, ScrollNode* ancestor) {
DCHECK(ancestor && ancestor->scrollable);
if (!child)
return false;
-
- auto* property_trees = child->layer_tree_impl()->property_trees();
- ScrollTree& scroll_tree = property_trees->scroll_tree;
+ DCHECK_EQ(child->layer_tree_impl(), active_tree_.get());
+ ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
for (ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index());
scroll_node; scroll_node = scroll_tree.parent(scroll_node)) {
if (scroll_node->id == ancestor->id)
@@ -621,15 +626,22 @@ LayerTreeHostImpl::EventListenerTypeForTouchStartAt(
// Now determine if there are actually any handlers at that point.
// TODO(rbyers): Consider also honoring touch-action (crbug.com/347272).
- LayerImpl* layer_impl =
+ LayerImpl* layer_impl_with_touch_handler =
active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion(
device_viewport_point);
- if (layer_impl == NULL)
+ if (layer_impl_with_touch_handler == NULL)
return InputHandler::TouchStartEventListenerType::NO_HANDLER;
if (!CurrentlyScrollingNode())
return InputHandler::TouchStartEventListenerType::HANDLER;
+ // Check if the touch start hits on the current scrolling layer or its
+ // descendant. layer_impl_with_touch_handler is the layer hit by the pointer
+ // and has an event handler, otherwise it is null.
+ // We want to compare the most inner layer we are hitting on which may not
+ // have an event listener with the actual scrolling layer.
+ LayerImpl* layer_impl =
+ active_tree_->FindLayerThatIsHitByPoint(device_viewport_point);
bool is_ancestor = IsScrolledBy(layer_impl, CurrentlyScrollingNode());
return is_ancestor ? InputHandler::TouchStartEventListenerType::
HANDLER_ON_SCROLLING_LAYER
@@ -673,6 +685,22 @@ bool LayerTreeHostImpl::ScrollLayerTo(int layer_id,
return true;
}
+bool LayerTreeHostImpl::ScrollingShouldSwitchtoMainThread() {
+ ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
+ ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+
+ if (!scroll_node)
+ return true;
+
+ for (; scroll_tree.parent(scroll_node);
+ scroll_node = scroll_tree.parent(scroll_node)) {
+ if (!!scroll_node->main_thread_scrolling_reasons)
+ return true;
+ }
+
+ return false;
+}
+
void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate(
std::unique_ptr<SwapPromise> swap_promise) {
swap_promises_for_main_thread_scroll_update_.push_back(
@@ -720,11 +748,6 @@ void LayerTreeHostImpl::FrameData::AsValueInto(
}
}
-void LayerTreeHostImpl::FrameData::AppendRenderPass(
- std::unique_ptr<RenderPass> render_pass) {
- render_passes.push_back(std::move(render_pass));
-}
-
DrawMode LayerTreeHostImpl::GetDrawMode() const {
if (resourceless_software_draw_) {
return DRAW_MODE_RESOURCELESS_SOFTWARE;
@@ -837,7 +860,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
render_surface->contributes_to_drawn_surface() ||
render_surface->HasCopyRequest();
if (should_draw_into_render_pass)
- render_surface->AppendRenderPasses(frame);
+ frame->render_passes.push_back(render_surface->CreateRenderPass());
}
// Damage rects for non-root passes aren't meaningful, so set them to be
@@ -885,19 +908,16 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
active_tree()->property_trees()->effect_tree.HasCopyRequests();
bool have_missing_animated_tiles = false;
- LayerIterator end = LayerIterator::End(frame->render_surface_layer_list);
- for (LayerIterator it =
- LayerIterator::Begin(frame->render_surface_layer_list);
- it != end; ++it) {
- auto target_render_pass_id =
- it.target_render_surface_layer()->GetRenderSurface()->GetRenderPassId();
+ for (EffectTreeLayerListIterator it(active_tree());
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
+ auto target_render_pass_id = it.target_render_surface()->GetRenderPassId();
RenderPass* target_render_pass =
FindRenderPassById(frame->render_passes, target_render_pass_id);
AppendQuadsData append_quads_data;
- RenderSurfaceImpl* render_surface = it->GetRenderSurface();
- if (it.represents_target_render_surface()) {
+ if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
+ RenderSurfaceImpl* render_surface = it.target_render_surface();
if (render_surface->HasCopyRequest()) {
active_tree()
->property_trees()
@@ -905,50 +925,57 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
render_surface->EffectTreeIndex(),
&target_render_pass->copy_requests);
}
- } else if (it.represents_contributing_render_surface() &&
- render_surface->contributes_to_drawn_surface()) {
- render_surface->AppendQuads(target_render_pass, &append_quads_data);
- } else if (it.represents_itself() && !it->visible_layer_rect().IsEmpty()) {
+ } else if (it.state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
+ RenderSurfaceImpl* render_surface = it.current_render_surface();
+ if (render_surface->contributes_to_drawn_surface())
+ render_surface->AppendQuads(target_render_pass, &append_quads_data);
+ } else if (it.state() == EffectTreeLayerListIterator::State::LAYER &&
+ !it.current_layer()->visible_layer_rect().IsEmpty()) {
+ LayerImpl* layer = it.current_layer();
bool occluded =
- it->draw_properties().occlusion_in_content_space.IsOccluded(
- it->visible_layer_rect());
- if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) {
- DCHECK_EQ(active_tree_.get(), it->layer_tree_impl());
+ layer->draw_properties().occlusion_in_content_space.IsOccluded(
+ layer->visible_layer_rect());
+ if (!occluded && layer->WillDraw(draw_mode, resource_provider_.get())) {
+ DCHECK_EQ(active_tree_.get(), layer->layer_tree_impl());
- frame->will_draw_layers.push_back(*it);
- if (it->may_contain_video())
+ frame->will_draw_layers.push_back(layer);
+ if (layer->may_contain_video())
frame->may_contain_video = true;
- it->AppendQuads(target_render_pass, &append_quads_data);
+ layer->AppendQuads(target_render_pass, &append_quads_data);
}
++layers_drawn;
- }
- rendering_stats_instrumentation_->AddVisibleContentArea(
- append_quads_data.visible_layer_area);
- rendering_stats_instrumentation_->AddApproximatedVisibleContentArea(
- append_quads_data.approximated_visible_content_area);
- rendering_stats_instrumentation_->AddCheckerboardedVisibleContentArea(
- append_quads_data.checkerboarded_visible_content_area);
- rendering_stats_instrumentation_->AddCheckerboardedNoRecordingContentArea(
- append_quads_data.checkerboarded_no_recording_content_area);
- rendering_stats_instrumentation_->AddCheckerboardedNeedsRasterContentArea(
- append_quads_data.checkerboarded_needs_raster_content_area);
-
- num_missing_tiles += append_quads_data.num_missing_tiles;
- num_incomplete_tiles += append_quads_data.num_incomplete_tiles;
- checkerboarded_no_recording_content_area +=
- append_quads_data.checkerboarded_no_recording_content_area;
- checkerboarded_needs_raster_content_area +=
- append_quads_data.checkerboarded_needs_raster_content_area;
- if (append_quads_data.num_missing_tiles > 0) {
- have_missing_animated_tiles |=
- !it->was_ever_ready_since_last_transform_animation() ||
- it->screen_space_transform_is_animating();
- } else {
- it->set_was_ever_ready_since_last_transform_animation(true);
+ rendering_stats_instrumentation_->AddVisibleContentArea(
+ append_quads_data.visible_layer_area);
+ rendering_stats_instrumentation_->AddApproximatedVisibleContentArea(
+ append_quads_data.approximated_visible_content_area);
+ rendering_stats_instrumentation_->AddCheckerboardedVisibleContentArea(
+ append_quads_data.checkerboarded_visible_content_area);
+ rendering_stats_instrumentation_->AddCheckerboardedNoRecordingContentArea(
+ append_quads_data.checkerboarded_no_recording_content_area);
+ rendering_stats_instrumentation_->AddCheckerboardedNeedsRasterContentArea(
+ append_quads_data.checkerboarded_needs_raster_content_area);
+
+ num_missing_tiles += append_quads_data.num_missing_tiles;
+ num_incomplete_tiles += append_quads_data.num_incomplete_tiles;
+ checkerboarded_no_recording_content_area +=
+ append_quads_data.checkerboarded_no_recording_content_area;
+ checkerboarded_needs_raster_content_area +=
+ append_quads_data.checkerboarded_needs_raster_content_area;
+ if (append_quads_data.num_missing_tiles > 0) {
+ have_missing_animated_tiles |=
+ !layer->was_ever_ready_since_last_transform_animation() ||
+ layer->screen_space_transform_is_animating();
+ } else {
+ layer->set_was_ever_ready_since_last_transform_animation(true);
+ }
}
+ frame->embedded_surfaces.insert(frame->embedded_surfaces.end(),
+ append_quads_data.embedded_surfaces.begin(),
+ append_quads_data.embedded_surfaces.end());
}
// If CommitToActiveTree() is true, then we wait to draw until
@@ -1020,11 +1047,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
checkerboarded_needs_raster_content_area);
}
- // Should only have one render pass in resourceless software mode.
- DCHECK(draw_mode != DRAW_MODE_RESOURCELESS_SOFTWARE ||
- frame->render_passes.size() == 1u)
- << frame->render_passes.size();
-
TRACE_EVENT_END2("cc", "LayerTreeHostImpl::CalculateRenderPasses",
"draw_result", draw_result, "missing tiles",
num_missing_tiles);
@@ -1169,7 +1191,8 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
break;
}
- if (pass->quad_list.empty() && pass->copy_requests.empty()) {
+ if (pass->quad_list.empty() && pass->copy_requests.empty() &&
+ pass->filters.IsEmpty() && pass->background_filters.IsEmpty()) {
// Remove the pass and decrement |i| to counter the for loop's increment,
// so we don't skip the next pass in the loop.
frame->render_passes.erase(frame->render_passes.begin() + i);
@@ -1328,10 +1351,12 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
is_likely_to_require_a_draw_ = is_likely_to_require_a_draw;
}
-gfx::ColorSpace LayerTreeHostImpl::GetTileColorSpace() const {
- if (!sync_tree())
+gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace() const {
+ if (!settings_.enable_color_correct_rasterization)
return gfx::ColorSpace();
- return sync_tree()->device_color_space();
+ if (!sync_tree())
+ return gfx::ColorSpace::CreateSRGB();
+ return sync_tree()->raster_color_space();
}
void LayerTreeHostImpl::RequestImplSideInvalidation() {
@@ -1600,13 +1625,14 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
for (LayerImpl* surface_layer : active_tree_->SurfaceLayers()) {
SurfaceLayerImpl* surface_layer_impl =
static_cast<SurfaceLayerImpl*>(surface_layer);
- metadata.referenced_surfaces.push_back(
- surface_layer_impl->primary_surface_info().id());
- // We need to retain a reference to the fallback surface too so that it's
- // guaranteed to be available when needed.
- if (surface_layer_impl->fallback_surface_info().is_valid()) {
+ if (settings_.enable_surface_synchronization) {
+ if (surface_layer_impl->fallback_surface_info().is_valid()) {
+ metadata.referenced_surfaces.push_back(
+ surface_layer_impl->fallback_surface_info().id());
+ }
+ } else {
metadata.referenced_surfaces.push_back(
- surface_layer_impl->fallback_surface_info().id());
+ surface_layer_impl->primary_surface_info().id());
}
}
if (!InnerViewportScrollLayer())
@@ -1683,6 +1709,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
CompositorFrameMetadata metadata = MakeCompositorFrameMetadata();
metadata.may_contain_video = frame->may_contain_video;
+ metadata.embedded_surfaces = std::move(frame->embedded_surfaces);
active_tree()->FinishSwapPromises(&metadata);
for (auto& latency : metadata.latency_info) {
TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow",
@@ -1707,11 +1734,21 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
}
}
+ DCHECK_LE(BeginFrameArgs::kStartingFrameNumber,
+ frame->begin_frame_ack.sequence_number);
+ metadata.begin_frame_ack = frame->begin_frame_ack;
+
CompositorFrame compositor_frame;
compositor_frame.metadata = std::move(metadata);
resource_provider_->PrepareSendToParent(resources,
&compositor_frame.resource_list);
compositor_frame.render_pass_list = std::move(frame->render_passes);
+ // TODO(fsamuel): Once all clients get their LocalSurfaceId from their parent,
+ // the LocalSurfaceId should hang off CompositorFrameMetadata.
+ if (active_tree()->local_surface_id().is_valid()) {
+ compositor_frame_sink_->SetLocalSurfaceId(
+ active_tree()->local_surface_id());
+ }
compositor_frame_sink_->SubmitCompositorFrame(std::move(compositor_frame));
// Clears the list of swap promises after calling DidSwap on each of them to
@@ -2041,10 +2078,10 @@ void LayerTreeHostImpl::ActivateSyncTree() {
else
active_tree_->MoveChangeTrackingToLayers();
}
+ TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree());
active_tree_->property_trees()->PushOpacityIfNeeded(
pending_tree_->property_trees());
- TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree());
pending_tree_->PushPropertiesTo(active_tree_.get());
if (!pending_tree_->LayerListIsEmpty())
pending_tree_->property_trees()->ResetAllChangeTracking();
@@ -2108,6 +2145,17 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
if (visible_) {
// TODO(crbug.com/469175): Replace with RequiresHighResToDraw.
SetRequiresHighResToDraw();
+ // Prior CompositorFrame may have been discarded and thus we need to ensure
+ // that we submit a new one, even if there are no tiles. Therefore, force a
+ // full viewport redraw. However, this is unnecessary when we become visible
+ // for the first time (before the first commit) as there is no prior
+ // CompositorFrame to replace. We can safely use |!active_tree_->
+ // LayerListIsEmpty()| as a proxy for this, because we wouldn't be able to
+ // draw anything even if this is not the first time we become visible.
+ if (!active_tree_->LayerListIsEmpty()) {
+ SetFullViewportDamage();
+ SetNeedsRedraw();
+ }
} else {
EvictAllUIResources();
// Call PrepareTiles to evict tiles when we become invisible.
@@ -2174,11 +2222,12 @@ void LayerTreeHostImpl::CreateTileManagerResources() {
image_decode_cache_ = base::MakeUnique<GpuImageDecodeCache>(
compositor_frame_sink_->worker_context_provider(),
settings_.renderer_settings.preferred_tile_format,
- settings_.gpu_decoded_image_budget_bytes);
+ settings_.decoded_image_working_set_budget_bytes,
+ settings_.decoded_image_cache_budget_bytes);
} else {
image_decode_cache_ = base::MakeUnique<SoftwareImageDecodeCache>(
settings_.renderer_settings.preferred_tile_format,
- settings_.software_decoded_image_budget_bytes);
+ settings_.decoded_image_working_set_budget_bytes);
}
// Pass the single-threaded synchronous task graph runner to the worker pool
@@ -2237,7 +2286,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider(
*raster_buffer_provider = base::MakeUnique<GpuRasterBufferProvider>(
compositor_context_provider, worker_context_provider,
resource_provider_.get(), settings_.use_distance_field_text,
- msaa_sample_count, settings_.async_worker_context_enabled);
+ msaa_sample_count, settings_.renderer_settings.preferred_tile_format,
+ settings_.async_worker_context_enabled);
return;
}
@@ -2293,7 +2343,38 @@ LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() {
return viewport()->MainScrollLayer();
}
+void LayerTreeHostImpl::QueueImageDecode(
+ sk_sp<const SkImage> image,
+ const base::Callback<void(bool)>& embedder_callback) {
+ decoded_image_tracker_.QueueImageDecode(
+ std::move(image), base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
+ base::Unretained(this), embedder_callback));
+}
+
+void LayerTreeHostImpl::ImageDecodeFinished(
+ const base::Callback<void(bool)>& embedder_callback,
+ bool decode_succeeded) {
+ completed_image_decode_callbacks_.emplace_back(
+ base::Bind(embedder_callback, decode_succeeded));
+ client_->SetNeedsCommitOnImplThread();
+}
+
+std::vector<base::Closure>
+LayerTreeHostImpl::TakeCompletedImageDecodeCallbacks() {
+ auto result = std::move(completed_image_decode_callbacks_);
+ completed_image_decode_callbacks_.clear();
+ return result;
+}
+
+void LayerTreeHostImpl::ClearImageCacheOnNavigation() {
+ if (image_decode_cache_)
+ image_decode_cache_->ClearCache();
+}
+
void LayerTreeHostImpl::DidChangeScrollbarVisibility() {
+ // Need a commit since input handling for scrollbars is handled in Blink so
+ // we need to communicate to Blink when the compositor shows/hides the
+ // scrollbars.
client_->SetNeedsCommitOnImplThread();
}
@@ -2380,7 +2461,7 @@ bool LayerTreeHostImpl::InitializeRenderer(
settings_.renderer_settings.texture_id_allocation_chunk_size,
compositor_frame_sink_->capabilities().delegated_sync_points_required,
settings_.renderer_settings.use_gpu_memory_buffer_resources,
- settings_.enable_color_correct_rendering,
+ settings_.enable_color_correct_rasterization,
settings_.renderer_settings.buffer_to_texture_target_map);
// Since the new context may be capable of MSAA, update status here. We don't
@@ -2480,9 +2561,11 @@ float LayerTreeHostImpl::CurrentBrowserControlsShownRatio() const {
return active_tree_->CurrentBrowserControlsShownRatio();
}
-void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) {
+void LayerTreeHostImpl::BindToClient(InputHandlerClient* client,
+ bool wheel_scroll_latching_enabled) {
DCHECK(input_handler_client_ == NULL);
input_handler_client_ = client;
+ touchpad_and_wheel_scroll_latching_enabled_ = wheel_scroll_latching_enabled;
}
InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll(
@@ -2668,6 +2751,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
client_->RenewTreePriority();
RecordCompositorSlowScrollMetric(type, CC_THREAD);
+ UpdateScrollSourceInfo(wheel_scrolling_);
+
return scroll_status;
}
@@ -2805,8 +2890,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
// this does not currently go through the scroll customization machinery
// that ScrollBy uses for non-animated wheel scrolls.
scroll_status = ScrollBegin(&scroll_state, WHEEL);
- scroll_node = scroll_tree.CurrentlyScrollingNode();
if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
+ scroll_animating_latched_node_id_ = ScrollTree::kInvalidNodeId;
ScrollStateData scroll_state_end_data;
scroll_state_end_data.is_ending = true;
ScrollState scroll_state_end(scroll_state_end_data);
@@ -2878,7 +2963,15 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
MainThreadScrollingReason::kNotScrollingOnMain;
ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+
if (scroll_node) {
+ // Flash the overlay scrollbar even if the scroll dalta is 0.
+ ScrollbarAnimationController* animation_controller =
+ ScrollbarAnimationControllerForId(scroll_node->owning_layer_id);
+
+ if (animation_controller)
+ animation_controller->WillUpdateScroll();
+
gfx::Vector2dF delta = scroll_delta;
if (!scroll_node->user_scrollable_horizontal)
delta.set_x(0);
@@ -2913,29 +3006,54 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
if (!scroll_node->scrollable)
continue;
+ if (touchpad_and_wheel_scroll_latching_enabled_ &&
+ scroll_animating_latched_node_id_ != ScrollTree::kInvalidNodeId &&
+ scroll_node->id != scroll_animating_latched_node_id_) {
+ continue;
+ }
+
bool scrolls_main_viewport_scroll_layer =
viewport()->MainScrollLayer() &&
viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id;
if (scrolls_main_viewport_scroll_layer) {
+ // Flash the overlay scrollbar even if the scroll dalta is 0.
+ ScrollbarAnimationController* animation_controller =
+ ScrollbarAnimationControllerForId(scroll_node->owning_layer_id);
+
+ if (animation_controller)
+ animation_controller->WillUpdateScroll();
+
gfx::Vector2dF scrolled =
viewport()->ScrollAnimated(pending_delta, delayed_by);
// Viewport::ScrollAnimated returns pending_delta as long as it starts
// an animation.
- if (scrolled == pending_delta)
+ if (scrolled == pending_delta) {
+ scroll_animating_latched_node_id_ = scroll_node->id;
return scroll_status;
+ }
break;
}
gfx::Vector2dF scroll_delta =
ComputeScrollDelta(scroll_node, pending_delta);
- if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by))
+ if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) {
+ scroll_animating_latched_node_id_ = scroll_node->id;
return scroll_status;
+ }
pending_delta -= scroll_delta;
}
}
scroll_state.set_is_ending(true);
ScrollEnd(&scroll_state);
+ if (settings_.is_layer_tree_for_subframe &&
+ scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
+ // If we get to here, we shouldn't return SCROLL_ON_IMPL_THREAD as otherwise
+ // we'll mark the scroll as handled and the scroll won't bubble.
+ scroll_status.thread = SCROLL_IGNORED;
+ scroll_status.main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kNotScrollable;
+ }
return scroll_status;
}
@@ -3161,9 +3279,18 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
DCHECK(scroll_state);
TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
- if (!CurrentlyScrollingNode())
+ ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
+ ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+
+ if (!scroll_node)
return InputHandlerScrollResult();
+ ScrollbarAnimationController* animation_controller =
+ ScrollbarAnimationControllerForId(scroll_node->owning_layer_id);
+
+ if (animation_controller)
+ animation_controller->WillUpdateScroll();
+
float initial_top_controls_offset =
browser_controls_offset_manager_->ControlsTopOffset();
@@ -3464,6 +3591,11 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
active_tree_->elastic_overscroll()->PullDeltaForMainThread();
scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_);
+ // Record and reset scroll source flags.
+ scroll_info->has_scrolled_by_wheel = has_scrolled_by_wheel_;
+ scroll_info->has_scrolled_by_touch = has_scrolled_by_touch_;
+ has_scrolled_by_wheel_ = has_scrolled_by_touch_ = false;
+
return scroll_info;
}
@@ -3785,7 +3917,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
id = resource_provider_->CreateResource(
upload_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format,
- gfx::ColorSpace());
+ gfx::ColorSpace::CreateSRGB());
if (!scaled) {
AutoLockUIResourceBitmap bitmap_lock(bitmap);
@@ -3965,55 +4097,6 @@ void LayerTreeHostImpl::SetMutatorsNeedCommit() {}
void LayerTreeHostImpl::SetMutatorsNeedRebuildPropertyTrees() {}
-void LayerTreeHostImpl::SetTreeLayerFilterMutated(
- ElementId element_id,
- LayerTreeImpl* tree,
- const FilterOperations& filters) {
- if (!tree)
- return;
-
- PropertyTrees* property_trees = tree->property_trees();
- DCHECK_EQ(1u,
- property_trees->element_id_to_effect_node_index.count(element_id));
- const int effect_node_index =
- property_trees->element_id_to_effect_node_index[element_id];
- property_trees->effect_tree.OnFilterAnimated(filters, effect_node_index,
- tree);
-}
-
-void LayerTreeHostImpl::SetTreeLayerOpacityMutated(ElementId element_id,
- LayerTreeImpl* tree,
- float opacity) {
- if (!tree)
- return;
-
- PropertyTrees* property_trees = tree->property_trees();
- DCHECK_EQ(1u,
- property_trees->element_id_to_effect_node_index.count(element_id));
- const int effect_node_index =
- property_trees->element_id_to_effect_node_index[element_id];
- property_trees->effect_tree.OnOpacityAnimated(opacity, effect_node_index,
- tree);
-}
-
-void LayerTreeHostImpl::SetTreeLayerTransformMutated(
- ElementId element_id,
- LayerTreeImpl* tree,
- const gfx::Transform& transform) {
- if (!tree)
- return;
-
- PropertyTrees* property_trees = tree->property_trees();
- DCHECK_EQ(
- 1u, property_trees->element_id_to_transform_node_index.count(element_id));
- const int transform_node_index =
- property_trees->element_id_to_transform_node_index[element_id];
- property_trees->transform_tree.OnTransformAnimated(
- transform, transform_node_index, tree);
- if (LayerImpl* layer = tree->LayerByElementId(element_id))
- layer->set_was_ever_ready_since_last_transform_animation(false);
-}
-
void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated(
ElementId element_id,
LayerTreeImpl* tree,
@@ -4047,10 +4130,12 @@ void LayerTreeHostImpl::SetElementFilterMutated(
ElementListType list_type,
const FilterOperations& filters) {
if (list_type == ElementListType::ACTIVE) {
- SetTreeLayerFilterMutated(element_id, active_tree(), filters);
+ active_tree()->SetFilterMutated(element_id, filters);
} else {
- SetTreeLayerFilterMutated(element_id, pending_tree(), filters);
- SetTreeLayerFilterMutated(element_id, recycle_tree(), filters);
+ if (pending_tree())
+ pending_tree()->SetFilterMutated(element_id, filters);
+ if (recycle_tree())
+ recycle_tree()->SetFilterMutated(element_id, filters);
}
}
@@ -4058,10 +4143,12 @@ void LayerTreeHostImpl::SetElementOpacityMutated(ElementId element_id,
ElementListType list_type,
float opacity) {
if (list_type == ElementListType::ACTIVE) {
- SetTreeLayerOpacityMutated(element_id, active_tree(), opacity);
+ active_tree()->SetOpacityMutated(element_id, opacity);
} else {
- SetTreeLayerOpacityMutated(element_id, pending_tree(), opacity);
- SetTreeLayerOpacityMutated(element_id, recycle_tree(), opacity);
+ if (pending_tree())
+ pending_tree()->SetOpacityMutated(element_id, opacity);
+ if (recycle_tree())
+ recycle_tree()->SetOpacityMutated(element_id, opacity);
}
}
@@ -4070,10 +4157,12 @@ void LayerTreeHostImpl::SetElementTransformMutated(
ElementListType list_type,
const gfx::Transform& transform) {
if (list_type == ElementListType::ACTIVE) {
- SetTreeLayerTransformMutated(element_id, active_tree(), transform);
+ active_tree()->SetTransformMutated(element_id, transform);
} else {
- SetTreeLayerTransformMutated(element_id, pending_tree(), transform);
- SetTreeLayerTransformMutated(element_id, recycle_tree(), transform);
+ if (pending_tree())
+ pending_tree()->SetTransformMutated(element_id, transform);
+ if (recycle_tree())
+ recycle_tree()->SetTransformMutated(element_id, transform);
}
}
@@ -4094,13 +4183,75 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged(
ElementListType list_type,
const PropertyAnimationState& mask,
const PropertyAnimationState& state) {
+ // TODO(weiliangc): Most of the code is duplicated with LayerTeeHost version
+ // of function. Should try to share code.
LayerTreeImpl* tree =
list_type == ElementListType::ACTIVE ? active_tree() : pending_tree();
if (!tree)
return;
- LayerImpl* layer = tree->LayerByElementId(element_id);
- if (layer)
- layer->OnIsAnimatingChanged(mask, state);
+ PropertyTrees* property_trees = tree->property_trees();
+
+ for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
+ property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
+ if (!mask.currently_running[property] &&
+ !mask.potentially_animating[property])
+ continue;
+
+ switch (property) {
+ case TargetProperty::TRANSFORM:
+ if (TransformNode* transform_node =
+ property_trees->transform_tree.FindNodeFromElementId(
+ element_id)) {
+ if (mask.currently_running[property])
+ transform_node->is_currently_animating =
+ state.currently_running[property];
+ if (mask.potentially_animating[property]) {
+ transform_node->has_potential_animation =
+ state.potentially_animating[property];
+ transform_node->has_only_translation_animations =
+ mutator_host()->HasOnlyTranslationTransforms(element_id,
+ list_type);
+ property_trees->transform_tree.set_needs_update(true);
+ tree->set_needs_update_draw_properties();
+ // TODO(crbug.com/702777):
+ // was_ever_ready_since_last_transform_animation should not live on
+ // layers.
+ if (LayerImpl* layer = tree->LayerByElementId(element_id)) {
+ layer->set_was_ever_ready_since_last_transform_animation(false);
+ }
+ }
+ }
+ break;
+ case TargetProperty::OPACITY:
+ if (EffectNode* effect_node =
+ property_trees->effect_tree.FindNodeFromElementId(element_id)) {
+ if (mask.currently_running[property])
+ effect_node->is_currently_animating_opacity =
+ state.currently_running[property];
+ if (mask.potentially_animating[property]) {
+ effect_node->has_potential_opacity_animation =
+ state.potentially_animating[property];
+ property_trees->effect_tree.set_needs_update(true);
+ }
+ }
+ break;
+ case TargetProperty::FILTER:
+ if (EffectNode* effect_node =
+ property_trees->effect_tree.FindNodeFromElementId(element_id)) {
+ if (mask.currently_running[property])
+ effect_node->is_currently_animating_filter =
+ state.currently_running[property];
+ if (mask.potentially_animating[property])
+ effect_node->has_potential_filter_animation =
+ state.potentially_animating[property];
+ // Filter animation changes only the node, and the subtree does not
+ // care. There is no need to request update on property trees here.
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
@@ -4166,4 +4317,11 @@ void LayerTreeHostImpl::SetContextVisibility(bool is_visible) {
}
}
+void LayerTreeHostImpl::UpdateScrollSourceInfo(bool is_wheel_scroll) {
+ if (is_wheel_scroll)
+ has_scrolled_by_wheel_ = true;
+ else
+ has_scrolled_by_touch_ = true;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 704eb1ab922..0b72dc47333 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -17,14 +17,13 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
-#include "cc/base/cc_export.h"
#include "cc/base/synced_property.h"
-#include "cc/debug/micro_benchmark_controller_impl.h"
+#include "cc/benchmarks/micro_benchmark_controller_impl.h"
+#include "cc/cc_export.h"
#include "cc/input/browser_controls_offset_manager_client.h"
#include "cc/input/input_handler.h"
#include "cc/input/scrollbar_animation_controller.h"
#include "cc/layers/layer_collections.h"
-#include "cc/layers/render_pass_sink.h"
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame_sink_client.h"
#include "cc/output/context_cache_controller.h"
@@ -36,6 +35,8 @@
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/draw_result.h"
#include "cc/scheduler/video_frame_controller.h"
+#include "cc/surfaces/local_surface_id.h"
+#include "cc/surfaces/surface_id.h"
#include "cc/tiles/decoded_image_tracker.h"
#include "cc/tiles/image_decode_cache.h"
#include "cc/tiles/tile_manager.h"
@@ -152,7 +153,8 @@ class CC_EXPORT LayerTreeHostImpl
~LayerTreeHostImpl() override;
// InputHandler implementation
- void BindToClient(InputHandlerClient* client) override;
+ void BindToClient(InputHandlerClient* client,
+ bool wheel_scroll_latching_enabled) override;
InputHandler::ScrollStatus ScrollBegin(
ScrollState* scroll_state,
InputHandler::ScrollInputType type) override;
@@ -200,6 +202,7 @@ class CC_EXPORT LayerTreeHostImpl
bool GetScrollOffsetForLayer(int layer_id,
gfx::ScrollOffset* offset) override;
bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) override;
+ bool ScrollingShouldSwitchtoMainThread() override;
// BrowserControlsOffsetManagerClient implementation.
float TopControlsHeight() const override;
@@ -215,11 +218,12 @@ class CC_EXPORT LayerTreeHostImpl
resourceless_software_draw_ = true;
}
- struct CC_EXPORT FrameData : public RenderPassSink {
+ struct CC_EXPORT FrameData {
FrameData();
- ~FrameData() override;
+ ~FrameData();
void AsValueInto(base::trace_event::TracedValue* value) const;
+ std::vector<SurfaceId> embedded_surfaces;
std::vector<gfx::Rect> occluding_screen_space_rects;
std::vector<gfx::Rect> non_occluding_screen_space_rects;
RenderPassList render_passes;
@@ -227,9 +231,7 @@ class CC_EXPORT LayerTreeHostImpl
LayerImplList will_draw_layers;
bool has_no_damage;
bool may_contain_video;
-
- // RenderPassSink implementation.
- void AppendRenderPass(std::unique_ptr<RenderPass> render_pass) override;
+ BeginFrameAck begin_frame_ack;
private:
DISALLOW_COPY_AND_ASSIGN(FrameData);
@@ -257,15 +259,6 @@ class CC_EXPORT LayerTreeHostImpl
// virtual for testing.
virtual void InvalidateContentOnImplSide();
- void SetTreeLayerFilterMutated(ElementId element_id,
- LayerTreeImpl* tree,
- const FilterOperations& filters);
- void SetTreeLayerOpacityMutated(ElementId element_id,
- LayerTreeImpl* tree,
- float opacity);
- void SetTreeLayerTransformMutated(ElementId element_id,
- LayerTreeImpl* tree,
- const gfx::Transform& transform);
void SetTreeLayerScrollOffsetMutated(ElementId element_id,
LayerTreeImpl* tree,
const gfx::ScrollOffset& scroll_offset);
@@ -354,7 +347,7 @@ class CC_EXPORT LayerTreeHostImpl
std::unique_ptr<EvictionTilePriorityQueue> BuildEvictionQueue(
TreePriority tree_priority) override;
void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override;
- gfx::ColorSpace GetTileColorSpace() const override;
+ gfx::ColorSpace GetRasterColorSpace() const override;
void RequestImplSideInvalidation() override;
// ScrollbarAnimationControllerClient implementation.
@@ -603,6 +596,12 @@ class CC_EXPORT LayerTreeHostImpl
LayerImpl* ViewportMainScrollLayer();
+ void QueueImageDecode(sk_sp<const SkImage> image,
+ const base::Callback<void(bool)>& embedder_callback);
+ std::vector<base::Closure> TakeCompletedImageDecodeCallbacks();
+
+ void ClearImageCacheOnNavigation();
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -702,6 +701,18 @@ class CC_EXPORT LayerTreeHostImpl
base::TimeDelta delayed_by);
void SetContextVisibility(bool is_visible);
+ void ImageDecodeFinished(const base::Callback<void(bool)>& embedder_callback,
+ bool decode_succeeded);
+
+ // This function keeps track of sources of scrolls that are handled in the
+ // compositor side. The information gets shared by the main thread as part of
+ // the begin_main_frame_state. Finally Use counters are updated in the main
+ // thread side to keep track of the frequency of scrolling with different
+ // sources per page load. TODO(crbug.com/691886): Use GRC API to plumb the
+ // scroll source info for Use Counters.
+ void UpdateScrollSourceInfo(bool is_wheel_scroll);
+
+ bool IsScrolledBy(LayerImpl* child, ScrollNode* ancestor);
using UIResourceMap = std::unordered_map<UIResourceId, UIResourceData>;
UIResourceMap ui_resource_map_;
@@ -713,6 +724,8 @@ class CC_EXPORT LayerTreeHostImpl
CompositorFrameSink* compositor_frame_sink_;
+ LocalSurfaceId local_surface_id_;
+
// The following scoped variables must not outlive the
// |compositor_frame_sink_|.
// These should be transfered to ContextCacheController's
@@ -843,6 +856,22 @@ class CC_EXPORT LayerTreeHostImpl
std::unique_ptr<PendingTreeDurationHistogramTimer>
pending_tree_duration_timer_;
+ // The id of the scroll node to which scroll animations must latch.
+ // This gets reset at ScrollAnimatedBegin, and updated the first time that a
+ // scroll animation is created in ScrollAnimated.
+ int scroll_animating_latched_node_id_;
+
+ // These callbacks are stored here to be transfered to the main thread when we
+ // begin main frame. These callbacks must only be called on the main thread.
+ std::vector<base::Closure> completed_image_decode_callbacks_;
+
+ // These are used to transfer usage of touch and wheel scrolls to the main
+ // thread.
+ bool has_scrolled_by_wheel_;
+ bool has_scrolled_by_touch_;
+
+ bool touchpad_and_wheel_scroll_latching_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 5c12dbc07db..a52bdf7996c 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -30,6 +30,7 @@
#include "cc/layers/render_surface_impl.h"
#include "cc/layers/solid_color_layer_impl.h"
#include "cc/layers/solid_color_scrollbar_layer_impl.h"
+#include "cc/layers/surface_layer_impl.h"
#include "cc/layers/texture_layer_impl.h"
#include "cc/layers/video_layer_impl.h"
#include "cc/layers/viewport.h"
@@ -93,6 +94,19 @@ using media::VideoFrame;
namespace cc {
namespace {
+SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) {
+ return SurfaceId(
+ frame_sink_id,
+ LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u)));
+}
+
+struct TestFrameData : public LayerTreeHostImpl::FrameData {
+ TestFrameData() {
+ // Set ack to something valid, so DCHECKs don't complain.
+ begin_frame_ack = BeginFrameAck(0, 1, 1, true);
+ }
+};
+
class LayerTreeHostImplTest : public testing::Test,
public LayerTreeHostImplClient {
public:
@@ -115,7 +129,6 @@ class LayerTreeHostImplTest : public testing::Test,
LayerTreeSettings settings;
settings.minimum_occlusion_tracking_size = gfx::Size();
settings.renderer_settings.texture_id_allocation_chunk_size = 1;
- settings.verify_clip_tree_calculations = true;
settings.renderer_settings.buffer_to_texture_target_map =
DefaultBufferToTextureTargetMapForTesting();
return settings;
@@ -166,8 +179,7 @@ class LayerTreeHostImplTest : public testing::Test,
did_complete_page_scale_animation_ = true;
}
void OnDrawForCompositorFrameSink(bool resourceless_software_draw) override {
- std::unique_ptr<LayerTreeHostImpl::FrameData> frame(
- new LayerTreeHostImpl::FrameData);
+ std::unique_ptr<TestFrameData> frame(new TestFrameData);
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(frame.get()));
last_on_draw_render_passes_.clear();
RenderPass::CopyAll(frame->render_passes, &last_on_draw_render_passes_);
@@ -326,6 +338,8 @@ class LayerTreeHostImplTest : public testing::Test,
LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
inner_scroll->SetScrollClipLayer(inner_clip->id());
+ inner_scroll->SetElementId(
+ LayerIdToElementIdForTesting(inner_scroll->id()));
inner_scroll->SetBounds(content_size);
inner_scroll->SetPosition(gfx::PointF());
@@ -338,6 +352,8 @@ class LayerTreeHostImplTest : public testing::Test,
std::unique_ptr<LayerImpl> outer_scroll =
LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
outer_scroll->SetScrollClipLayer(outer_clip->id());
+ outer_scroll->SetElementId(
+ LayerIdToElementIdForTesting(outer_scroll->id()));
outer_scroll->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
@@ -401,9 +417,6 @@ class LayerTreeHostImplTest : public testing::Test,
inner_clip_layer->SetBounds(viewport_size);
host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size);
- // Needs to happen before building property trees as the latter propagates
- // these element ids to property tree nodes.
- host_impl_->active_tree()->SetElementIdsForTesting();
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->SetViewportSize(viewport_size);
@@ -420,6 +433,7 @@ class LayerTreeHostImplTest : public testing::Test,
std::unique_ptr<LayerImpl> layer =
LayerImpl::Create(host_impl_->active_tree(), id);
layer->SetScrollClipLayer(clip_layer->id());
+ layer->SetElementId(LayerIdToElementIdForTesting(layer->id()));
layer->SetDrawsContent(true);
layer->SetBounds(size);
clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2));
@@ -457,7 +471,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void DrawFrame() {
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -481,7 +495,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void DrawOneFrame() {
- LayerTreeHostImpl::FrameData frame_data;
+ TestFrameData frame_data;
host_impl_->PrepareToDraw(&frame_data);
host_impl_->DidDrawAllLayers(frame_data);
}
@@ -531,7 +545,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool did_request_impl_side_invalidation_;
base::Closure animation_task_;
base::TimeDelta requested_animation_delay_;
- std::unique_ptr<LayerTreeHostImpl::FrameData> last_on_draw_frame_;
+ std::unique_ptr<TestFrameData> last_on_draw_frame_;
RenderPassList last_on_draw_render_passes_;
scoped_refptr<AnimationTimeline> timeline_;
std::unique_ptr<base::Thread> image_worker_;
@@ -545,6 +559,58 @@ class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest {
}
};
+class TestInputHandlerClient : public InputHandlerClient {
+ public:
+ TestInputHandlerClient()
+ : page_scale_factor_(0.f),
+ min_page_scale_factor_(-1.f),
+ max_page_scale_factor_(-1.f) {}
+ ~TestInputHandlerClient() override {}
+
+ // InputHandlerClient implementation.
+ void WillShutdown() override {}
+ void Animate(base::TimeTicks time) override {}
+ void MainThreadHasStoppedFlinging() override {}
+ void ReconcileElasticOverscrollAndRootScroll() override {}
+ void UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) override {
+ DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
+ DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
+ last_set_scroll_offset_ = total_scroll_offset;
+ max_scroll_offset_ = max_scroll_offset;
+ scrollable_size_ = scrollable_size;
+ page_scale_factor_ = page_scale_factor;
+ min_page_scale_factor_ = min_page_scale_factor;
+ max_page_scale_factor_ = max_page_scale_factor;
+ }
+ void DeliverInputForBeginFrame() override {}
+
+ gfx::ScrollOffset last_set_scroll_offset() { return last_set_scroll_offset_; }
+
+ gfx::ScrollOffset max_scroll_offset() const { return max_scroll_offset_; }
+
+ gfx::SizeF scrollable_size() const { return scrollable_size_; }
+
+ float page_scale_factor() const { return page_scale_factor_; }
+
+ float min_page_scale_factor() const { return min_page_scale_factor_; }
+
+ float max_page_scale_factor() const { return max_page_scale_factor_; }
+
+ private:
+ gfx::ScrollOffset last_set_scroll_offset_;
+ gfx::ScrollOffset max_scroll_offset_;
+ gfx::SizeF scrollable_size_;
+ float page_scale_factor_;
+ float min_page_scale_factor_;
+ float max_page_scale_factor_;
+};
+
TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
// Note: It is not possible to disable the renderer once it has been set,
// so we do not need to test that disabling the renderer notifies us
@@ -661,6 +727,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
root_clip->test_properties()->AddChild(std::move(root_owned));
root->SetBounds(gfx::Size(110, 110));
root->SetScrollClipLayer(root_clip->id());
+ root->SetElementId(LayerIdToElementIdForTesting(root->id()));
root->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(root->id(), scroll_offset);
@@ -966,6 +1033,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) {
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
scroll->SetBounds(scroll_content_size);
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
@@ -1037,6 +1105,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
scroll->SetBounds(scroll_content_size);
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
std::unique_ptr<SolidColorScrollbarLayerImpl> drawn_scrollbar =
@@ -1281,6 +1350,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
overflow->SetBounds(overflow_size);
overflow->SetScrollClipLayer(
scroll_layer->test_properties()->parent->test_properties()->parent->id());
+ overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id()));
overflow->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->id(),
@@ -1628,7 +1698,7 @@ TEST_F(LayerTreeHostImplTest, AnimationMarksLayerNotReady) {
host_impl_->ResetRequiresHighResToDraw();
// Child layer has an animating transform but missing tiles.
- FakeLayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
DrawResult result = host_impl_->PrepareToDraw(&frame);
EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result);
host_impl_->DidDrawAllLayers(frame);
@@ -2105,7 +2175,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
std::unique_ptr<std::set<LayerImpl*>> scroll_children(
new std::set<LayerImpl*>);
scroll_children->insert(child_clip);
- parent->test_properties()->scroll_children.reset(scroll_children.release());
+ parent->test_properties()->scroll_children = std::move(scroll_children);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
DrawFrame();
@@ -2791,15 +2861,19 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->DidBecomeActive();
DrawFrame();
+
+ // SetScrollLayerId will initialize the scrollbar which will cause it to
+ // show and request a redraw.
+ did_request_redraw_ = false;
}
void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
LayerTreeSettings settings = DefaultSettings();
settings.scrollbar_animator = animator;
- settings.scrollbar_show_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_duration =
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_out_resize_delay =
base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20);
// If no animator is set, scrollbar won't show and no animation is expected.
bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR;
@@ -2831,6 +2905,25 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ // For Aura Overlay Scrollbar, if no scroll happened during a scroll
+ // gesture, shows scrollbars and schedules a delay fade out.
+ host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ InputHandler::WHEEL);
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 0)).get());
+ host_impl_->ScrollEnd(EndState().get());
+ EXPECT_FALSE(did_request_next_frame_);
+ EXPECT_FALSE(did_request_redraw_);
+ if (animator == LayerTreeSettings::AURA_OVERLAY) {
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
+ requested_animation_delay_);
+ EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ requested_animation_delay_ = base::TimeDelta();
+ animation_task_ = base::Closure();
+ } else {
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ }
+
// Before the scrollbar animation exists, we should not get redraws.
BeginFrameArgs begin_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2, fake_now);
@@ -2938,7 +3031,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->DidFinishImplFrame();
}
- // Scrollbar animation is not triggered unnecessarily.
+ // For Andrdoid, scrollbar animation is not triggered unnecessarily.
+ // For Aura Overlay Scrollbar, scrollbar appears even if scroll offset did
+ // not change.
host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(5, 0)).get());
@@ -2951,8 +3046,16 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->ScrollEnd(EndState().get());
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
- EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
- EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ if (animator == LayerTreeSettings::AURA_OVERLAY) {
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
+ requested_animation_delay_);
+ EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ requested_animation_delay_ = base::TimeDelta();
+ animation_task_ = base::Closure();
+ } else {
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+ }
// Changing page scale triggers scrollbar animation.
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
@@ -2989,10 +3092,8 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
LayerTreeSettings settings = DefaultSettings();
settings.scrollbar_animator = animator;
- settings.scrollbar_show_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_duration =
- base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20);
gfx::Size content_size(100, 100);
// If no animator is set, scrollbar won't show and no animation is expected.
@@ -3085,6 +3186,75 @@ TEST_F(LayerTreeHostImplTestScrollbarOpacity, NoAnimator) {
RunTest(LayerTreeSettings::NO_ANIMATOR);
}
+TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
+ LayerTreeSettings settings = DefaultSettings();
+ settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY;
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20);
+ gfx::Size content_size(100, 100);
+
+ CreateHostImpl(settings, CreateCompositorFrameSink());
+ host_impl_->CreatePendingTree();
+ CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size);
+ std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
+ SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400,
+ VERTICAL, 10, 0, false, true);
+ scrollbar->test_properties()->opacity = 0.f;
+ LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer();
+ LayerImpl* container =
+ host_impl_->pending_tree()->InnerViewportContainerLayer();
+ scrollbar->SetScrollLayerId(scroll->id());
+ container->test_properties()->AddChild(std::move(scrollbar));
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+ host_impl_->ActivateSyncTree();
+
+ ScrollbarAnimationController* scrollbar_controller =
+ host_impl_->ScrollbarAnimationControllerForId(scroll->id());
+
+ // Scrollbars will flash shown but we should have a fade out animation
+ // queued. Run it and fade out the scrollbars.
+ {
+ ASSERT_FALSE(animation_task_.Equals(base::Closure()));
+ ASSERT_FALSE(animation_task_.IsCancelled());
+ animation_task_.Run();
+
+ base::TimeTicks fake_now = base::TimeTicks::Now();
+ scrollbar_controller->Animate(fake_now);
+ fake_now += settings.scrollbar_fade_delay;
+ scrollbar_controller->Animate(fake_now);
+
+ ASSERT_TRUE(scrollbar_controller->ScrollbarsHidden());
+ }
+
+ // Move the mouse over the scrollbar region. This should post a delayed fade
+ // in task. Execute it to show the scrollbars.
+ {
+ animation_task_ = base::Closure();
+ scrollbar_controller->DidMouseMoveNear(VERTICAL, 0);
+ ASSERT_FALSE(animation_task_.Equals(base::Closure()));
+ ASSERT_FALSE(animation_task_.IsCancelled());
+ }
+
+ // The fade in task should cause the scrollbars to show. Ensure that we
+ // requested a redraw and a commit.
+ {
+ did_request_redraw_ = false;
+ did_request_commit_ = false;
+ ASSERT_TRUE(scrollbar_controller->ScrollbarsHidden());
+ animation_task_.Run();
+
+ base::TimeTicks fake_now = base::TimeTicks::Now();
+ scrollbar_controller->Animate(fake_now);
+ fake_now += settings.scrollbar_fade_duration;
+ scrollbar_controller->Animate(fake_now);
+
+ ASSERT_FALSE(scrollbar_controller->ScrollbarsHidden());
+ EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_commit_);
+ }
+}
+
TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) {
LayerTreeSettings settings = DefaultSettings();
CreateHostImpl(settings, CreateCompositorFrameSink());
@@ -3122,9 +3292,8 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) {
TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
LayerTreeSettings settings = DefaultSettings();
settings.scrollbar_animator = LayerTreeSettings::ANDROID_OVERLAY;
- settings.scrollbar_show_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_delay = base::TimeDelta::FromMilliseconds(20);
- settings.scrollbar_fade_out_duration = base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20);
CreateHostImpl(settings, CreateCompositorFrameSink());
gfx::Size viewport_size(300, 200);
@@ -3192,6 +3361,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
// Check scrollbar registration on a sublayer.
child->SetScrollClipLayer(child_clip->id());
+ child->SetElementId(LayerIdToElementIdForTesting(child->id()));
child_clip->test_properties()->AddChild(std::move(child));
root_scroll->test_properties()->AddChild(std::move(child_clip));
EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
@@ -3243,9 +3413,8 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
float device_scale_factor) {
LayerTreeSettings settings = DefaultSettings();
- settings.scrollbar_show_delay = base::TimeDelta::FromMilliseconds(500);
- settings.scrollbar_fade_out_delay = base::TimeDelta::FromMilliseconds(500);
- settings.scrollbar_fade_out_duration = base::TimeDelta::FromMilliseconds(300);
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY;
gfx::Size viewport_size(300, 200);
@@ -3290,31 +3459,24 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
host_impl_->MouseMoveAt(
gfx::Point(15 + kMouseDistanceToTriggerAnimation * 2, 1));
- EXPECT_FALSE(
- scrollbar_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_FALSE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(15 + kMouseDistanceToTriggerAnimation - 1, 50));
- EXPECT_TRUE(
- scrollbar_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(15 + kMouseDistanceToTriggerAnimation, 100));
- EXPECT_FALSE(
- scrollbar_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_FALSE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL));
did_request_redraw_ = false;
- EXPECT_FALSE(
- scrollbar_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_FALSE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(gfx::Point(10, 100));
- EXPECT_TRUE(
- scrollbar_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(gfx::Point(10, 120));
- EXPECT_TRUE(
- scrollbar_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(gfx::Point(150, 120));
- EXPECT_FALSE(
- scrollbar_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_FALSE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL));
}
TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
@@ -3325,6 +3487,43 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
SetupMouseMoveAtWithDeviceScale(2.f);
}
+// This test verifies that only SurfaceLayers in the viewport are included
+// in CompositorFrameMetadata's |embedded_surfaces|.
+TEST_F(LayerTreeHostImplTest, EmbeddedSurfacesInMetadata) {
+ SetupScrollAndContentsLayers(gfx::Size(100, 100));
+ host_impl_->SetViewportSize(gfx::Size(50, 50));
+ LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
+
+ std::vector<SurfaceId> children = {MakeSurfaceId(FrameSinkId(1, 1), 1),
+ MakeSurfaceId(FrameSinkId(2, 2), 2),
+ MakeSurfaceId(FrameSinkId(3, 3), 3)};
+ for (size_t i = 0; i < children.size(); ++i) {
+ std::unique_ptr<SurfaceLayerImpl> child =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), i + 6);
+ child->SetPosition(gfx::PointF(25.f * i, 0.f));
+ child->SetBounds(gfx::Size(1, 1));
+ child->SetDrawsContent(true);
+ child->SetPrimarySurfaceInfo(
+ SurfaceInfo(children[i], 1.f /* device_scale_factor */,
+ gfx::Size(10, 10) /* size_in_pixels */));
+ root->test_properties()->AddChild(std::move(child));
+ }
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+ DrawFrame();
+
+ FakeCompositorFrameSink* fake_compositor_frame_sink =
+ static_cast<FakeCompositorFrameSink*>(
+ host_impl_->compositor_frame_sink());
+ const CompositorFrameMetadata& metadata =
+ fake_compositor_frame_sink->last_sent_frame()->metadata;
+ EXPECT_THAT(metadata.embedded_surfaces,
+ testing::UnorderedElementsAre(children[0], children[1]));
+ EXPECT_THAT(
+ metadata.referenced_surfaces,
+ testing::UnorderedElementsAre(children[0], children[1], children[2]));
+}
+
TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
SetupScrollAndContentsLayers(gfx::Size(100, 100));
host_impl_->SetViewportSize(gfx::Size(50, 50));
@@ -3526,7 +3725,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
{
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -3539,7 +3738,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
host_impl_->SetViewportDamage(gfx::Rect(10, 10));
{
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
layer->set_will_draw_returns_false();
layer->ClearDidDrawCheck();
@@ -3572,7 +3771,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
layer->SetBounds(gfx::Size(10, 10));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_FALSE(layer->will_draw_called());
EXPECT_FALSE(layer->did_draw_called());
@@ -3629,7 +3828,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
top_layer->SetContentsOpaque(true);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_FALSE(occluded_layer->will_draw_called());
EXPECT_FALSE(occluded_layer->did_draw_called());
@@ -3671,9 +3870,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
EXPECT_FALSE(layer1->did_draw_called());
EXPECT_FALSE(layer2->did_draw_called());
- LayerTreeHostImpl::FrameData frame;
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
- *host_impl_->active_tree()->begin());
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -3842,7 +4039,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) {
root->test_properties()->force_render_surface = true;
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -3869,7 +4066,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) {
if (testcase.high_res_required)
host_impl_->SetRequiresHighResToDraw();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(testcase.expected_result, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -4038,6 +4235,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
root_clip->SetBounds(inner_viewport_size);
root->SetScrollClipLayer(root_clip->id());
+ root->SetElementId(LayerIdToElementIdForTesting(root->id()));
root->SetBounds(outer_viewport_size);
root->SetPosition(gfx::PointF());
root->SetDrawsContent(false);
@@ -4045,6 +4243,8 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
root->test_properties()->is_container_for_fixed_position_layers = true;
outer_clip->SetBounds(outer_viewport_size);
outer_scroll->SetScrollClipLayer(outer_clip->id());
+ outer_scroll->SetElementId(
+ LayerIdToElementIdForTesting(outer_scroll->id()));
outer_scroll->SetBounds(scroll_layer_size);
outer_scroll->SetPosition(gfx::PointF());
outer_scroll->SetDrawsContent(false);
@@ -4398,6 +4598,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
child_clip->SetBounds(sub_content_layer_size);
child->SetScrollClipLayer(child_clip->id());
+ child->SetElementId(LayerIdToElementIdForTesting(child->id()));
child->SetBounds(sub_content_size);
child->SetPosition(gfx::PointF());
child->SetDrawsContent(true);
@@ -4944,6 +5145,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
std::unique_ptr<LayerImpl> scroll_layer =
LayerImpl::Create(host_impl_->active_tree(), 12);
scroll_layer->SetScrollClipLayer(scroll_clip_layer->id());
+ scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
scroll_layer->SetBounds(contents_size);
scroll_layer->SetPosition(gfx::PointF());
scroll_layer->test_properties()->AddChild(std::move(content_layer));
@@ -5229,7 +5431,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
// Make sure all the layers are drawn with the page scale delta applied, i.e.,
// the page scale delta on the root layer is applied hierarchically.
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -5349,6 +5551,106 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
}
}
+TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) {
+ // Enable wheel scroll latching flag.
+ TestInputHandlerClient input_handler_client;
+ host_impl_->BindToClient(&input_handler_client, true);
+
+ // Scroll a child layer beyond its maximum scroll range and make sure the
+ // parent layer isn't scrolled.
+ gfx::Size surface_size(100, 100);
+ gfx::Size content_size(150, 150);
+
+ LayerImpl* root =
+ CreateBasicVirtualViewportLayers(surface_size, surface_size);
+ root->test_properties()->force_render_surface = true;
+
+ root->test_properties()->force_render_surface = true;
+ std::unique_ptr<LayerImpl> grand_child =
+ CreateScrollableLayer(13, content_size, root);
+
+ std::unique_ptr<LayerImpl> child =
+ CreateScrollableLayer(12, content_size, root);
+ LayerImpl* grand_child_layer = grand_child.get();
+ child->test_properties()->AddChild(std::move(grand_child));
+
+ LayerImpl* child_layer = child.get();
+ root->test_properties()->AddChild(std::move(child));
+ host_impl_->active_tree()->SetElementIdsForTesting();
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+ host_impl_->active_tree()->DidBecomeActive();
+
+ grand_child_layer->layer_tree_impl()
+ ->property_trees()
+ ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
+ gfx::ScrollOffset(0, 30));
+ child_layer->layer_tree_impl()
+ ->property_trees()
+ ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
+ gfx::ScrollOffset(0, 50));
+
+ host_impl_->SetViewportSize(surface_size);
+ DrawFrame();
+
+ base::TimeTicks start_time =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(10);
+
+ BeginFrameArgs begin_frame_args =
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
+
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, -100)).thread);
+
+ begin_frame_args.frame_time = start_time;
+ begin_frame_args.sequence_number++;
+ host_impl_->WillBeginImplFrame(begin_frame_args);
+ host_impl_->Animate();
+ host_impl_->UpdateAnimationState(true);
+
+ EXPECT_EQ(gfx::ScrollOffset(0, 30), grand_child_layer->CurrentScrollOffset());
+ host_impl_->DidFinishImplFrame();
+
+ begin_frame_args.frame_time =
+ start_time + base::TimeDelta::FromMilliseconds(200);
+ begin_frame_args.sequence_number++;
+ host_impl_->WillBeginImplFrame(begin_frame_args);
+ host_impl_->Animate();
+ host_impl_->UpdateAnimationState(true);
+
+ EXPECT_EQ(gfx::ScrollOffset(0, 0), grand_child_layer->CurrentScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(0, 50), child_layer->CurrentScrollOffset());
+ host_impl_->DidFinishImplFrame();
+
+ // Second ScrollAnimated should still latch to the grand_child_layer.
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, -100)).thread);
+
+ begin_frame_args.frame_time =
+ start_time + base::TimeDelta::FromMilliseconds(250);
+ begin_frame_args.sequence_number++;
+ host_impl_->WillBeginImplFrame(begin_frame_args);
+ host_impl_->Animate();
+ host_impl_->UpdateAnimationState(true);
+ host_impl_->DidFinishImplFrame();
+
+ begin_frame_args.frame_time =
+ start_time + base::TimeDelta::FromMilliseconds(450);
+ begin_frame_args.sequence_number++;
+ host_impl_->WillBeginImplFrame(begin_frame_args);
+ host_impl_->Animate();
+ host_impl_->UpdateAnimationState(true);
+
+ EXPECT_EQ(gfx::ScrollOffset(0, 0), grand_child_layer->CurrentScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(0, 50), child_layer->CurrentScrollOffset());
+ host_impl_->DidFinishImplFrame();
+
+ // Tear down the LayerTreeHostImpl before the InputHandlerClient.
+ host_impl_->ReleaseCompositorFrameSink();
+ host_impl_ = nullptr;
+}
+
TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
// Scroll a child layer beyond its maximum scroll range and make sure the
// the scroll doesn't bubble up to the parent layer.
@@ -5894,58 +6196,6 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
inner_viewport_scroll_layer->MaxScrollOffset());
}
-class TestInputHandlerClient : public InputHandlerClient {
- public:
- TestInputHandlerClient()
- : page_scale_factor_(0.f),
- min_page_scale_factor_(-1.f),
- max_page_scale_factor_(-1.f) {}
- ~TestInputHandlerClient() override {}
-
- // InputHandlerClient implementation.
- void WillShutdown() override {}
- void Animate(base::TimeTicks time) override {}
- void MainThreadHasStoppedFlinging() override {}
- void ReconcileElasticOverscrollAndRootScroll() override {}
- void UpdateRootLayerStateForSynchronousInputHandler(
- const gfx::ScrollOffset& total_scroll_offset,
- const gfx::ScrollOffset& max_scroll_offset,
- const gfx::SizeF& scrollable_size,
- float page_scale_factor,
- float min_page_scale_factor,
- float max_page_scale_factor) override {
- DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
- DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
- last_set_scroll_offset_ = total_scroll_offset;
- max_scroll_offset_ = max_scroll_offset;
- scrollable_size_ = scrollable_size;
- page_scale_factor_ = page_scale_factor;
- min_page_scale_factor_ = min_page_scale_factor;
- max_page_scale_factor_ = max_page_scale_factor;
- }
- void DeliverInputForBeginFrame() override {}
-
- gfx::ScrollOffset last_set_scroll_offset() { return last_set_scroll_offset_; }
-
- gfx::ScrollOffset max_scroll_offset() const { return max_scroll_offset_; }
-
- gfx::SizeF scrollable_size() const { return scrollable_size_; }
-
- float page_scale_factor() const { return page_scale_factor_; }
-
- float min_page_scale_factor() const { return min_page_scale_factor_; }
-
- float max_page_scale_factor() const { return max_page_scale_factor_; }
-
- private:
- gfx::ScrollOffset last_set_scroll_offset_;
- gfx::ScrollOffset max_scroll_offset_;
- gfx::SizeF scrollable_size_;
- float page_scale_factor_;
- float min_page_scale_factor_;
- float max_page_scale_factor_;
-};
-
TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
TestInputHandlerClient scroll_watcher;
host_impl_->SetViewportSize(gfx::Size(10, 20));
@@ -5955,7 +6205,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
clip_layer->SetBounds(gfx::Size(10, 20));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- host_impl_->BindToClient(&scroll_watcher);
+ host_impl_->BindToClient(&scroll_watcher, false);
gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
scroll_layer->layer_tree_impl()
@@ -6078,7 +6328,7 @@ TEST_F(LayerTreeHostImplTest,
host_impl_->active_tree()->BuildPropertyTreesForTesting();
// Check scroll delta reflected in layer.
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -6527,6 +6777,7 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) {
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
scroll->SetBounds(gfx::Size(400, 400));
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
scroll_layer = scroll.get();
@@ -6617,6 +6868,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
scroll->SetBounds(gfx::Size(400, 400));
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12);
@@ -6627,6 +6879,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13);
scroll2->SetBounds(gfx::Size(500, 500));
scroll2->SetScrollClipLayer(clip2->id());
+ scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id()));
scroll2->SetDrawsContent(true);
scroll_layer = scroll.get();
@@ -6748,6 +7001,7 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
scroll->SetBounds(gfx::Size(1200, 1200));
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
outer_scroll_layer = scroll.get();
@@ -6763,6 +7017,7 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15);
scroll2->SetBounds(gfx::Size(1200, 1200));
scroll2->SetScrollClipLayer(clip2->id());
+ scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id()));
scroll2->SetDrawsContent(true);
sibling_scroll_layer = scroll2.get();
@@ -7027,7 +7282,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]);
layer1->SetPosition(gfx::PointF(2.f, 2.f));
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
// Opaque layer, drawn without blending.
layer1->SetContentsOpaque(true);
@@ -7142,8 +7397,6 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false);
layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
- host_impl_->active_tree()->root_layer_for_testing());
host_impl_->active_tree()->BuildPropertyTreesForTesting();
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
@@ -7269,7 +7522,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) {
host_impl->active_tree()->BuildPropertyTreesForTesting();
host_impl->active_tree()->set_needs_update_draw_properties();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
host_impl->DrawLayers(&frame);
host_impl->DidDrawAllLayers(frame);
@@ -7359,7 +7612,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
ASSERT_EQ(1u, frame.render_passes.size());
@@ -7393,7 +7646,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
void TestEmptyLayer() {
SetUpEmptylayer();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
VerifyEmptyLayerRenderPasses(frame.render_passes);
host_impl_->DidDrawAllLayers(frame);
@@ -7430,7 +7683,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
void TestLayerInMiddleOfViewport() {
SetUpLayerInMiddleOfViewport();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
VerifyLayerInMiddleOfViewport(frame.render_passes);
host_impl_->DidDrawAllLayers(frame);
@@ -7466,7 +7719,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
void TestLayerIsLargerThanViewport() {
SetUpLayerIsLargerThanViewport();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
VerifyLayerIsLargerThanViewport(frame.render_passes);
host_impl_->DidDrawAllLayers(frame);
@@ -7664,7 +7917,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
// First frame, the entire screen should get swapped.
EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
@@ -7726,7 +7979,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_EQ(1u, frame.render_surface_layer_list->size());
@@ -7845,7 +8098,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
DefaultSettings(), true, this, &task_runner_provider_, &task_graph_runner,
&stats_instrumentation_, compositor_frame_sink.get());
{
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
// Verify all quads have been computed
@@ -7874,7 +8127,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
DefaultSettings(), false, this, &task_runner_provider_,
&task_graph_runner, &stats_instrumentation_, compositor_frame_sink.get());
{
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
// Verify all quads have been computed
@@ -7920,7 +8173,7 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
EXPECT_EQ(0u, context3d->NumTextures());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -7948,7 +8201,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
// Verify one quad is drawn when transparent background set is not set.
host_impl_->active_tree()->set_has_transparent_background(false);
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
{
const auto& root_pass = frame.render_passes.back();
@@ -7982,7 +8235,7 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest {
void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) {
bool expect_to_draw = !expected_damage.IsEmpty();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
if (!expect_to_draw) {
@@ -8024,6 +8277,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
+ root->SetBackgroundColor(SK_ColorRED);
root->test_properties()->force_render_surface = true;
// Child layer is in the bottom right corner.
@@ -8032,6 +8286,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
child->SetPosition(gfx::PointF(9.f, 9.f));
child->SetBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
+ child->SetBackgroundColor(SK_ColorRED);
root->test_properties()->AddChild(std::move(child));
host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
@@ -8100,6 +8355,8 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
gfx::ScrollOffset scroll_offset(100000, 0);
scrolling_layer->SetScrollClipLayer(root->id());
+ scrolling_layer->SetElementId(
+ LayerIdToElementIdForTesting(scrolling_layer->id()));
host_impl_->pending_tree()->BuildPropertyTreesForTesting();
scrolling_layer->layer_tree_impl()
@@ -8112,7 +8369,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
ASSERT_EQ(1u, frame.render_passes.size());
@@ -8147,7 +8404,7 @@ TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
{
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -8301,12 +8558,36 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) {
}
}
-TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
+namespace {
+void ExpectFullDamageAndDraw(LayerTreeHostImpl* host_impl) {
+ gfx::Rect full_frame_damage(host_impl->DeviceViewport().size());
+ TestFrameData frame;
+ EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
+ ASSERT_EQ(1u, frame.render_passes.size());
+ const RenderPass* root_render_pass = frame.render_passes.back().get();
+ EXPECT_EQ(full_frame_damage, root_render_pass->damage_rect);
+ EXPECT_TRUE(host_impl->DrawLayers(&frame));
+ host_impl->DidDrawAllLayers(frame);
+}
+} // namespace
+
+TEST_F(LayerTreeHostImplTestDrawAndTestDamage,
+ RequireHighResAndRedrawWhenVisible) {
ASSERT_TRUE(host_impl_->active_tree());
+ std::unique_ptr<SolidColorLayerImpl> root =
+ SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
+ root->SetBackgroundColor(SK_ColorRED);
+ SetupRootLayerImpl(std::move(root));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
// RequiresHighResToDraw is set when new output surface is used.
EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
+ // Expect full frame damage for first frame.
+ EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get()));
+
host_impl_->ResetRequiresHighResToDraw();
host_impl_->SetVisible(false);
@@ -8319,8 +8600,12 @@ TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
host_impl_->ResetRequiresHighResToDraw();
EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
+ did_request_redraw_ = false;
host_impl_->SetVisible(true);
EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
+ // Expect redraw and full frame damage when becoming visible.
+ EXPECT_TRUE(did_request_redraw_);
+ EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get()));
}
TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
@@ -8432,7 +8717,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
// correct width/height are passed directly to UIResourceBitmap.
SkImageInfo info =
SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType);
- sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::NewAllocate(info, 0, 0));
+ sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::MakeAllocate(info, 0, 0));
pixel_ref->setImmutable();
UIResourceBitmap bitmap(std::move(pixel_ref), size);
UIResourceId ui_resource_id = 1;
@@ -8456,6 +8741,8 @@ class FrameSinkClient : public TestCompositorFrameSinkClient {
return FakeOutputSurface::Create3d(std::move(display_context_provider_));
}
+ void DisplayReceivedLocalSurfaceId(
+ const LocalSurfaceId& local_surface_id) override {}
void DisplayReceivedCompositorFrame(const CompositorFrame& frame) override {}
void DisplayWillDrawAndSwap(bool will_draw_and_swap,
const RenderPassList& render_passes) override {}
@@ -8487,7 +8774,7 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
base::Bind(&ShutdownReleasesContext_Callback)));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -8836,7 +9123,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_TRUE(host_impl_->DrawLayers(&frame));
host_impl_->DidDrawAllLayers(frame);
@@ -8880,7 +9167,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
host_impl_->SetNeedsRedraw();
gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_TRUE(host_impl_->DrawLayers(&frame));
host_impl_->DidDrawAllLayers(frame);
@@ -9550,6 +9837,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
scroll->SetBounds(scroll_content_size);
scroll->SetScrollClipLayer(clip->id());
+ scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id()));
scroll->SetDrawsContent(true);
scroll_layer = scroll.get();
@@ -9611,6 +9899,8 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
inner_scroll->SetScrollClipLayer(inner_clip->id());
+ inner_scroll->SetElementId(
+ LayerIdToElementIdForTesting(inner_scroll->id()));
inner_scroll->SetBounds(outer_viewport);
inner_scroll->SetPosition(gfx::PointF());
@@ -9623,6 +9913,8 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
std::unique_ptr<LayerImpl> outer_scroll =
LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
outer_scroll->SetScrollClipLayer(outer_clip->id());
+ outer_scroll->SetElementId(
+ LayerIdToElementIdForTesting(outer_scroll->id()));
outer_scroll->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
@@ -10065,26 +10357,31 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) {
EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
}
-// We will force the touch event handler to be passive if we touch on a
-// layer which is the current scrolling layer or its descendant.
-TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) {
+// We will force the touch event handler to be passive if we touch on a layer
+// which is the current scrolling layer.
+TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) {
gfx::Size surface_size(100, 100);
- gfx::Size inner_size(50, 50);
+ gfx::Size content_size(200, 200);
LayerImpl* root =
CreateBasicVirtualViewportLayers(surface_size, surface_size);
root->test_properties()->force_render_surface = true;
+ // A div layer which has an event handler.
std::unique_ptr<LayerImpl> child =
CreateScrollableLayer(26, surface_size, root);
LayerImpl* child_layer = child.get();
+ // The layer tree should create a layer for the div layer, which is the
+ // actual scrolling layer.
std::unique_ptr<LayerImpl> grand_child =
- CreateScrollableLayer(27, inner_size, root);
+ CreateScrollableLayer(27, content_size, root);
LayerImpl* grand_child_layer = grand_child.get();
+
child->test_properties()->AddChild(std::move(grand_child));
root->test_properties()->AddChild(std::move(child));
+ host_impl_->SetViewportSize(surface_size);
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->DidBecomeActive();
DrawFrame();
@@ -10094,10 +10391,9 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) {
EXPECT_EQ(InputHandler::TouchStartEventListenerType::NO_HANDLER,
host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 10)));
child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
- grand_child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER,
host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 10)));
- // Flinging the child layer.
+ // Flinging the grand_child layer.
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
->ScrollBegin(BeginState(gfx::Point(60, 60)).get(),
@@ -10105,20 +10401,78 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) {
.thread);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_->FlingScrollBegin().thread);
- EXPECT_EQ(child_layer->scroll_tree_index(),
+ EXPECT_EQ(grand_child_layer->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
- // Touch on the child layer, which is an active fling layer, the touch
+ // Touch on the grand_child layer, which is an active fling layer, the touch
// event handler will force to be passive.
EXPECT_EQ(
InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER,
host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(70, 80)));
- // Touch on the grand child layer, which is a descendant of an active fling
- // layer, the touch event handler will force to be passive.
+ }
+}
+
+// We will force the touch event handler to be passive if we touch on a layer
+// which is a descendant of the current scrolling layer. If we touch on its
+// ancestor, then the touch event handler will still be blocked.
+TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) {
+ gfx::Size surface_size(100, 100);
+ gfx::Size content_size(200, 200);
+ gfx::Size inner_size(50, 50);
+
+ LayerImpl* root =
+ CreateBasicVirtualViewportLayers(surface_size, surface_size);
+ root->test_properties()->force_render_surface = true;
+
+ // A div layer which has an event handler.
+ std::unique_ptr<LayerImpl> child =
+ CreateScrollableLayer(26, surface_size, root);
+ LayerImpl* child_layer = child.get();
+
+ // The layer tree should create a layer for the div layer, which is the
+ // actual scrolling layer.
+ std::unique_ptr<LayerImpl> grand_child =
+ CreateScrollableLayer(27, content_size, root);
+ LayerImpl* grand_child_layer = grand_child.get();
+
+ // A child scrollable layer inside grand_child_layer.
+ std::unique_ptr<LayerImpl> great_grand_child =
+ CreateScrollableLayer(28, inner_size, root);
+ LayerImpl* great_grand_child_layer = great_grand_child.get();
+
+ grand_child->test_properties()->AddChild(std::move(great_grand_child));
+ child->test_properties()->AddChild(std::move(grand_child));
+ root->test_properties()->AddChild(std::move(child));
+
+ host_impl_->SetViewportSize(surface_size);
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+ host_impl_->active_tree()->DidBecomeActive();
+ DrawFrame();
+
+ {
+ child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
+ grand_child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
+ // Flinging the grand_child layer.
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(60, 60)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_->FlingScrollBegin().thread);
+ EXPECT_EQ(grand_child_layer->scroll_tree_index(),
+ host_impl_->CurrentlyScrollingNode()->id);
+ // Touch on the grand_child layer, which is an active fling layer, the touch
+ // event handler will force to be passive.
+ EXPECT_EQ(
+ InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER,
+ host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(70, 80)));
+ // Touch on the great_grand_child_layer layer, which is the child of the
+ // active fling layer, the touch event handler will force to be passive.
EXPECT_EQ(
InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER,
host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(20, 30)));
- // Now flinging on the grand child layer.
+ // Now flinging on the great_grand_child_layer.
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
@@ -10126,9 +10480,9 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) {
.thread);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_->FlingScrollBegin().thread);
- EXPECT_EQ(grand_child_layer->scroll_tree_index(),
+ EXPECT_EQ(great_grand_child_layer->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
- // Touch on the child layer, the touch event handler will still be blocking.
+ // Touch on the child layer, the touch event handler will be blocked.
EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER,
host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(60, 60)));
}
@@ -11007,7 +11361,7 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
layer->SetBounds(gfx::Size(10, 10));
layer->set_gpu_raster_max_texture_size(host_impl_->device_viewport_size());
layer->SetDrawsContent(true);
- layer->tilings()->AddTiling(1.0f, raster_source_with_tiles);
+ layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source_with_tiles);
layer->UpdateRasterSource(raster_source_with_tiles, &empty_invalidation,
nullptr);
layer->tilings()->tiling_at(0)->set_resolution(
@@ -11141,7 +11495,7 @@ size_t CountRenderPassesWithId(const RenderPassList& list, int id) {
}
TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) {
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
frame.render_passes.push_back(RenderPass::Create());
RenderPass* pass3 = frame.render_passes.back().get();
frame.render_passes.push_back(RenderPass::Create());
@@ -11178,7 +11532,7 @@ TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) {
}
TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
frame.render_passes.push_back(RenderPass::Create());
RenderPass* pass3 = frame.render_passes.back().get();
frame.render_passes.push_back(RenderPass::Create());
@@ -11220,7 +11574,7 @@ TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
}
TEST_F(LayerTreeHostImplTest, DoNotRemoveEmptyRootRenderPass) {
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
frame.render_passes.push_back(RenderPass::Create());
RenderPass* pass3 = frame.render_passes.back().get();
frame.render_passes.push_back(RenderPass::Create());
@@ -11286,7 +11640,7 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
host_impl_->DidFinishImplFrame();
EXPECT_FALSE(controller.did_draw_frame());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(controller.did_draw_frame());
@@ -11315,7 +11669,7 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
EXPECT_TRUE(controller.begin_frame_args().IsValid());
EXPECT_FALSE(controller.did_draw_frame());
- LayerTreeHostImpl::FrameData frame;
+ TestFrameData frame;
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(controller.did_draw_frame());
@@ -11707,9 +12061,8 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnCompositorFrameSinkChange) {
void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
bool main_thread_scrolling) {
LayerTreeSettings settings = DefaultSettings();
- settings.scrollbar_show_delay = base::TimeDelta::FromMilliseconds(500);
- settings.scrollbar_fade_out_delay = base::TimeDelta::FromMilliseconds(500);
- settings.scrollbar_fade_out_duration = base::TimeDelta::FromMilliseconds(300);
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY;
gfx::Size viewport_size(300, 200);
@@ -11770,32 +12123,28 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
host_impl_->MouseMoveAt(
gfx::Point(15 + kMouseDistanceToTriggerAnimation, 150));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(gfx::Point(10, 150));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(15 + kMouseDistanceToTriggerAnimation, 150));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
// scrollbar_2 on child.
std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 =
@@ -11810,6 +12159,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
child->SetBounds(child_layer_size);
child->SetDrawsContent(true);
child->SetScrollClipLayer(child_clip_id);
+ child->SetElementId(LayerIdToElementIdForTesting(child->id()));
if (main_thread_scrolling) {
child->set_main_thread_scrolling_reasons(
@@ -11835,42 +12185,36 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
// scrollbar_1, goes over scrollbar_1.
host_impl_->MouseMoveAt(gfx::Point(60, 150));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
- EXPECT_TRUE(
- scrollbar_2_animation_controller->mouse_is_near_scrollbar(VERTICAL));
- EXPECT_TRUE(
- scrollbar_2_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(64 + kMouseDistanceToTriggerAnimation, 150));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
- EXPECT_TRUE(
- scrollbar_2_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_2_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(
gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_2_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_2_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL));
host_impl_->MouseMoveAt(gfx::Point(10, 150));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_near_scrollbar(VERTICAL));
- EXPECT_TRUE(
- scrollbar_1_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL));
+ EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_2_animation_controller->mouse_is_near_scrollbar(VERTICAL));
+ scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL));
EXPECT_FALSE(
- scrollbar_2_animation_controller->mouse_is_over_scrollbar(VERTICAL));
+ scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL));
// Capture scrollbar_1, then move mouse to scrollbar_2's layer, should post an
// event to fade out scrollbar_1.
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 1a25a13cb11..ff17af70317 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -13,7 +13,7 @@
#include "base/path_service.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
-#include "cc/debug/lap_timer.h"
+#include "cc/base/lap_timer.h"
#include "cc/layers/nine_patch_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/texture_layer.h"
@@ -59,10 +59,8 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
}
void BeginMainFrame(const BeginFrameArgs& args) override {
- if (begin_frame_driven_drawing_ && !TestEnded()) {
- layer_tree_host()->SetNeedsAnimate();
- layer_tree_host()->SetNextCommitForcesRedraw();
- }
+ if (begin_frame_driven_drawing_ && !TestEnded())
+ layer_tree_host()->SetNeedsCommitWithForcedRedraw();
}
void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
@@ -309,9 +307,9 @@ class BrowserCompositorInvalidateLayerTreePerfTest
clean_up_started_ = true;
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&BrowserCompositorInvalidateLayerTreePerfTest::
- CleanUpAndEndTestOnMainThread,
- base::Unretained(this)));
+ base::BindOnce(&BrowserCompositorInvalidateLayerTreePerfTest::
+ CleanUpAndEndTestOnMainThread,
+ base::Unretained(this)));
}
void CleanUpAndEndTestOnMainThread() {
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index bd43e52f94f..eed99f6a625 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -9,10 +9,9 @@
#include "cc/layers/picture_image_layer.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/solid_color_layer.h"
+#include "cc/paint/drawing_display_item.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_recorder.h"
-#include "cc/paint/paint_surface.h"
-#include "cc/playback/drawing_display_item.h"
#include "cc/test/layer_tree_pixel_resource_test.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/solid_color_content_layer_client.h"
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index b74968e44c3..d6145d577c8 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -7,11 +7,11 @@
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer.h"
#include "cc/output/copy_output_request.h"
+#include "cc/paint/display_item_list.h"
+#include "cc/paint/drawing_display_item.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_recorder.h"
-#include "cc/playback/display_item_list.h"
-#include "cc/playback/drawing_display_item.h"
#include "cc/test/layer_tree_pixel_test.h"
#include "cc/test/test_compositor_frame_sink.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -203,15 +203,30 @@ TEST_F(LayerTreeHostTilesTestPartialInvalidation,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
}
+// crbug.com/707711
+#if defined(OS_LINUX)
+#define MAYBE_PartialRaster_MultiThread_OneCopy \
+ DISABLED_PartialRaster_MultiThread_OneCopy
+#else
+#define MAYBE_PartialRaster_MultiThread_OneCopy \
+ PartialRaster_MultiThread_OneCopy
+#endif
TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- PartialRaster_MultiThread_OneCopy) {
+ MAYBE_PartialRaster_MultiThread_OneCopy) {
RunRasterPixelTest(
true, PARTIAL_ONE_COPY, picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
}
+// crbug.com/707711
+#if defined(OS_LINUX)
+#define MAYBE_FullRaster_MultiThread_OneCopy \
+ DISABLED_FullRaster_MultiThread_OneCopy
+#else
+#define MAYBE_FullRaster_MultiThread_OneCopy FullRaster_MultiThread_OneCopy
+#endif
TEST_F(LayerTreeHostTilesTestPartialInvalidation,
- FullRaster_MultiThread_OneCopy) {
+ MAYBE_FullRaster_MultiThread_OneCopy) {
RunRasterPixelTest(
true, FULL_ONE_COPY, picture_layer_,
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 1f2059cb0c3..2e7457a49aa 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -17,9 +17,9 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/timing_function.h"
-#include "cc/debug/frame_rate_counter.h"
#include "cc/input/scroll_elasticity_helper.h"
#include "cc/layers/content_layer_client.h"
+#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/layers/picture_layer.h"
@@ -34,6 +34,7 @@
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/resources/ui_resource_manager.h"
+#include "cc/test/begin_frame_args_test.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
@@ -52,7 +53,9 @@
#include "cc/test/skia_common.h"
#include "cc/test/test_compositor_frame_sink.h"
#include "cc/test/test_web_graphics_context_3d.h"
+#include "cc/trees/clip_node.h"
#include "cc/trees/effect_node.h"
+#include "cc/trees/frame_rate_counter.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
@@ -802,7 +805,7 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest {
void DidCommit() override {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
- // child_ should create transform, effect, clip node.
+ // child_ should create transform, effect node.
child_->SetForceRenderSurfaceForTesting(true);
break;
case 2:
@@ -810,7 +813,12 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest {
child_->SetScrollClipLayerId(root_->id());
break;
case 3:
+ // child_ should create a clip node.
+ child_->SetMasksToBounds(true);
+ break;
+ case 4:
// child_ should not create any property tree node.
+ child_->SetMasksToBounds(false);
child_->SetForceRenderSurfaceForTesting(false);
child_->SetScrollClipLayerId(Layer::INVALID_ID);
}
@@ -818,92 +826,64 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest {
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
PropertyTrees* property_trees = impl->sync_tree()->property_trees();
- auto root_transform_id_to_index =
- property_trees->layer_id_to_transform_node_index.find(root_->id());
- auto child_transform_id_to_index =
- property_trees->layer_id_to_transform_node_index.find(child_->id());
- auto root_effect_id_to_index =
- property_trees->layer_id_to_effect_node_index.find(root_->id());
- auto child_effect_id_to_index =
- property_trees->layer_id_to_effect_node_index.find(child_->id());
- auto root_clip_id_to_index =
- property_trees->layer_id_to_clip_node_index.find(root_->id());
- auto child_clip_id_to_index =
- property_trees->layer_id_to_clip_node_index.find(child_->id());
- auto root_scroll_id_to_index =
- property_trees->layer_id_to_scroll_node_index.find(root_->id());
- auto child_scroll_id_to_index =
- property_trees->layer_id_to_scroll_node_index.find(child_->id());
+ const TransformNode* root_transform_node =
+ property_trees->transform_tree.FindNodeFromOwningLayerId(root_->id());
+ const TransformNode* child_transform_node =
+ property_trees->transform_tree.FindNodeFromOwningLayerId(child_->id());
+ const EffectNode* root_effect_node =
+ property_trees->effect_tree.FindNodeFromOwningLayerId(root_->id());
+ const EffectNode* child_effect_node =
+ property_trees->effect_tree.FindNodeFromOwningLayerId(child_->id());
+ const ClipNode* root_clip_node =
+ property_trees->clip_tree.FindNodeFromOwningLayerId(root_->id());
+ const ClipNode* child_clip_node =
+ property_trees->clip_tree.FindNodeFromOwningLayerId(child_->id());
+ const ScrollNode* root_scroll_node =
+ property_trees->scroll_tree.FindNodeFromOwningLayerId(root_->id());
+ const ScrollNode* child_scroll_node =
+ property_trees->scroll_tree.FindNodeFromOwningLayerId(child_->id());
switch (impl->sync_tree()->source_frame_number()) {
case 0:
- // root_ should create every property tree node and child_ should not
- // create any.
- EXPECT_NE(root_transform_id_to_index,
- property_trees->layer_id_to_transform_node_index.end());
- EXPECT_EQ(root_transform_id_to_index->second,
- root_->transform_tree_index());
- EXPECT_NE(root_effect_id_to_index,
- property_trees->layer_id_to_effect_node_index.end());
- EXPECT_EQ(root_effect_id_to_index->second, root_->effect_tree_index());
- EXPECT_NE(root_clip_id_to_index,
- property_trees->layer_id_to_clip_node_index.end());
- EXPECT_EQ(root_clip_id_to_index->second, root_->clip_tree_index());
- EXPECT_NE(root_scroll_id_to_index,
- property_trees->layer_id_to_scroll_node_index.end());
- EXPECT_EQ(root_scroll_id_to_index->second, root_->scroll_tree_index());
- EXPECT_EQ(child_transform_id_to_index,
- property_trees->layer_id_to_transform_node_index.end());
- EXPECT_EQ(child_effect_id_to_index,
- property_trees->layer_id_to_effect_node_index.end());
- EXPECT_EQ(child_clip_id_to_index,
- property_trees->layer_id_to_clip_node_index.end());
- EXPECT_EQ(child_scroll_id_to_index,
- property_trees->layer_id_to_scroll_node_index.end());
+ // root_ should create transform, scroll and effect tree nodes but not
+ // a clip node.
+ EXPECT_NE(root_transform_node, nullptr);
+ EXPECT_EQ(root_transform_node->id, root_->transform_tree_index());
+ EXPECT_NE(root_effect_node, nullptr);
+ EXPECT_EQ(root_effect_node->id, root_->effect_tree_index());
+ EXPECT_NE(root_scroll_node, nullptr);
+ EXPECT_EQ(root_scroll_node->id, root_->scroll_tree_index());
+ EXPECT_EQ(root_clip_node, nullptr);
+ EXPECT_EQ(child_transform_node, nullptr);
+ EXPECT_EQ(child_effect_node, nullptr);
+ EXPECT_EQ(child_clip_node, nullptr);
+ EXPECT_EQ(child_scroll_node, nullptr);
break;
case 1:
- // child_ should create a transfrom, clip, effect nodes but not a scroll
+ // child_ should create a transfrom, effect nodes but not a scroll, clip
// node.
- EXPECT_NE(
- property_trees->layer_id_to_transform_node_index.find(child_->id()),
- property_trees->layer_id_to_transform_node_index.end());
- EXPECT_EQ(child_transform_id_to_index->second,
- child_->transform_tree_index());
- EXPECT_NE(
- property_trees->layer_id_to_effect_node_index.find(child_->id()),
- property_trees->layer_id_to_effect_node_index.end());
- EXPECT_EQ(child_effect_id_to_index->second,
- child_->effect_tree_index());
- EXPECT_NE(
- property_trees->layer_id_to_clip_node_index.find(child_->id()),
- property_trees->layer_id_to_clip_node_index.end());
- EXPECT_EQ(child_clip_id_to_index->second, child_->clip_tree_index());
- EXPECT_EQ(
- property_trees->layer_id_to_scroll_node_index.find(child_->id()),
- property_trees->layer_id_to_scroll_node_index.end());
+ EXPECT_NE(child_transform_node, nullptr);
+ EXPECT_EQ(child_transform_node->id, child_->transform_tree_index());
+ EXPECT_NE(child_effect_node, nullptr);
+ EXPECT_EQ(child_effect_node->id, child_->effect_tree_index());
+ EXPECT_EQ(child_clip_node, nullptr);
+ EXPECT_EQ(child_scroll_node, nullptr);
break;
case 2:
// child_ should create a scroll node.
- EXPECT_NE(
- property_trees->layer_id_to_scroll_node_index.find(child_->id()),
- property_trees->layer_id_to_scroll_node_index.end());
- EXPECT_EQ(child_scroll_id_to_index->second,
- child_->scroll_tree_index());
+ EXPECT_NE(child_scroll_node, nullptr);
+ EXPECT_EQ(child_scroll_node->id, child_->scroll_tree_index());
break;
case 3:
+ // child_ should create a clip node.
+ EXPECT_NE(child_clip_node, nullptr);
+ EXPECT_EQ(child_clip_node->id, child_->clip_tree_index());
+ break;
+ case 4:
// child_ should not create any property tree nodes.
- EXPECT_EQ(
- property_trees->layer_id_to_transform_node_index.find(child_->id()),
- property_trees->layer_id_to_transform_node_index.end());
- EXPECT_EQ(
- property_trees->layer_id_to_effect_node_index.find(child_->id()),
- property_trees->layer_id_to_effect_node_index.end());
- EXPECT_EQ(
- property_trees->layer_id_to_clip_node_index.find(child_->id()),
- property_trees->layer_id_to_clip_node_index.end());
- EXPECT_EQ(
- property_trees->layer_id_to_scroll_node_index.find(child_->id()),
- property_trees->layer_id_to_scroll_node_index.end());
-
+ EXPECT_EQ(child_transform_node, nullptr);
+ EXPECT_EQ(child_effect_node, nullptr);
+ EXPECT_EQ(child_clip_node, nullptr);
+ EXPECT_EQ(child_scroll_node, nullptr);
EndTest();
break;
}
@@ -923,7 +903,6 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
void SetupTree() override {
root_ = Layer::Create();
child_ = Layer::Create();
- child_->SetElementId(kTestElementId);
root_->AddChild(child_);
layer_tree_host()->SetRootLayer(root_);
LayerTreeHostTest::SetupTree();
@@ -961,13 +940,13 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
->property_trees()
->scroll_tree.size());
EXPECT_TRUE(property_trees->element_id_to_transform_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_transform_node_index.end());
EXPECT_TRUE(property_trees->element_id_to_effect_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_effect_node_index.end());
EXPECT_TRUE(property_trees->element_id_to_scroll_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_scroll_node_index.end());
break;
case 1:
@@ -981,12 +960,14 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
->property_trees()
->scroll_tree.size());
EXPECT_EQ(
- 2,
- property_trees->element_id_to_transform_node_index[kTestElementId]);
- EXPECT_EQ(
- 2, property_trees->element_id_to_effect_node_index[kTestElementId]);
- EXPECT_EQ(
- 2, property_trees->element_id_to_scroll_node_index[kTestElementId]);
+ 2, property_trees
+ ->element_id_to_transform_node_index[child_->element_id()]);
+ EXPECT_EQ(2,
+ property_trees
+ ->element_id_to_effect_node_index[child_->element_id()]);
+ EXPECT_EQ(2,
+ property_trees
+ ->element_id_to_scroll_node_index[child_->element_id()]);
break;
case 2:
EXPECT_EQ(2U, child_impl_->layer_tree_impl()
@@ -996,13 +977,13 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
->property_trees()
->effect_tree.size());
EXPECT_TRUE(property_trees->element_id_to_transform_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_transform_node_index.end());
EXPECT_TRUE(property_trees->element_id_to_effect_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_effect_node_index.end());
EXPECT_TRUE(property_trees->element_id_to_scroll_node_index.find(
- kTestElementId) ==
+ child_->element_id()) ==
property_trees->element_id_to_scroll_node_index.end());
break;
}
@@ -1012,8 +993,6 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
void AfterTest() override {}
private:
- const ElementId kTestElementId = ElementId(42, 8118);
-
scoped_refptr<Layer> root_;
scoped_refptr<Layer> child_;
};
@@ -1149,8 +1128,7 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest {
case OPACITY:
index_++;
impl->active_tree()->ResetAllChangeTracking();
- impl->active_tree()->property_trees()->effect_tree.OnOpacityAnimated(
- 0.5f, root->effect_tree_index(), impl->active_tree());
+ impl->active_tree()->SetOpacityMutated(root->element_id(), 0.5f);
PostSetNeedsCommitToMainThread();
break;
case TRANSFORM:
@@ -1166,10 +1144,7 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest {
->LayerById(child_->id())
->LayerPropertyChanged());
transform.Translate(10, 10);
- impl->active_tree()
- ->property_trees()
- ->transform_tree.OnTransformAnimated(
- transform, root->transform_tree_index(), impl->active_tree());
+ impl->active_tree()->SetTransformMutated(root->element_id(), transform);
PostSetNeedsCommitToMainThread();
break;
case FILTER:
@@ -1184,8 +1159,7 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest {
->LayerById(child_->id())
->LayerPropertyChanged());
filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
- impl->active_tree()->property_trees()->effect_tree.OnFilterAnimated(
- filters, root->effect_tree_index(), impl->active_tree());
+ impl->active_tree()->SetFilterMutated(root->element_id(), filters);
PostSetNeedsCommitToMainThread();
break;
case END:
@@ -1259,8 +1233,7 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest {
EffectNode* node = effect_tree.Node(root->effect_tree_index());
switch (impl->sync_tree()->source_frame_number()) {
case 0:
- effect_tree.OnOpacityAnimated(0.75f, root->effect_tree_index(),
- impl->sync_tree());
+ impl->sync_tree()->SetOpacityMutated(root->element_id(), 0.75f);
PostSetNeedsCommitToMainThread();
break;
case 1:
@@ -1269,8 +1242,7 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest {
break;
case 2:
EXPECT_EQ(node->opacity, 0.75f);
- effect_tree.OnOpacityAnimated(0.75f, root->effect_tree_index(),
- impl->sync_tree());
+ impl->sync_tree()->SetOpacityMutated(root->element_id(), 0.75f);
PostSetNeedsCommitToMainThread();
break;
case 3:
@@ -1279,8 +1251,8 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest {
break;
case 4:
EXPECT_EQ(node->opacity, 0.25f);
- impl->sync_tree()->property_trees()->effect_tree.OnFilterAnimated(
- brightness_filter_, root->effect_tree_index(), impl->sync_tree());
+ impl->sync_tree()->SetFilterMutated(root->element_id(),
+ brightness_filter_);
PostSetNeedsCommitToMainThread();
break;
case 5:
@@ -1289,8 +1261,8 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest {
break;
case 6:
EXPECT_EQ(node->filters, brightness_filter_);
- impl->sync_tree()->property_trees()->effect_tree.OnFilterAnimated(
- brightness_filter_, root->effect_tree_index(), impl->sync_tree());
+ impl->sync_tree()->SetFilterMutated(root->element_id(),
+ brightness_filter_);
PostSetNeedsCommitToMainThread();
break;
case 7:
@@ -1352,16 +1324,17 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest {
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
TransformTree& transform_tree =
impl->sync_tree()->property_trees()->transform_tree;
- TransformNode* node = transform_tree.Node(
- impl->sync_tree()->root_layer_for_testing()->transform_tree_index());
+ const LayerImpl* root_layer = impl->sync_tree()->root_layer_for_testing();
+ const TransformNode* node =
+ transform_tree.Node(root_layer->transform_tree_index());
gfx::Transform rotate10;
rotate10.Rotate(10.f);
gfx::Transform rotate20;
rotate20.Rotate(20.f);
switch (impl->sync_tree()->source_frame_number()) {
case 0:
- impl->sync_tree()->property_trees()->transform_tree.OnTransformAnimated(
- rotate20, node->id, impl->sync_tree());
+ impl->sync_tree()->SetTransformMutated(root_layer->element_id(),
+ rotate20);
PostSetNeedsCommitToMainThread();
break;
case 1:
@@ -1370,8 +1343,8 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest {
break;
case 2:
EXPECT_EQ(node->local, rotate20);
- impl->sync_tree()->property_trees()->transform_tree.OnTransformAnimated(
- rotate20, node->id, impl->sync_tree());
+ impl->sync_tree()->SetTransformMutated(root_layer->element_id(),
+ rotate20);
PostSetNeedsCommitToMainThread();
break;
case 3:
@@ -1455,8 +1428,7 @@ class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest {
if (impl->active_tree()->source_frame_number() == 0) {
gfx::Transform scale;
scale.Scale(2.0, 2.0);
- impl->active_tree()->property_trees()->transform_tree.OnTransformAnimated(
- scale, child_->transform_tree_index(), impl->active_tree());
+ impl->active_tree()->SetTransformMutated(child_->element_id(), scale);
}
}
@@ -1888,7 +1860,7 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorChange);
-class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest {
+class LayerTreeHostTestRasterColorSpaceChange : public LayerTreeHostTest {
public:
void SetupTree() override {
space1_ = gfx::ColorSpace::CreateXYZD50();
@@ -1902,7 +1874,7 @@ class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest {
root_layer_->AddChild(child_layer_);
layer_tree_host()->SetRootLayer(root_layer_);
- layer_tree_host()->SetDeviceColorSpace(space1_);
+ layer_tree_host()->SetRasterColorSpace(space1_);
LayerTreeHostTest::SetupTree();
client_.set_bounds(root_layer_->bounds());
}
@@ -1920,32 +1892,32 @@ class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest {
// The first frame will have full damage, and should be in the initial
// color space.
EXPECT_FALSE(frame_data->has_no_damage);
- EXPECT_TRUE(space1_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space1_ == host_impl->active_tree()->raster_color_space());
break;
case 1:
// Empty commit.
EXPECT_TRUE(frame_data->has_no_damage);
- EXPECT_TRUE(space1_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space1_ == host_impl->active_tree()->raster_color_space());
break;
case 2:
// The change from space1 to space2 should cause full damage.
EXPECT_FALSE(frame_data->has_no_damage);
- EXPECT_TRUE(space2_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space2_ == host_impl->active_tree()->raster_color_space());
break;
case 3:
// Empty commit with the color space set to space2 redundantly.
EXPECT_TRUE(frame_data->has_no_damage);
- EXPECT_TRUE(space2_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space2_ == host_impl->active_tree()->raster_color_space());
break;
case 4:
// The change from space2 to space1 should cause full damage.
EXPECT_FALSE(frame_data->has_no_damage);
- EXPECT_TRUE(space1_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space1_ == host_impl->active_tree()->raster_color_space());
break;
case 5:
// Empty commit.
EXPECT_TRUE(frame_data->has_no_damage);
- EXPECT_TRUE(space1_ == host_impl->active_tree()->device_color_space());
+ EXPECT_TRUE(space1_ == host_impl->active_tree()->raster_color_space());
EndTest();
break;
default:
@@ -1972,19 +1944,19 @@ class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest {
break;
case 2:
EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
- layer_tree_host()->SetDeviceColorSpace(space2_);
+ layer_tree_host()->SetRasterColorSpace(space2_);
EXPECT_TRUE(child_layer_->NeedsDisplayForTesting());
break;
case 3:
- // The redundant SetDeviceColorSpace should cause no commit and no
+ // The redundant SetRasterColorSpace should cause no commit and no
// damage. Force a commit for the test to continue.
- layer_tree_host()->SetDeviceColorSpace(space2_);
+ layer_tree_host()->SetRasterColorSpace(space2_);
PostSetNeedsCommitToMainThread();
EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
break;
case 4:
EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
- layer_tree_host()->SetDeviceColorSpace(space1_);
+ layer_tree_host()->SetRasterColorSpace(space1_);
EXPECT_TRUE(child_layer_->NeedsDisplayForTesting());
break;
case 5:
@@ -2009,11 +1981,12 @@ class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest {
scoped_refptr<Layer> child_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceColorSpaceChange);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRasterColorSpaceChange);
-class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
+class LayerTreeHostTestSetNeedsCommitWithForcedRedraw
+ : public LayerTreeHostTest {
public:
- LayerTreeHostTestSetNextCommitForcesRedraw()
+ LayerTreeHostTestSetNeedsCommitWithForcedRedraw()
: num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
void BeginTest() override {
@@ -2073,8 +2046,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
break;
case 2:
// Should force full frame damage on the next commit
- PostSetNextCommitForcesRedrawToMainThread();
- PostSetNeedsCommitToMainThread();
+ PostSetNeedsCommitWithForcedRedrawToMainThread();
host_impl->BlockNotifyReadyToActivateForTesting(true);
break;
case 3:
@@ -2098,7 +2070,8 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
};
// This test blocks activation which is not supported for single thread mode.
-MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(
+ LayerTreeHostTestSetNeedsCommitWithForcedRedraw);
// Tests that if a layer is not drawn because of some reason in the parent then
// its damage is preserved until the next time it is drawn.
@@ -2715,17 +2688,20 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
public:
- LayerTreeHostTestDeferCommits()
- : num_will_begin_impl_frame_(0), num_send_begin_main_frame_(0) {}
+ LayerTreeHostTestDeferCommits() = default;
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+ void BeginTest() override {
+ // Start with commits deferred.
+ PostSetDeferCommitsToMainThread(true);
+ PostSetNeedsCommitToMainThread();
+ }
void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
const BeginFrameArgs& args) override {
+ // Impl frames happen while commits are deferred.
num_will_begin_impl_frame_++;
switch (num_will_begin_impl_frame_) {
case 1:
- break;
case 2:
case 3:
case 4:
@@ -2735,7 +2711,12 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
PostSetNeedsRedrawToMainThread();
break;
case 5:
- PostSetDeferCommitsToMainThread(false);
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ // Unretained because the test should not end before allowing
+ // commits via this running.
+ base::BindOnce(&LayerTreeHostTestDeferCommits::AllowCommits,
+ base::Unretained(this)));
break;
default:
// Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
@@ -2745,32 +2726,128 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
}
void WillBeginMainFrame() override {
+ EXPECT_TRUE(allow_commits_);
num_send_begin_main_frame_++;
- switch (num_send_begin_main_frame_) {
- case 1:
- layer_tree_host()->SetDeferCommits(true);
- break;
- case 2:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
+ EndTest();
+ }
+
+ void AllowCommits() {
+ allow_commits_ = true;
+ layer_tree_host()->SetDeferCommits(false);
}
void AfterTest() override {
EXPECT_GE(num_will_begin_impl_frame_, 5);
- EXPECT_EQ(2, num_send_begin_main_frame_);
+ EXPECT_EQ(1, num_send_begin_main_frame_);
}
private:
- int num_will_begin_impl_frame_;
- int num_send_begin_main_frame_;
+ bool allow_commits_ = false;
+ int num_will_begin_impl_frame_ = 0;
+ int num_send_begin_main_frame_ = 0;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
+// This verifies that we can abort a commit inside the main frame, and
+// we don't leave any weird states around if we never allow the commit
+// to happen.
+class LayerTreeHostTestDeferCommitsInsideBeginMainFrame
+ : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestDeferCommitsInsideBeginMainFrame() = default;
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillBeginMainFrame() override {
+ ++begin_main_frame_count_;
+ if (allow_commits_)
+ return;
+
+ // This should prevent the commit from happening.
+ layer_tree_host()->SetDeferCommits(true);
+ // Wait to see if the commit happens. It's possible the deferred
+ // commit happens when it shouldn't but takes long enough that
+ // this passes. But it won't fail when it shouldn't.
+ MainThreadTaskRunner()->PostDelayedTask(
+ FROM_HERE,
+ // Unretained because the test doesn't end before this runs.
+ base::BindOnce(&LayerTreeTest::EndTest, base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(100));
+ }
+
+ void DidCommit() override { ++commit_count_; }
+
+ void AfterTest() override {
+ EXPECT_EQ(0, commit_count_);
+ EXPECT_EQ(1, begin_main_frame_count_);
+ }
+
+ private:
+ bool allow_commits_ = false;
+ int commit_count_ = 0;
+ int begin_main_frame_count_ = 0;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestDeferCommitsInsideBeginMainFrame);
+
+// This verifies that we can abort a commit inside the main frame, and
+// we will finish the commit once it is allowed.
+class LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter
+ : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter() = default;
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillBeginMainFrame() override {
+ ++begin_main_frame_count_;
+ if (allow_commits_)
+ return;
+
+ // This should prevent the commit from happening.
+ layer_tree_host()->SetDeferCommits(true);
+ // Wait to see if the commit happens. It's possible the deferred
+ // commit happens when it shouldn't but takes long enough that
+ // this passes. But it won't fail when it shouldn't.
+ MainThreadTaskRunner()->PostDelayedTask(
+ FROM_HERE,
+ // Unretained because the test doesn't end before this runs.
+ base::BindOnce(
+ &LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter::
+ AllowCommits,
+ base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(100));
+ }
+
+ void AllowCommits() {
+ // Once we've waited and seen that commit did not happen, we
+ // allow commits and should see this one go through.
+ allow_commits_ = true;
+ layer_tree_host()->SetDeferCommits(false);
+ }
+
+ void DidCommit() override {
+ ++commit_count_;
+ EXPECT_TRUE(allow_commits_);
+ EndTest();
+ }
+
+ void AfterTest() override {
+ EXPECT_EQ(1, commit_count_);
+ EXPECT_EQ(2, begin_main_frame_count_);
+ }
+
+ private:
+ bool allow_commits_ = false;
+ int commit_count_ = 0;
+ int begin_main_frame_count_ = 0;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestDeferCommitsInsideBeginMainFrameWithCommitAfter);
+
class LayerTreeHostTestCompositeImmediatelyStateTransitions
: public LayerTreeHostTest {
public:
@@ -2944,7 +3021,7 @@ class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
// once we return. End test while it's enabled.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTest::EndTest, base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostTest::EndTest, base::Unretained(this)));
}
void AfterTest() override {}
@@ -3065,9 +3142,9 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
// surface. But it needs to be done on a new stack frame.
bool resourceless_software_draw = false;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&OnDrawCompositorFrameSink::OnDraw,
- base::Unretained(compositor_frame_sink_),
- resourceless_software_draw));
+ FROM_HERE, base::BindOnce(&OnDrawCompositorFrameSink::OnDraw,
+ base::Unretained(compositor_frame_sink_),
+ resourceless_software_draw));
}
}
@@ -4544,8 +4621,7 @@ class TestSwapPromise : public SwapPromise {
class PinnedLayerTreeSwapPromise : public LayerTreeHostTest {
protected:
void BeginTest() override {
- PostSetNextCommitForcesRedrawToMainThread();
- PostSetNeedsCommitToMainThread();
+ layer_tree_host()->SetNeedsCommitWithForcedRedraw();
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
@@ -4700,8 +4776,9 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest {
void DidCommit() override {
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
+ base::Unretained(this)));
}
void ChangeFrame() {
@@ -4805,8 +4882,8 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest {
void DidCommit() override {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTestKeepSwapPromiseMFBA::ChangeFrame,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostTestKeepSwapPromiseMFBA::ChangeFrame,
+ base::Unretained(this)));
}
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
@@ -4905,9 +4982,10 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
const BeginFrameArgs& args) override {
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility::
- SetVisibleFalseAndQueueSwapPromise,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
+ SetVisibleFalseAndQueueSwapPromise,
+ base::Unretained(this)));
}
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
@@ -5916,8 +5994,9 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
return;
posted_ = true;
ImplThreadTaskRunner()->PostDelayedTask(
- FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
- base::Unretained(this), host_impl),
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
+ base::Unretained(this), host_impl),
// Use a delay to allow raster/upload to happen in between frames. This
// should cause flakiness if we fail to block raster/upload when
// desired.
@@ -5957,14 +6036,15 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
// On frame 3, we will have a lower res tile complete for the pinch-out
// gesture even though it's not displayed. We wait for it here to prevent
// flakiness.
- EXPECT_EQ(0.75f, tile->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(0.75f, gfx::Vector2dF()),
+ tile->raster_transform());
PostNextAfterDraw(host_impl);
}
// On frame_ == 4, we are preventing texture uploads from completing,
// so this verifies they are not completing before frame_ == 5.
// Flaky failures here indicate we're failing to prevent uploads from
// completing.
- EXPECT_NE(4, frame_) << tile->contents_scale();
+ EXPECT_NE(4, frame_) << tile->contents_scale_key();
}
void AfterTest() override {}
@@ -6387,9 +6467,10 @@ class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
void WillCommit() override {
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
- EndTestShouldRunAfterDidCommit,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
+ EndTestShouldRunAfterDidCommit,
+ base::Unretained(this)));
}
void EndTestShouldRunAfterDidCommit() {
@@ -6465,6 +6546,104 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
+ : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size layer_size(100, 100);
+ content_layer->SetBounds(layer_size);
+
+ gfx::Size mask_size(100, 100);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
+ outer_viewport_scroll_layer->SetBounds(layer_size);
+ CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer,
+ gfx::Size(50, 50), gfx::Size(50, 50),
+ layer_tree_host());
+ outer_viewport_scroll_layer->scroll_clip_layer()->SetMasksToBounds(true);
+ outer_viewport_scroll_layer->AddChild(content_layer);
+
+ client_.set_bounds(root->bounds());
+ outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
+
+ EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
+ const RenderPassDrawQuad* render_pass_quad =
+ RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
+ render_pass_quad->rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
+ 50.f / texture_size.width(), 50.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin);
+
class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
protected:
void SetupTree() override {
@@ -6485,8 +6664,19 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
FakePictureLayer::Create(&client_);
content_layer->AddChild(content_child_layer);
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -6510,6 +6700,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
gfx::Size mask_size(100, 100);
mask_layer->SetBounds(mask_size);
mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
layer_tree_host()->SetRootLayer(root);
LayerTreeTest::SetupTree();
@@ -6538,15 +6729,28 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
// coords in the mask are scaled by 10/50 and 20/50.
// The surface is clipped to (20,10) so the mask texture coords are offset
// by 20/50 and 10/50
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
+ 10.f / texture_size.width(), 20.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
EndTest();
return draw_result;
}
void AfterTest() override {}
+ int mask_layer_id_;
FakeContentLayerClient client_;
};
@@ -6576,8 +6780,19 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
FakePictureLayer::Create(&client_);
scaling_layer->AddChild(content_layer);
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 10), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 10, 100, 90), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -6620,16 +6835,28 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
// mask, that should fully map onto the quad.
EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
render_pass_quad->rect.ToString());
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
break;
case 1:
// Applying a DSF should change the render surface size, but won't
// affect which part of the mask is used.
EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
render_pass_quad->rect.ToString());
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
EndTest();
break;
}
@@ -6665,8 +6892,19 @@ class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
FakePictureLayer::Create(&client_);
root->AddChild(content_layer);
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -6704,16 +6942,26 @@ class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
// Check that the mask fills the surface.
EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
render_pass_quad->rect.ToString());
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 50.f / 128.f, 50.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
break;
case 1:
// Applying a DSF should change the render surface size, but won't
// affect which part of the mask is used.
EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
render_pass_quad->rect.ToString());
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 50.f / 128.f, 50.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
EndTest();
break;
}
@@ -6851,9 +7099,39 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
void AfterTest() override {}
};
-
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
+// Makes sure that LocalSurfaceId is propagated to the CompositorFrameSink.
+class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override {
+ expected_local_surface_id_ = allocator_.GenerateId();
+ PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_);
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(DRAW_SUCCESS, draw_result);
+ EXPECT_EQ(expected_local_surface_id_,
+ host_impl->active_tree()->local_surface_id());
+ return draw_result;
+ }
+
+ void DisplayReceivedLocalSurfaceIdOnThread(
+ const LocalSurfaceId& local_surface_id) override {
+ EXPECT_EQ(expected_local_surface_id_, local_surface_id);
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ LocalSurfaceId expected_local_surface_id_;
+ LocalSurfaceIdAllocator allocator_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
+
// The GPU image decode controller hands images off to Skia for rasterization.
// When used with large images, the images in question could be deleted before
// Skia was done with them, causing a crash. This test performs an end-to-end
@@ -6870,8 +7148,9 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest {
void InitializeSettings(LayerTreeSettings* settings) override {
settings->gpu_rasterization_forced = true;
- /// Set to 0 to force at-raster GPU image decode.
- settings->gpu_decoded_image_budget_bytes = 0;
+ // Set to 0 to force at-raster GPU image decode.
+ settings->decoded_image_working_set_budget_bytes = 0;
+ settings->decoded_image_cache_budget_bytes = 0;
}
void SetupTree() override {
@@ -7037,5 +7316,191 @@ class LayerTreeHostTestContentSourceId : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContentSourceId);
+class LayerTreeHostTestBeginFrameSequenceNumbers : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
+ const BeginFrameArgs& args) override {
+ // First BeginFrame will block activation, second one unblocks.
+ impl->BlockNotifyReadyToActivateForTesting(false);
+
+ EXPECT_TRUE(args.IsValid());
+ current_begin_frame_args_ = args;
+ }
+
+ void BeginMainFrame(const BeginFrameArgs& args) override {
+ EXPECT_TRUE(args.IsValid());
+ if (!current_begin_main_frame_args_.IsValid())
+ current_begin_main_frame_args_ = args;
+ }
+
+ void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
+ current_begin_main_frame_args_on_impl_ = current_begin_main_frame_args_;
+ // Request another subsequent commit. That way, the first commit's
+ // latest_confirmed_sequence_number should stay at the first BeginFrame's
+ // sequence number.
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void WillCommitCompleteOnThread(LayerTreeHostImpl* impl) override {
+ // Defer current commit's activation until second BeginFrame.
+ impl->BlockNotifyReadyToActivateForTesting(true);
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ // We should only draw in second BeginFrame.
+ EXPECT_TRUE(current_begin_main_frame_args_on_impl_.IsValid());
+ EXPECT_LT(current_begin_main_frame_args_on_impl_.sequence_number,
+ current_begin_frame_args_.sequence_number);
+ frame_data_ = frame_data;
+ return draw_result;
+ }
+
+ void DisplayReceivedCompositorFrameOnThread(
+ const CompositorFrame& frame) override {
+ if (compositor_frame_submitted_)
+ return;
+ compositor_frame_submitted_ = true;
+
+ EXPECT_EQ(BeginFrameAck(
+ current_begin_frame_args_.source_id,
+ current_begin_frame_args_.sequence_number,
+ current_begin_main_frame_args_on_impl_.sequence_number, true),
+ frame.metadata.begin_frame_ack);
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ if (layers_drawn_)
+ return;
+ layers_drawn_ = true;
+
+ EXPECT_TRUE(frame_data_);
+ EXPECT_TRUE(compositor_frame_submitted_);
+ EXPECT_EQ(BeginFrameAck(
+ current_begin_frame_args_.source_id,
+ current_begin_frame_args_.sequence_number,
+ current_begin_main_frame_args_on_impl_.sequence_number, true),
+ frame_data_->begin_frame_ack);
+ EndTest();
+ }
+
+ void AfterTest() override { EXPECT_TRUE(layers_drawn_); }
+
+ private:
+ bool compositor_frame_submitted_ = false;
+ bool layers_drawn_ = false;
+ BeginFrameArgs current_begin_frame_args_;
+ BeginFrameArgs current_begin_main_frame_args_;
+ BeginFrameArgs current_begin_main_frame_args_on_impl_;
+ LayerTreeHostImpl::FrameData* frame_data_;
+};
+
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestBeginFrameSequenceNumbers);
+
+class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillBeginMainFrame() override {
+ if (!first_)
+ return;
+ first_ = false;
+
+ sk_sp<const SkImage> image = CreateDiscardableImage(gfx::Size(10, 10));
+ auto callback =
+ base::Bind(&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
+ base::Unretained(this));
+ // Schedule the decode twice for the same image.
+ layer_tree_host()->QueueImageDecode(image, callback);
+ layer_tree_host()->QueueImageDecode(image, callback);
+ }
+
+ void ImageDecodeFinished(bool decode_succeeded) {
+ EXPECT_TRUE(decode_succeeded);
+ ++finished_decode_count_;
+ EXPECT_LE(finished_decode_count_, 2);
+ if (finished_decode_count_ == 2)
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ bool first_ = true;
+ int finished_decode_count_ = 0;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecode);
+
+class LayerTreeHostTestQueueImageDecodeNonLazy : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillBeginMainFrame() override {
+ if (!first_)
+ return;
+ first_ = false;
+
+ bitmap_.allocN32Pixels(10, 10);
+ sk_sp<const SkImage> image = SkImage::MakeFromBitmap(bitmap_);
+ auto callback = base::Bind(
+ &LayerTreeHostTestQueueImageDecodeNonLazy::ImageDecodeFinished,
+ base::Unretained(this));
+ layer_tree_host()->QueueImageDecode(image, callback);
+ }
+
+ void ImageDecodeFinished(bool decode_succeeded) {
+ EXPECT_TRUE(decode_succeeded);
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ bool first_ = true;
+ SkBitmap bitmap_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecodeNonLazy);
+
+class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->initial_debug_state.show_paint_rects = true;
+ settings->use_layer_lists = true;
+ }
+
+ void SetupTree() override {
+ LayerTreeHostTest::SetupTree();
+
+ // Build the property trees for the root layer.
+ layer_tree_host()->BuildPropertyTreesForTesting();
+
+ // The HUD layer should not have been setup by the property tree building.
+ DCHECK_EQ(layer_tree_host()->hud_layer(), nullptr);
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); }
+
+ void DidCommit() override {
+ auto* hud = layer_tree_host()->hud_layer();
+ DCHECK(hud);
+ auto* root_layer = layer_tree_host()->root_layer();
+ DCHECK_EQ(hud->transform_tree_index(), root_layer->transform_tree_index());
+ DCHECK_EQ(hud->clip_tree_index(), root_layer->clip_tree_index());
+ DCHECK_EQ(hud->effect_tree_index(), root_layer->effect_tree_index());
+ DCHECK_EQ(hud->scroll_tree_index(), root_layer->scroll_tree_index());
+ }
+
+ void AfterTest() override {}
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHudLayerWithLayerLists);
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index f77964271d5..f25dc93e40f 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -573,7 +573,7 @@ class LayerTreeHostAnimationTestForceRedraw
}
void UpdateLayerTreeHost() override {
- layer_tree_host()->SetNextCommitForcesRedraw();
+ layer_tree_host()->SetNeedsCommitWithForcedRedraw();
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1355,9 +1355,9 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating
if (!TestEnded()) {
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostAnimationTestAddAnimationAfterAnimating::
- CheckAnimations,
- base::Unretained(this), host_impl));
+ base::BindOnce(&LayerTreeHostAnimationTestAddAnimationAfterAnimating::
+ CheckAnimations,
+ base::Unretained(this), host_impl));
}
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index 580fa3e8363..37b3e1b006f 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -51,8 +51,8 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
CompletionEvent completion_event;
image_worker_task_runner()->PostTask(
FROM_HERE,
- base::Bind([](CompletionEvent* event) { event->Signal(); },
- base::Unretained(&completion_event)));
+ base::BindOnce([](CompletionEvent* event) { event->Signal(); },
+ base::Unretained(&completion_event)));
completion_event.Wait();
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index f59b200beda..3c7351f3ff4 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
#include "base/memory/ptr_util.h"
+#include "cc/base/filter_operations.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/painted_scrollbar_layer.h"
@@ -14,7 +15,6 @@
#include "cc/layers/texture_layer_impl.h"
#include "cc/layers/video_layer.h"
#include "cc/layers/video_layer_impl.h"
-#include "cc/output/filter_operations.h"
#include "cc/paint/paint_flags.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/ui_resource_manager.h"
@@ -181,9 +181,10 @@ class LayerTreeHostContextTestLostContextSucceeds
void RequestNewCompositorFrameSink() override {
if (async_compositor_frame_sink_creation_) {
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostContextTestLostContextSucceeds::
- AsyncRequestNewCompositorFrameSink,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostContextTestLostContextSucceeds::
+ AsyncRequestNewCompositorFrameSink,
+ base::Unretained(this)));
} else {
AsyncRequestNewCompositorFrameSink();
}
@@ -408,8 +409,9 @@ class LayerTreeHostClientTakeAwayCompositorFrameSink
CHECK(surface);
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostClientTakeAwayCompositorFrameSink::MakeVisible,
- base::Unretained(this)));
+ base::BindOnce(
+ &LayerTreeHostClientTakeAwayCompositorFrameSink::MakeVisible,
+ base::Unretained(this)));
}
void DidInitializeCompositorFrameSink() override {
@@ -417,9 +419,9 @@ class LayerTreeHostClientTakeAwayCompositorFrameSink
if (setos_counter_ == 1) {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostClientTakeAwayCompositorFrameSink::
- HideAndReleaseCompositorFrameSink,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostClientTakeAwayCompositorFrameSink::
+ HideAndReleaseCompositorFrameSink,
+ base::Unretained(this)));
} else {
EndTest();
}
@@ -539,7 +541,7 @@ class LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink
void RequestNewCompositorFrameSink() override {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink::
CreateAndSetCompositorFrameSink,
base::Unretained(this)));
@@ -708,9 +710,9 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
if (HasImplThread()) {
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostContextTestLostContextAndEvictTextures::
- EvictTexturesOnImplThread,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostContextTestLostContextAndEvictTextures::
+ EvictTexturesOnImplThread,
+ base::Unretained(this)));
} else {
DebugScopedSetImplThread impl(task_runner_provider());
EvictTexturesOnImplThread();
@@ -1149,15 +1151,15 @@ class UIResourceLostTest : public LayerTreeHostContextTest {
void PostStepCompleteToMainThread() {
task_runner_provider()->MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&UIResourceLostTest::StepCompleteOnMainThreadInternal,
- base::Unretained(this), time_step_));
+ base::BindOnce(&UIResourceLostTest::StepCompleteOnMainThreadInternal,
+ base::Unretained(this), time_step_));
}
void PostLoseContextToImplThread() {
EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostContextTest::LoseContext,
- base::Unretained(this)));
+ FROM_HERE, base::BindOnce(&LayerTreeHostContextTest::LoseContext,
+ base::Unretained(this)));
}
protected:
@@ -1563,9 +1565,9 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
// Meanwhile, lose the context while we are in defer commits.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostContextTestLoseAfterSendingBeginMainFrame::
- LoseContextOnImplThread,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostContextTestLoseAfterSendingBeginMainFrame::
+ LoseContextOnImplThread,
+ base::Unretained(this)));
// After the first frame, we will lose the context and then not start
// allowing commits until that happens. The 2nd frame should not happen
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 201c30f9fab..7805b3d76cf 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -8,7 +8,7 @@
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "cc/layers/layer_iterator.h"
+#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/direct_renderer.h"
@@ -55,8 +55,8 @@ class LayerTreeHostCopyRequestTestMultipleRequests
void WaitForCallback() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
+ base::Unretained(this)));
}
void NextStep() {
@@ -597,6 +597,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestClippedOut);
class LayerTreeHostCopyRequestTestScaledLayer
: public LayerTreeHostCopyRequestTest {
protected:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+
void SetupTree() override {
root_ = Layer::Create();
root_->SetBounds(gfx::Size(20, 20));
@@ -780,9 +784,9 @@ class LayerTreeHostCopyRequestTestDeleteTexture
result_ = nullptr;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture::
- CheckNumTexturesAfterReadbackDestroyed,
- base::Unretained(this)));
+ FROM_HERE, base::BindOnce(&LayerTreeHostCopyRequestTestDeleteTexture::
+ CheckNumTexturesAfterReadbackDestroyed,
+ base::Unretained(this)));
}
void CheckNumTexturesAfterReadbackDestroyed() {
@@ -809,7 +813,7 @@ class LayerTreeHostCopyRequestTestDeleteTexture
// Request a copy of the layer. This will use another texture.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostCopyRequestTestDeleteTexture::InsertCopyRequest,
base::Unretained(this)));
break;
@@ -828,9 +832,10 @@ class LayerTreeHostCopyRequestTestDeleteTexture
// to the compositor. Then check the resulting number of allocated
// textures.
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture::
- DestroyCopyResultAndCheckNumTextures,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostCopyRequestTestDeleteTexture::
+ DestroyCopyResultAndCheckNumTextures,
+ base::Unretained(this)));
break;
}
}
@@ -880,6 +885,11 @@ class LayerTreeHostCopyRequestTestCountTextures
copy_layer_ = FakePictureLayer::Create(&copy_client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
copy_client_.set_bounds(copy_layer_->bounds());
+ PaintFlags flags;
+ flags.setColor(SK_ColorRED);
+ // Ensure the layer isn't completely transparent so the RenderPass isn't
+ // optimized away.
+ copy_client_.add_draw_rect(gfx::Rect(0, 0, 10, 10), flags);
// Doing a copy makes the layer have a render surface which can cause
// texture allocations. So get those allocations out of the way in the
// first frame by forcing it to have a render surface.
@@ -927,8 +937,9 @@ class LayerTreeHostCopyRequestTestCountTextures
// readback.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
- base::Unretained(this)));
+ base::BindOnce(
+ &LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
+ base::Unretained(this)));
break;
}
}
@@ -1065,8 +1076,9 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
- base::Unretained(this)));
+ base::BindOnce(
+ &LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
+ base::Unretained(this)));
}
void DidActivate() {
@@ -1142,8 +1154,9 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate,
- base::Unretained(this)));
+ base::BindOnce(
+ &LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate,
+ base::Unretained(this)));
}
void DidActivate() {
@@ -1168,8 +1181,9 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
// the main thread.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest,
- base::Unretained(this)));
+ base::BindOnce(
+ &LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest,
+ base::Unretained(this)));
break;
}
}
@@ -1227,14 +1241,12 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
bool saw_root = false;
bool saw_child = false;
- for (LayerIterator it =
- LayerIterator::Begin(frame_data->render_surface_layer_list);
- it != LayerIterator::End(frame_data->render_surface_layer_list);
- ++it) {
- if (it.represents_itself()) {
- if (*it == root)
+ for (EffectTreeLayerListIterator it(host_impl->active_tree());
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
+ if (it.state() == EffectTreeLayerListIterator::State::LAYER) {
+ if (it.current_layer() == root)
saw_root = true;
- else if (*it == child)
+ else if (it.current_layer() == child)
saw_child = true;
else
NOTREACHED();
@@ -1268,7 +1280,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
// to the main thread.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest::
TryEndTest,
base::Unretained(this), WhatHappened::DRAW));
diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
index 5873138ce5f..73d71a2d6dd 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
@@ -354,7 +354,6 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest {
FakePaintedScrollbarLayer::Create(false, true, content_layer_->id());
scrollbar_layer->SetPosition(gfx::PointF(300.f, 300.f));
scrollbar_layer->SetBounds(gfx::Size(10, 100));
- scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(content_layer_->id());
root_layer->AddChild(scrollbar_layer);
gfx::RectF content_rect(content_layer_->position(),
@@ -421,9 +420,10 @@ class LayerTreeHostDamageTestScrollbarDoesDamage
// Test that modifying the position of the content layer (not
// scrolling) won't damage the scrollbar.
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&LayerTreeHostDamageTestScrollbarDoesDamage::
- ModifyContentLayerPosition,
- base::Unretained(this)));
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostDamageTestScrollbarDoesDamage::
+ ModifyContentLayerPosition,
+ base::Unretained(this)));
break;
case 2:
scroll_layer->ScrollBy(gfx::Vector2dF(10.f, 10.f));
@@ -433,7 +433,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage
// We will resize the content layer, on the main thread.
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostDamageTestScrollbarDoesDamage::ResizeScrollLayer,
base::Unretained(this)));
break;
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index cbdd64173b9..55eabcb1eb7 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -250,11 +250,8 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
// Make the bottom of the layer visible.
gfx::Transform transform;
transform.Translate(0.f, -100000.f + 100.f);
- impl->active_tree()
- ->property_trees()
- ->transform_tree.OnTransformAnimated(
- transform, picture_impl->transform_tree_index(),
- impl->active_tree());
+ impl->active_tree()->SetTransformMutated(picture_impl->element_id(),
+ transform);
impl->SetNeedsRedraw();
break;
}
@@ -265,11 +262,8 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
EXPECT_FALSE(tiling->TileAt(0, 0));
// Make the top of the layer visible again.
- impl->active_tree()
- ->property_trees()
- ->transform_tree.OnTransformAnimated(
- gfx::Transform(), picture_impl->transform_tree_index(),
- impl->active_tree());
+ impl->active_tree()->SetTransformMutated(picture_impl->element_id(),
+ gfx::Transform());
impl->SetNeedsRedraw();
break;
}
@@ -458,19 +452,22 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
case 0:
// On 1st commit the pending layer has tilings.
ASSERT_EQ(1u, picture->tilings()->num_tilings());
- EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(),
+ picture->tilings()->tiling_at(0)->raster_transform());
break;
case 1:
// On 2nd commit, the pending layer is transparent, so has a stale
// value.
ASSERT_EQ(1u, picture->tilings()->num_tilings());
- EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(),
+ picture->tilings()->tiling_at(0)->raster_transform());
break;
case 2:
// On 3rd commit, the pending layer is visible again, so has tilings and
// is updated for the pinch.
ASSERT_EQ(1u, picture->tilings()->num_tilings());
- EXPECT_EQ(2.f, picture->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(2.f, gfx::Vector2dF()),
+ picture->tilings()->tiling_at(0)->raster_transform());
}
}
@@ -488,7 +485,8 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
if (draws_in_frame_ == 1) {
// On 1st commit the layer has tilings.
EXPECT_GT(picture->tilings()->num_tilings(), 0u);
- EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(),
+ picture->HighResTiling()->raster_transform());
// Pinch zoom in to change the scale on the active tree.
impl->PinchGestureBegin();
@@ -498,7 +496,8 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
// If the pinch gesture caused a commit we could get here with a
// pending tree.
EXPECT_FALSE(impl->pending_tree());
- EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(2.f, gfx::Vector2dF()),
+ picture->HighResTiling()->raster_transform());
// Need to wait for ready to draw here so that the pinch is
// entirely complete, otherwise another draw might come in before
@@ -507,7 +506,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
++frame_;
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
base::Unretained(this)));
}
@@ -524,7 +523,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
++frame_;
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
base::Unretained(this)));
break;
@@ -616,14 +615,16 @@ class LayerTreeHostPictureTestForceRecalculateScales
case 0:
// On first commit, both layers are at the default scale.
ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings());
- EXPECT_EQ(1.f,
- will_change_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(
+ gfx::AxisTransform2d(),
+ will_change_layer->tilings()->tiling_at(0)->raster_transform());
ASSERT_EQ(1u, normal_layer->tilings()->num_tilings());
- EXPECT_EQ(1.f, normal_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(),
+ normal_layer->tilings()->tiling_at(0)->raster_transform());
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&LayerTreeHostPictureTestForceRecalculateScales::ScaleRootUp,
base::Unretained(this)));
break;
@@ -631,25 +632,29 @@ class LayerTreeHostPictureTestForceRecalculateScales
// On 2nd commit after scaling up to 2, the normal layer will adjust its
// scale and the will change layer should not (as it is will change.
ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings());
- EXPECT_EQ(1.f,
- will_change_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(
+ gfx::AxisTransform2d(),
+ will_change_layer->tilings()->tiling_at(0)->raster_transform());
ASSERT_EQ(1u, normal_layer->tilings()->num_tilings());
- EXPECT_EQ(2.f, normal_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(2.f, gfx::Vector2dF()),
+ normal_layer->tilings()->tiling_at(0)->raster_transform());
MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostPictureTestForceRecalculateScales::
- ScaleRootUpAndRecalculateScales,
- base::Unretained(this)));
+ base::BindOnce(&LayerTreeHostPictureTestForceRecalculateScales::
+ ScaleRootUpAndRecalculateScales,
+ base::Unretained(this)));
break;
case 2:
// On 3rd commit, both layers should adjust scales due to forced
// recalculating.
ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings());
- EXPECT_EQ(4.f,
- will_change_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(
+ gfx::AxisTransform2d(4.f, gfx::Vector2dF()),
+ will_change_layer->tilings()->tiling_at(0)->raster_transform());
ASSERT_EQ(1u, normal_layer->tilings()->num_tilings());
- EXPECT_EQ(4.f, normal_layer->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_EQ(gfx::AxisTransform2d(4.f, gfx::Vector2dF()),
+ normal_layer->tilings()->tiling_at(0)->raster_transform());
EndTest();
break;
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index ec968022fe0..b547fefcc45 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -9,7 +9,6 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/base/completion_event.h"
#include "cc/input/main_thread_scrolling_reason.h"
@@ -570,6 +569,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
root_layer->SetBounds(gfx::Size(10, 10));
root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ root_scroll_layer_->SetElementId(
+ LayerIdToElementIdForTesting(root_scroll_layer_->id()));
root_scroll_layer_->SetBounds(gfx::Size(110, 110));
root_scroll_layer_->SetPosition(gfx::PointF());
root_scroll_layer_->SetIsDrawable(true);
@@ -582,6 +583,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
child_layer_->set_did_scroll_callback(
base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
base::Unretained(this)));
+ child_layer_->SetElementId(
+ LayerIdToElementIdForTesting(child_layer_->id()));
child_layer_->SetBounds(gfx::Size(110, 110));
if (scroll_child_layer_) {
@@ -599,6 +602,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
child_layer_->SetIsDrawable(true);
child_layer_->SetScrollClipLayerId(outer_container_layer->id());
+ child_layer_->SetElementId(
+ LayerIdToElementIdForTesting(child_layer_->id()));
child_layer_->SetBounds(root_scroll_layer_->bounds());
root_scroll_layer_->AddChild(child_layer_);
@@ -1314,7 +1319,7 @@ class ThreadCheckingInputHandlerClient : public InputHandlerClient {
void BindInputHandlerOnCompositorThread(
const base::WeakPtr<InputHandler>& input_handler,
ThreadCheckingInputHandlerClient* client) {
- input_handler->BindToClient(client);
+ input_handler->BindToClient(client, false);
}
TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
@@ -1342,9 +1347,9 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
ThreadCheckingInputHandlerClient input_handler_client(
impl_thread.task_runner().get(), &received_stop_flinging);
impl_thread.task_runner()->PostTask(
- FROM_HERE, base::Bind(&BindInputHandlerOnCompositorThread,
- layer_tree_host->GetInputHandler(),
- base::Unretained(&input_handler_client)));
+ FROM_HERE, base::BindOnce(&BindInputHandlerOnCompositorThread,
+ layer_tree_host->GetInputHandler(),
+ base::Unretained(&input_handler_client)));
layer_tree_host->DidStopFlinging();
@@ -1435,6 +1440,8 @@ class LayerTreeHostScrollTestLayerStructureChange
scroll_layer->SetPosition(gfx::PointF());
scroll_layer->SetIsDrawable(true);
scroll_layer->SetScrollClipLayerId(parent->id());
+ scroll_layer->SetElementId(
+ LayerIdToElementIdForTesting(scroll_layer->id()));
scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
parent->bounds().height() + 100));
scroll_layer->set_did_scroll_callback(base::Bind(
@@ -1861,15 +1868,15 @@ class LayerTreeHostScrollTestElasticOverscroll
DCHECK(HasImplThread());
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostScrollTestElasticOverscroll::BindInputHandler,
- base::Unretained(this),
- layer_tree_host()->GetInputHandler()));
+ base::BindOnce(
+ &LayerTreeHostScrollTestElasticOverscroll::BindInputHandler,
+ base::Unretained(this), layer_tree_host()->GetInputHandler()));
PostSetNeedsCommitToMainThread();
}
void BindInputHandler(base::WeakPtr<InputHandler> input_handler) {
DCHECK(task_runner_provider()->IsImplThread());
- input_handler->BindToClient(&input_handler_client_);
+ input_handler->BindToClient(&input_handler_client_, false);
scroll_elasticity_helper_ = input_handler->CreateScrollElasticityHelper();
DCHECK(scroll_elasticity_helper_);
}
@@ -2072,20 +2079,11 @@ class LayerTreeHostScrollTestPropertyTreeUpdate
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate);
-// Disabled due to flakes/crashes on Linux TSan Tests and on
-// linux_chromium_asan_rel; see https://crbug.com/697652.
-#if defined(OS_LINUX)
-#define MAYBE_LayerTreeHostScrollTestImplSideInvalidation \
- DISABLED_LayerTreeHostScrollTestImplSideInvalidation
-#else
-#define MAYBE_LayerTreeHostScrollTestImplSideInvalidation \
- LayerTreeHostScrollTestImplSideInvalidation
-#endif
-class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
+class LayerTreeHostScrollTestImplSideInvalidation
: public LayerTreeHostScrollTest {
void BeginTest() override {
layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
- base::Bind(&MAYBE_LayerTreeHostScrollTestImplSideInvalidation::
+ base::Bind(&LayerTreeHostScrollTestImplSideInvalidation::
DidScrollOuterViewport,
base::Unretained(this)));
PostSetNeedsCommitToMainThread();
@@ -2098,9 +2096,9 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
CompletionEvent completion;
task_runner_provider()->ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&MAYBE_LayerTreeHostScrollTestImplSideInvalidation::
- WaitForInvalidationOnImplThread,
- base::Unretained(this), &completion));
+ base::BindOnce(&LayerTreeHostScrollTestImplSideInvalidation::
+ WaitForInvalidationOnImplThread,
+ base::Unretained(this), &completion));
completion.Wait();
}
@@ -2172,18 +2170,11 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
CommitEarlyOutReason reason) override {
- // The aborted main frame is bound to come after the fourth activation,
- // since the activation should occur synchronously after the impl-side
- // invalidation, and the main thread is released after this activation. It
- // should leave the scroll offset unchanged.
- EXPECT_EQ(reason, CommitEarlyOutReason::FINISHED_NO_UPDATES);
- EXPECT_EQ(num_of_activations_, 4);
- EXPECT_EQ(num_of_main_frames_, 3);
- EXPECT_EQ(host_impl->active_tree()
- ->OuterViewportScrollLayer()
- ->CurrentScrollOffset(),
- outer_viewport_offsets_[2]);
- EndTest();
+ EXPECT_EQ(CommitEarlyOutReason::FINISHED_NO_UPDATES, reason);
+ EXPECT_EQ(3, num_of_main_frames_);
+ EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree()
+ ->OuterViewportScrollLayer()
+ ->CurrentScrollOffset());
}
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
@@ -2200,11 +2191,10 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
// The second activation is from an impl-side pending tree so the source
// frame number on the active tree remains unchanged, and the scroll
// offset on the active tree should also remain unchanged.
- EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 0);
- EXPECT_EQ(host_impl->active_tree()
- ->OuterViewportScrollLayer()
- ->CurrentScrollOffset(),
- outer_viewport_offsets_[1]);
+ EXPECT_EQ(0, host_impl->active_tree()->source_frame_number());
+ EXPECT_EQ(outer_viewport_offsets_[1], host_impl->active_tree()
+ ->OuterViewportScrollLayer()
+ ->CurrentScrollOffset());
break;
case 3:
// The third activation is from a commit. The scroll offset on the
@@ -2218,21 +2208,25 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
case 4:
// The fourth activation is from an impl-side pending tree, which should
// leave the scroll offset unchanged.
- EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 1);
- EXPECT_EQ(host_impl->active_tree()
- ->OuterViewportScrollLayer()
- ->CurrentScrollOffset(),
- outer_viewport_offsets_[2]);
+ EXPECT_EQ(1, host_impl->active_tree()->source_frame_number());
+ EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree()
+ ->OuterViewportScrollLayer()
+ ->CurrentScrollOffset());
break;
default:
NOTREACHED();
}
}
+ void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ if (++num_of_draws_ == 4)
+ EndTest();
+ }
+
void AfterTest() override {
- EXPECT_EQ(num_of_activations_, 4);
- EXPECT_EQ(num_of_deltas_, 2);
- EXPECT_EQ(num_of_main_frames_, 3);
+ EXPECT_EQ(4, num_of_activations_);
+ EXPECT_EQ(2, num_of_deltas_);
+ EXPECT_EQ(3, num_of_main_frames_);
}
const gfx::ScrollOffset outer_viewport_offsets_[3] = {
@@ -2241,6 +2235,7 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
// Impl thread.
int num_of_activations_ = 0;
+ int num_of_draws_ = 0;
int num_of_main_frames_ = 0;
bool invalidated_on_impl_thread_ = false;
CompletionEvent* impl_side_invalidation_event_ = nullptr;
@@ -2249,7 +2244,7 @@ class MAYBE_LayerTreeHostScrollTestImplSideInvalidation
int num_of_deltas_ = 0;
};
-MULTI_THREAD_TEST_F(MAYBE_LayerTreeHostScrollTestImplSideInvalidation);
+MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplSideInvalidation);
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index 08ca53054cb..12ebf3fa413 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -17,16 +17,16 @@
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
#include "cc/base/synced_property.h"
-#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
#include "cc/input/page_scale_animation.h"
#include "cc/input/scrollbar_animation_controller.h"
+#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
-#include "cc/layers/layer_iterator.h"
#include "cc/layers/layer_list_iterator.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/layers/scrollbar_layer_impl_base.h"
@@ -243,27 +243,31 @@ void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) {
}
bool scrollbar_needs_animation = false;
+ bool clip_layer_size_did_change = false;
bool scroll_layer_size_did_change = false;
bool y_offset_did_change = false;
for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(scroll_layer_id)) {
if (scrollbar->orientation() == HORIZONTAL) {
scrollbar_needs_animation |= scrollbar->SetCurrentPos(current_offset.x());
- scrollbar_needs_animation |=
+ clip_layer_size_did_change |=
scrollbar->SetClipLayerLength(clip_size.width());
- scrollbar_needs_animation |= scroll_layer_size_did_change |=
+ scroll_layer_size_did_change |=
scrollbar->SetScrollLayerLength(scroll_size.width());
} else {
scrollbar_needs_animation |= y_offset_did_change |=
scrollbar->SetCurrentPos(current_offset.y());
- scrollbar_needs_animation |=
+ clip_layer_size_did_change |=
scrollbar->SetClipLayerLength(clip_size.height());
- scrollbar_needs_animation |= scroll_layer_size_did_change |=
+ scroll_layer_size_did_change |=
scrollbar->SetScrollLayerLength(scroll_size.height());
}
scrollbar_needs_animation |=
scrollbar->SetVerticalAdjust(clip_layer->bounds_delta().y());
}
+ scrollbar_needs_animation |=
+ (clip_layer_size_did_change || scroll_layer_size_did_change);
+
if (y_offset_did_change && IsViewportLayerId(scroll_layer_id))
TRACE_COUNTER_ID1("cc", "scroll_offset_y", scroll_layer->id(),
current_offset.y());
@@ -272,8 +276,16 @@ void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) {
ScrollbarAnimationController* controller =
layer_tree_host_impl_->ScrollbarAnimationControllerForId(
scroll_layer_id);
- if (controller)
- controller->DidScrollUpdate(scroll_layer_size_did_change);
+ if (!controller)
+ return;
+
+ // TODO(chaopeng) clip_layer_size_did_change should call DidResize after
+ // crbug.com/701810 got fixed.
+ if (scroll_layer_size_did_change) {
+ controller->DidResize();
+ } else {
+ controller->DidScrollUpdate();
+ }
}
}
@@ -485,11 +497,13 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
max_page_scale_factor());
target_tree->SetDeviceScaleFactor(device_scale_factor());
target_tree->set_painted_device_scale_factor(painted_device_scale_factor());
- target_tree->SetDeviceColorSpace(device_color_space_);
+ target_tree->SetRasterColorSpace(raster_color_space_);
target_tree->elastic_overscroll()->PushPendingToActive();
target_tree->set_content_source_id(content_source_id());
+ target_tree->set_local_surface_id(local_surface_id());
+
target_tree->pending_page_scale_animation_ =
std::move(pending_page_scale_animation_);
@@ -527,6 +541,23 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->set_hud_layer(NULL);
target_tree->has_ever_been_drawn_ = false;
+
+ // Note: this needs to happen after SetPropertyTrees.
+ target_tree->ShowScrollbars();
+}
+
+void LayerTreeImpl::ShowScrollbars() {
+ LayerTreeHostCommon::CallFunctionForEveryLayer(this, [this](
+ LayerImpl* layer) {
+ if (!layer->needs_show_scrollbars())
+ return;
+ ScrollbarAnimationController* controller =
+ layer_tree_host_impl_->ScrollbarAnimationControllerForId(layer->id());
+ if (controller) {
+ controller->DidRequestShowFromMainThread();
+ layer->set_needs_show_scrollbars(false);
+ }
+ });
}
void LayerTreeImpl::MoveChangeTrackingToLayers() {
@@ -624,17 +655,40 @@ void LayerTreeImpl::RemoveFromElementMap(LayerImpl* layer) {
}
void LayerTreeImpl::AddToOpacityAnimationsMap(int id, float opacity) {
- opacity_animations_map_[id] = opacity;
+ if (LayerImpl* layer = LayerById(id))
+ element_id_to_opacity_animations_[layer->element_id()] = opacity;
+}
+
+void LayerTreeImpl::SetTransformMutated(ElementId element_id,
+ const gfx::Transform& transform) {
+ DCHECK_EQ(1u, property_trees()->element_id_to_transform_node_index.count(
+ element_id));
+ element_id_to_transform_animations_[element_id] = transform;
+ if (!property_trees()->transform_tree.OnTransformAnimated(element_id,
+ transform))
+ return;
+
+ if (LayerImpl* layer = LayerByElementId(element_id))
+ layer->set_was_ever_ready_since_last_transform_animation(false);
+
+ set_needs_update_draw_properties();
}
-void LayerTreeImpl::AddToTransformAnimationsMap(int id,
- gfx::Transform transform) {
- transform_animations_map_[id] = transform;
+void LayerTreeImpl::SetOpacityMutated(ElementId element_id, float opacity) {
+ DCHECK_EQ(
+ 1u, property_trees()->element_id_to_effect_node_index.count(element_id));
+ element_id_to_opacity_animations_[element_id] = opacity;
+ if (property_trees()->effect_tree.OnOpacityAnimated(element_id, opacity))
+ set_needs_update_draw_properties();
}
-void LayerTreeImpl::AddToFilterAnimationsMap(int id,
- const FilterOperations& filters) {
- filter_animations_map_[id] = filters;
+void LayerTreeImpl::SetFilterMutated(ElementId element_id,
+ const FilterOperations& filters) {
+ DCHECK_EQ(
+ 1u, property_trees()->element_id_to_effect_node_index.count(element_id));
+ element_id_to_filter_animations_[element_id] = filters;
+ if (property_trees()->effect_tree.OnFilterAnimated(element_id, filters))
+ set_needs_update_draw_properties();
}
LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
@@ -668,17 +722,28 @@ void LayerTreeImpl::SetCurrentlyScrollingNode(ScrollNode* node) {
ScrollTree& scroll_tree = property_trees()->scroll_tree;
ScrollNode* old_node = scroll_tree.CurrentlyScrollingNode();
- // TODO(pdr): Refactor these to not use owning_layer_id.
+
+ ElementId old_element_id = old_node ? old_node->element_id : ElementId();
+ ElementId new_element_id = node ? node->element_id : ElementId();
+
+#if DCHECK_IS_ON()
int old_layer_id = old_node ? old_node->owning_layer_id : Layer::INVALID_ID;
int new_layer_id = node ? node->owning_layer_id : Layer::INVALID_ID;
+ DCHECK(old_layer_id == LayerIdByElementId(old_element_id));
+ DCHECK(new_layer_id == LayerIdByElementId(new_element_id));
+#endif
- if (old_layer_id == new_layer_id)
+ if (old_element_id == new_element_id)
return;
+ // TODO(pdr): Make the scrollbar animation controller lookup based on
+ // element ids instead of layer ids.
ScrollbarAnimationController* old_animation_controller =
- layer_tree_host_impl_->ScrollbarAnimationControllerForId(old_layer_id);
+ layer_tree_host_impl_->ScrollbarAnimationControllerForId(
+ LayerIdByElementId(old_element_id));
ScrollbarAnimationController* new_animation_controller =
- layer_tree_host_impl_->ScrollbarAnimationControllerForId(new_layer_id);
+ layer_tree_host_impl_->ScrollbarAnimationControllerForId(
+ LayerIdByElementId(new_element_id));
if (old_animation_controller)
old_animation_controller->DidScrollEnd();
@@ -710,61 +775,54 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() {
// frame to a newly-committed property tree.
if (layer_list_.empty())
return;
- std::vector<int> layer_ids_to_remove;
- for (auto& layer_id_to_opacity : opacity_animations_map_) {
- const int id = layer_id_to_opacity.first;
- if (property_trees_.IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT, id)) {
- EffectNode* node = property_trees_.effect_tree.Node(
- property_trees_.layer_id_to_effect_node_index[id]);
+ auto element_id_to_opacity = element_id_to_opacity_animations_.begin();
+ while (element_id_to_opacity != element_id_to_opacity_animations_.end()) {
+ const ElementId id = element_id_to_opacity->first;
+ if (EffectNode* node =
+ property_trees_.effect_tree.FindNodeFromElementId(id)) {
if (!node->is_currently_animating_opacity ||
- node->opacity == layer_id_to_opacity.second) {
- layer_ids_to_remove.push_back(id);
+ node->opacity == element_id_to_opacity->second) {
+ element_id_to_opacity_animations_.erase(element_id_to_opacity++);
continue;
}
- node->opacity = layer_id_to_opacity.second;
+ node->opacity = element_id_to_opacity->second;
property_trees_.effect_tree.set_needs_update(true);
}
+ ++element_id_to_opacity;
}
- for (auto id : layer_ids_to_remove)
- opacity_animations_map_.erase(id);
- layer_ids_to_remove.clear();
-
- for (auto& layer_id_to_transform : transform_animations_map_) {
- const int id = layer_id_to_transform.first;
- if (property_trees_.IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
- id)) {
- TransformNode* node = property_trees_.transform_tree.Node(
- property_trees_.layer_id_to_transform_node_index[id]);
- if (!node->is_currently_animating ||
- node->local == layer_id_to_transform.second) {
- layer_ids_to_remove.push_back(id);
+
+ auto element_id_to_filter = element_id_to_filter_animations_.begin();
+ while (element_id_to_filter != element_id_to_filter_animations_.end()) {
+ const ElementId id = element_id_to_filter->first;
+ if (EffectNode* node =
+ property_trees_.effect_tree.FindNodeFromElementId(id)) {
+ if (!node->is_currently_animating_filter ||
+ node->filters == element_id_to_filter->second) {
+ element_id_to_filter_animations_.erase(element_id_to_filter++);
continue;
}
- node->local = layer_id_to_transform.second;
- node->needs_local_transform_update = true;
- property_trees_.transform_tree.set_needs_update(true);
+ node->filters = element_id_to_filter->second;
+ property_trees_.effect_tree.set_needs_update(true);
}
+ ++element_id_to_filter;
}
- for (auto id : layer_ids_to_remove)
- transform_animations_map_.erase(id);
- layer_ids_to_remove.clear();
-
- for (auto& layer_id_to_filters : filter_animations_map_) {
- const int id = layer_id_to_filters.first;
- if (property_trees_.IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT, id)) {
- EffectNode* node = property_trees_.effect_tree.Node(
- property_trees_.layer_id_to_effect_node_index[id]);
- if (!node->is_currently_animating_filter ||
- node->filters == layer_id_to_filters.second) {
- layer_ids_to_remove.push_back(id);
+
+ auto element_id_to_transform = element_id_to_transform_animations_.begin();
+ while (element_id_to_transform != element_id_to_transform_animations_.end()) {
+ const ElementId id = element_id_to_transform->first;
+ if (TransformNode* node =
+ property_trees_.transform_tree.FindNodeFromElementId(id)) {
+ if (!node->is_currently_animating ||
+ node->local == element_id_to_transform->second) {
+ element_id_to_transform_animations_.erase(element_id_to_transform++);
continue;
}
- node->filters = layer_id_to_filters.second;
- property_trees_.effect_tree.set_needs_update(true);
+ node->local = element_id_to_transform->second;
+ node->needs_local_transform_update = true;
+ property_trees_.transform_tree.set_needs_update(true);
}
+ ++element_id_to_transform;
}
- for (auto id : layer_ids_to_remove)
- filter_animations_map_.erase(id);
LayerTreeHostCommon::CallFunctionForEveryLayer(this, [](LayerImpl* layer) {
layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
@@ -926,11 +984,11 @@ void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
layer_tree_host_impl_->SetNeedUpdateGpuRasterizationStatus();
}
-void LayerTreeImpl::SetDeviceColorSpace(
- const gfx::ColorSpace& device_color_space) {
- if (device_color_space == device_color_space_)
+void LayerTreeImpl::SetRasterColorSpace(
+ const gfx::ColorSpace& raster_color_space) {
+ if (raster_color_space == raster_color_space_)
return;
- device_color_space_ = device_color_space;
+ raster_color_space_ = raster_color_space;
}
SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
@@ -999,13 +1057,12 @@ static void SetElementIdForTesting(LayerImpl* layer) {
void LayerTreeImpl::SetElementIdsForTesting() {
LayerListIterator<LayerImpl> it(root_layer_for_testing_);
for (; it != LayerListIterator<LayerImpl>(nullptr); ++it) {
- SetElementIdForTesting(*it);
+ if (!it->element_id())
+ SetElementIdForTesting(*it);
}
}
-bool LayerTreeImpl::UpdateDrawProperties(
- bool update_lcd_text,
- bool force_skip_verify_visible_rect_calculations) {
+bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
if (!needs_update_draw_properties_)
return true;
@@ -1037,10 +1094,6 @@ bool LayerTreeImpl::UpdateDrawProperties(
// We verify visible rect calculations whenever we verify clip tree
// calculations except when this function is explicitly passed a flag asking
// us to skip it.
- bool verify_visible_rect_calculations =
- force_skip_verify_visible_rect_calculations
- ? false
- : settings().verify_clip_tree_calculations;
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
layer_list_[0], DrawViewportSize(),
layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
@@ -1050,8 +1103,7 @@ bool LayerTreeImpl::UpdateDrawProperties(
OverscrollElasticityLayer(), resource_provider()->max_texture_size(),
can_render_to_separate_surface,
settings().layer_transforms_should_scale_layer_contents,
- settings().verify_clip_tree_calculations,
- verify_visible_rect_calculations, &render_surface_layer_list_,
+ settings().use_layer_lists, &render_surface_layer_list_,
&property_trees_);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
if (const char* client_name = GetClientNameForMetrics()) {
@@ -1075,24 +1127,23 @@ bool LayerTreeImpl::UpdateDrawProperties(
occlusion_tracker.set_minimum_tracking_size(
settings().minimum_occlusion_tracking_size);
- // LayerIterator is used here instead of CallFunctionForEveryLayer to only
- // UpdateTilePriorities on layers that will be visible (and thus have valid
- // draw properties) and not because any ordering is required.
- LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
- for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
- it != end; ++it) {
+ for (EffectTreeLayerListIterator it(this);
+ it.state() != EffectTreeLayerListIterator::State::END; ++it) {
occlusion_tracker.EnterLayer(it);
- if (it.represents_itself()) {
- it->draw_properties().occlusion_in_content_space =
- occlusion_tracker.GetCurrentOcclusionForLayer(it->DrawTransform());
+ if (it.state() == EffectTreeLayerListIterator::State::LAYER) {
+ LayerImpl* layer = it.current_layer();
+ layer->draw_properties().occlusion_in_content_space =
+ occlusion_tracker.GetCurrentOcclusionForLayer(
+ layer->DrawTransform());
}
- if (it.represents_contributing_render_surface()) {
+ if (it.state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
const RenderSurfaceImpl* occlusion_surface =
occlusion_tracker.OcclusionSurfaceForContributingSurface();
gfx::Transform draw_transform;
- RenderSurfaceImpl* render_surface = it->GetRenderSurface();
+ RenderSurfaceImpl* render_surface = it.current_render_surface();
if (occlusion_surface) {
// We are calculating transform between two render surfaces. So, we
// need to apply the surface contents scale at target and remove the
@@ -1116,7 +1167,7 @@ bool LayerTreeImpl::UpdateDrawProperties(
if (LayerImpl* mask = render_surface->MaskLayer()) {
mask->draw_properties().occlusion_in_content_space =
occlusion_tracker.GetCurrentOcclusionForContributingSurface(
- draw_transform * it->DrawTransform());
+ draw_transform * render_surface->SurfaceScale());
}
}
@@ -1178,7 +1229,7 @@ void LayerTreeImpl::BuildLayerListAndPropertyTreesForTesting() {
}
void LayerTreeImpl::BuildPropertyTreesForTesting() {
- PropertyTreeBuilder::PreCalculateMetaInformationForTesting(layer_list_[0]);
+ SetElementIdsForTesting();
property_trees_.needs_rebuild = true;
property_trees_.transform_tree.set_source_to_parent_updates_allowed(true);
PropertyTreeBuilder::BuildPropertyTrees(
@@ -1250,14 +1301,16 @@ void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
DCHECK(LayerById(layer->id()));
layers_that_should_push_properties_.erase(layer);
- transform_animations_map_.erase(layer->id());
- opacity_animations_map_.erase(layer->id());
+ element_id_to_transform_animations_.erase(layer->element_id());
+ element_id_to_opacity_animations_.erase(layer->element_id());
+ element_id_to_filter_animations_.erase(layer->element_id());
layer_id_map_.erase(layer->id());
}
// These manage ownership of the LayerImpl.
void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) {
DCHECK(std::find(layers_->begin(), layers_->end(), layer) == layers_->end());
+ DCHECK(layer);
layers_->push_back(std::move(layer));
set_needs_update_draw_properties();
}
@@ -1417,29 +1470,26 @@ const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
std::unique_ptr<ScrollbarAnimationController>
LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) {
- DCHECK(!settings().scrollbar_fade_out_delay.is_zero());
- DCHECK(!settings().scrollbar_fade_out_duration.is_zero());
- base::TimeDelta fade_out_delay = settings().scrollbar_fade_out_delay;
+ DCHECK(!settings().scrollbar_fade_delay.is_zero());
+ DCHECK(!settings().scrollbar_fade_duration.is_zero());
+ base::TimeDelta fade_delay = settings().scrollbar_fade_delay;
base::TimeDelta fade_out_resize_delay =
settings().scrollbar_fade_out_resize_delay;
- base::TimeDelta fade_out_duration = settings().scrollbar_fade_out_duration;
+ base::TimeDelta fade_duration = settings().scrollbar_fade_duration;
switch (settings().scrollbar_animator) {
case LayerTreeSettings::ANDROID_OVERLAY: {
return ScrollbarAnimationController::
CreateScrollbarAnimationControllerAndroid(
- scroll_layer_id, layer_tree_host_impl_, fade_out_delay,
- fade_out_resize_delay, fade_out_duration);
+ scroll_layer_id, layer_tree_host_impl_, fade_delay,
+ fade_out_resize_delay, fade_duration);
}
case LayerTreeSettings::AURA_OVERLAY: {
- DCHECK(!settings().scrollbar_show_delay.is_zero());
- base::TimeDelta show_delay = settings().scrollbar_show_delay;
base::TimeDelta thinning_duration =
settings().scrollbar_thinning_duration;
return ScrollbarAnimationController::
CreateScrollbarAnimationControllerAuraOverlay(
- scroll_layer_id, layer_tree_host_impl_, show_delay,
- fade_out_delay, fade_out_resize_delay, fade_out_duration,
- thinning_duration);
+ scroll_layer_id, layer_tree_host_impl_, fade_delay,
+ fade_out_resize_delay, fade_duration, thinning_duration);
}
case LayerTreeSettings::NO_ANIMATOR:
NOTREACHED();
@@ -1470,12 +1520,10 @@ void LayerTreeImpl::SetNeedsRedraw() {
void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
std::vector<PrioritizedTile>* prioritized_tiles) const {
- LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
- for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
- it != end; ++it) {
- if (!it.represents_itself())
- continue;
+ for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) {
LayerImpl* layer_impl = *it;
+ if (!layer_impl->is_drawn_render_surface_layer_list_member())
+ continue;
layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles);
}
}
@@ -1485,10 +1533,8 @@ void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetInteger("source_frame_number", source_frame_number_);
state->BeginArray("render_surface_layer_list");
- LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
- for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
- it != end; ++it) {
- if (!it.represents_itself())
+ for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) {
+ if (!(*it)->is_drawn_render_surface_layer_list_member())
continue;
TracedValue::AppendIDRef(*it, state);
}
@@ -1741,11 +1787,6 @@ void LayerTreeImpl::RemoveSurfaceLayer(LayerImpl* layer) {
surface_layers_.erase(it);
}
-template <typename LayerType>
-static inline bool LayerClipsSubtree(LayerType* layer) {
- return layer->masks_to_bounds() || layer->mask_layer();
-}
-
static bool PointHitsRect(
const gfx::PointF& screen_space_point,
const gfx::Transform& local_space_to_screen_space_transform,
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 02c6e994d3d..1d785f86e4e 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -145,9 +145,14 @@ class CC_EXPORT LayerTreeImpl {
LayerImplList::reverse_iterator rbegin();
LayerImplList::reverse_iterator rend();
+ // TODO(crbug.com/702832): This won't be needed if overlay scrollbars have
+ // element ids.
void AddToOpacityAnimationsMap(int id, float opacity);
- void AddToTransformAnimationsMap(int id, gfx::Transform transform);
- void AddToFilterAnimationsMap(int id, const FilterOperations& filters);
+
+ void SetTransformMutated(ElementId element_id,
+ const gfx::Transform& transform);
+ void SetOpacityMutated(ElementId element_id, float opacity);
+ void SetFilterMutated(ElementId element_id, const FilterOperations& filters);
int source_frame_number() const { return source_frame_number_; }
void set_source_frame_number(int frame_number) {
@@ -232,9 +237,14 @@ class CC_EXPORT LayerTreeImpl {
void set_content_source_id(uint32_t id) { content_source_id_ = id; }
uint32_t content_source_id() { return content_source_id_; }
- void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
- const gfx::ColorSpace& device_color_space() const {
- return device_color_space_;
+ void set_local_surface_id(const LocalSurfaceId& id) {
+ local_surface_id_ = id;
+ }
+ const LocalSurfaceId& local_surface_id() const { return local_surface_id_; }
+
+ void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space);
+ const gfx::ColorSpace& raster_color_space() const {
+ return raster_color_space_;
}
SyncedElasticOverscroll* elastic_overscroll() {
@@ -256,9 +266,7 @@ class CC_EXPORT LayerTreeImpl {
// Updates draw properties and render surface layer list, as well as tile
// priorities. Returns false if it was unable to update. Updating lcd
// text may cause invalidations, so should only be done after a commit.
- bool UpdateDrawProperties(
- bool update_lcd_text,
- bool force_skip_verify_visible_rect_calculations = false);
+ bool UpdateDrawProperties(bool update_lcd_text);
void BuildPropertyTreesForTesting();
void BuildLayerListAndPropertyTreesForTesting();
@@ -469,6 +477,7 @@ class CC_EXPORT LayerTreeImpl {
float max_page_scale_factor);
bool IsViewportLayerId(int id) const;
void UpdateScrollbars(int scroll_layer_id, int clip_layer_id);
+ void ShowScrollbars();
void DidUpdatePageScale();
void PushBrowserControls(const float* top_controls_shown_ratio);
bool ClampBrowserControlsShownRatio();
@@ -496,9 +505,10 @@ class CC_EXPORT LayerTreeImpl {
float device_scale_factor_;
float painted_device_scale_factor_;
- gfx::ColorSpace device_color_space_;
+ gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
+ LocalSurfaceId local_surface_id_;
scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_;
@@ -510,9 +520,12 @@ class CC_EXPORT LayerTreeImpl {
std::unordered_map<ElementId, int, ElementIdHash> element_layers_map_;
- std::unordered_map<int, float> opacity_animations_map_;
- std::unordered_map<int, gfx::Transform> transform_animations_map_;
- std::unordered_map<int, FilterOperations> filter_animations_map_;
+ std::unordered_map<ElementId, float, ElementIdHash>
+ element_id_to_opacity_animations_;
+ std::unordered_map<ElementId, gfx::Transform, ElementIdHash>
+ element_id_to_transform_animations_;
+ std::unordered_map<ElementId, FilterOperations, ElementIdHash>
+ element_id_to_filter_animations_;
// Maps from clip layer ids to scroll layer ids. Note that this only includes
// the subset of clip layers that act as scrolling containers. (This is
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index 81d2800c986..3b0cbeec663 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -10,7 +10,6 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
-#include "cc/test/layer_tree_settings_for_testing.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/layer_tree_host_common.h"
@@ -22,7 +21,7 @@
namespace cc {
namespace {
-class LayerTreeImplTestSettings : public LayerTreeSettingsForTesting {
+class LayerTreeImplTestSettings : public LayerTreeSettings {
public:
LayerTreeImplTestSettings() {
layer_transforms_should_scale_layer_contents = true;
@@ -41,9 +40,7 @@ class LayerTreeImplTest : public testing::Test {
return host_impl().active_tree()->RenderSurfaceLayerList();
}
- void ExecuteCalculateDrawProperties(
- LayerImpl* root_layer,
- bool skip_verify_visible_rect_calculations = false) {
+ void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
// We are probably not testing what is intended if the root_layer bounds are
// empty.
DCHECK(!root_layer->bounds().IsEmpty());
@@ -52,8 +49,6 @@ class LayerTreeImplTest : public testing::Test {
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_layer_list_impl_);
inputs.can_adjust_raster_scales = true;
- if (skip_verify_visible_rect_calculations)
- inputs.verify_visible_rect_calculations = false;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
@@ -247,14 +242,7 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) {
root->SetDrawsContent(true);
host_impl().SetViewportSize(root->bounds());
- // While computing visible rects by combining clips in screen space, we set
- // the entire layer as visible if the screen space transform is singular. This
- // is not always true when we combine clips in target space because if the
- // intersection of combined_clip in taret space with layer_rect projected to
- // target space is empty, we set it to an empty rect.
- bool skip_verify_visible_rect_calculations = true;
- host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(
- skip_verify_visible_rect_calculations);
+ host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
// Sanity check the scenario we just created.
ASSERT_EQ(1u, RenderSurfaceLayerList().size());
ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size());
@@ -441,10 +429,6 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) {
host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
ASSERT_TRUE(result_layer);
EXPECT_EQ(5, result_layer->id());
-
- ClipTree& clip_tree = host_impl().active_tree()->property_trees()->clip_tree;
- ClipNode* clip_node = clip_tree.Node(result_layer->clip_tree_index());
- EXPECT_NE(clip_node->transform_id, clip_node->target_transform_id);
}
TEST_F(LayerTreeImplTest, HitTestingSiblings) {
@@ -637,7 +621,6 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
// Visible rects computed by combinig clips in target space and root space
// don't match because of rotation transforms. So, we skip
// verify_visible_rect_calculations.
- bool skip_verify_visible_rect_calculations = true;
{
std::unique_ptr<LayerImpl> child =
LayerImpl::Create(host_impl().active_tree(), 456);
@@ -677,12 +660,11 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
child->test_properties()->AddChild(std::move(grand_child));
root->test_properties()->AddChild(std::move(child));
- ExecuteCalculateDrawProperties(root, skip_verify_visible_rect_calculations);
+ ExecuteCalculateDrawProperties(root);
}
host_impl().SetViewportSize(root->bounds());
- host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(
- skip_verify_visible_rect_calculations);
+ host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
// (11, 89) is close to the the bottom left corner within the clip, but it is
// not inside the layer.
gfx::PointF test_point(11.f, 89.f);
@@ -1073,7 +1055,7 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) {
std::unique_ptr<std::set<LayerImpl*>> clip_children(
new std::set<LayerImpl*>);
clip_children->insert(grand_child.get());
- root->test_properties()->clip_children.reset(clip_children.release());
+ root->test_properties()->clip_children = std::move(clip_children);
child->test_properties()->AddChild(std::move(grand_child));
root->test_properties()->AddChild(std::move(child));
@@ -1343,14 +1325,7 @@ TEST_F(LayerTreeImplTest,
root->SetTouchEventHandlerRegion(touch_handler_region);
host_impl().SetViewportSize(root->bounds());
- // While computing visible rects by combining clips in screen space, we set
- // the entire layer as visible if the screen space transform is singular. This
- // is not always true when we combine clips in target space because if the
- // intersection of combined_clip in taret space with layer_rect projected to
- // target space is empty, we set it to an empty rect.
- bool skip_verify_visible_rect_calculations = true;
- host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(
- skip_verify_visible_rect_calculations);
+ host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
// Sanity check the scenario we just created.
ASSERT_EQ(1u, RenderSurfaceLayerList().size());
@@ -2242,13 +2217,13 @@ TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) {
EXPECT_TRUE(host_impl().active_tree()->needs_update_draw_properties());
}
-TEST_F(LayerTreeImplTest, DeviceColorSpaceDoesNotNeedDrawPropertiesUpdate) {
+TEST_F(LayerTreeImplTest, RasterColorSpaceDoesNotNeedDrawPropertiesUpdate) {
host_impl().active_tree()->BuildPropertyTreesForTesting();
- host_impl().active_tree()->SetDeviceColorSpace(
+ host_impl().active_tree()->SetRasterColorSpace(
gfx::ColorSpace::CreateXYZD50());
host_impl().active_tree()->UpdateDrawProperties(false);
EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
- host_impl().active_tree()->SetDeviceColorSpace(gfx::ColorSpace::CreateSRGB());
+ host_impl().active_tree()->SetRasterColorSpace(gfx::ColorSpace::CreateSRGB());
EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
}
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index 9233ca2eec9..f7a1578bec8 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -7,7 +7,7 @@
#include "base/callback_forward.h"
#include "base/time/time.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace cc {
diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc
index de32ad805da..2b8531c9e01 100644
--- a/chromium/cc/trees/layer_tree_settings.cc
+++ b/chromium/cc/trees/layer_tree_settings.cc
@@ -22,68 +22,6 @@ LayerTreeSettings::LayerTreeSettings()
LayerTreeSettings::LayerTreeSettings(const LayerTreeSettings& other) = default;
LayerTreeSettings::~LayerTreeSettings() = default;
-bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const {
- return renderer_settings == other.renderer_settings &&
- single_thread_proxy_scheduler == other.single_thread_proxy_scheduler &&
- main_frame_before_activation_enabled ==
- other.main_frame_before_activation_enabled &&
- using_synchronous_renderer_compositor ==
- other.using_synchronous_renderer_compositor &&
- enable_latency_recovery == other.enable_latency_recovery &&
- can_use_lcd_text == other.can_use_lcd_text &&
- use_distance_field_text == other.use_distance_field_text &&
- gpu_rasterization_forced == other.gpu_rasterization_forced &&
- async_worker_context_enabled == other.async_worker_context_enabled &&
- gpu_rasterization_msaa_sample_count ==
- other.gpu_rasterization_msaa_sample_count &&
- create_low_res_tiling == other.create_low_res_tiling &&
- scrollbar_animator == other.scrollbar_animator &&
- scrollbar_show_delay == other.scrollbar_show_delay &&
- scrollbar_fade_out_delay == other.scrollbar_fade_out_delay &&
- scrollbar_fade_out_resize_delay ==
- other.scrollbar_fade_out_resize_delay &&
- scrollbar_fade_out_duration == other.scrollbar_fade_out_duration &&
- solid_color_scrollbar_color == other.solid_color_scrollbar_color &&
- timeout_and_draw_when_animation_checkerboards ==
- other.timeout_and_draw_when_animation_checkerboards &&
- layer_transforms_should_scale_layer_contents ==
- other.layer_transforms_should_scale_layer_contents &&
- layers_always_allowed_lcd_text ==
- other.layers_always_allowed_lcd_text &&
- minimum_contents_scale == other.minimum_contents_scale &&
- low_res_contents_scale_factor == other.low_res_contents_scale_factor &&
- top_controls_show_threshold == other.top_controls_show_threshold &&
- top_controls_hide_threshold == other.top_controls_hide_threshold &&
- background_animation_rate == other.background_animation_rate &&
- default_tile_size == other.default_tile_size &&
- max_untiled_layer_size == other.max_untiled_layer_size &&
- minimum_occlusion_tracking_size ==
- other.minimum_occlusion_tracking_size &&
- tiling_interest_area_padding == other.tiling_interest_area_padding &&
- skewport_target_time_in_seconds ==
- other.skewport_target_time_in_seconds &&
- skewport_extrapolation_limit_in_screen_pixels ==
- other.skewport_extrapolation_limit_in_screen_pixels &&
- max_memory_for_prepaint_percentage ==
- other.max_memory_for_prepaint_percentage &&
- use_zero_copy == other.use_zero_copy &&
- use_partial_raster == other.use_partial_raster &&
- enable_elastic_overscroll == other.enable_elastic_overscroll &&
- ignore_root_layer_flings == other.ignore_root_layer_flings &&
- scheduled_raster_task_limit == other.scheduled_raster_task_limit &&
- use_occlusion_for_tile_prioritization ==
- other.use_occlusion_for_tile_prioritization &&
- verify_clip_tree_calculations == other.verify_clip_tree_calculations &&
- image_decode_tasks_enabled == other.image_decode_tasks_enabled &&
- max_staging_buffer_usage_in_bytes ==
- other.max_staging_buffer_usage_in_bytes &&
- gpu_memory_policy == other.gpu_memory_policy &&
- software_memory_policy == other.software_memory_policy &&
- enable_mask_tiling == other.enable_mask_tiling &&
- LayerTreeDebugState::Equal(initial_debug_state,
- other.initial_debug_state);
-}
-
SchedulerSettings LayerTreeSettings::ToSchedulerSettings() const {
SchedulerSettings scheduler_settings;
scheduler_settings.main_frame_before_activation_enabled =
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 92b759ba864..90348788b5e 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -10,7 +10,7 @@
#include <vector>
#include "base/time/time.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/debug/layer_tree_debug_state.h"
#include "cc/output/managed_memory_policy.h"
#include "cc/output/renderer_settings.h"
@@ -27,8 +27,6 @@ class CC_EXPORT LayerTreeSettings {
LayerTreeSettings(const LayerTreeSettings& other);
virtual ~LayerTreeSettings();
- bool operator==(const LayerTreeSettings& other) const;
-
SchedulerSettings ToSchedulerSettings() const;
TileManagerSettings ToTileManagerSettings() const;
@@ -51,10 +49,9 @@ class CC_EXPORT LayerTreeSettings {
AURA_OVERLAY,
};
ScrollbarAnimator scrollbar_animator = NO_ANIMATOR;
- base::TimeDelta scrollbar_show_delay;
- base::TimeDelta scrollbar_fade_out_delay;
+ base::TimeDelta scrollbar_fade_delay;
base::TimeDelta scrollbar_fade_out_resize_delay;
- base::TimeDelta scrollbar_fade_out_duration;
+ base::TimeDelta scrollbar_fade_duration;
base::TimeDelta scrollbar_thinning_duration;
SkColor solid_color_scrollbar_color = SK_ColorWHITE;
bool timeout_and_draw_when_animation_checkerboards = true;
@@ -82,7 +79,6 @@ class CC_EXPORT LayerTreeSettings {
bool ignore_root_layer_flings = false;
size_t scheduled_raster_task_limit = 32;
bool use_occlusion_for_tile_prioritization = false;
- bool verify_clip_tree_calculations = false;
// TODO(khushalsagar): Enable for all client and remove this flag if possible.
// See crbug/com/696864.
@@ -92,11 +88,11 @@ class CC_EXPORT LayerTreeSettings {
int max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024;
ManagedMemoryPolicy gpu_memory_policy;
ManagedMemoryPolicy software_memory_policy;
- size_t gpu_decoded_image_budget_bytes = 96 * 1024 * 1024;
- size_t software_decoded_image_budget_bytes = 128 * 1024 * 1024;
+ size_t decoded_image_cache_budget_bytes = 128 * 1024 * 1024;
+ size_t decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
int max_preraster_distance_in_screen_pixels = 1000;
- bool enable_color_correct_rendering = false;
+ bool enable_color_correct_rasterization = false;
// TODO(sunxd): remove this flag when filter demoting and aa of mask layers
// are implemented.
@@ -108,6 +104,14 @@ class CC_EXPORT LayerTreeSettings {
bool enable_checker_imaging = false;
LayerTreeDebugState initial_debug_state;
+
+ // Indicates that the LayerTreeHost should defer commits unless it has a valid
+ // LocalSurfaceId set.
+ bool enable_surface_synchronization = false;
+
+ // Indicates the case when a sub-frame gets its own LayerTree because it's
+ // rendered in a different process from its ancestor frames.
+ bool is_layer_tree_for_subframe = false;
};
} // namespace cc
diff --git a/chromium/cc/trees/occlusion.h b/chromium/cc/trees/occlusion.h
index 7e856aa66d2..ea38304907f 100644
--- a/chromium/cc/trees/occlusion.h
+++ b/chromium/cc/trees/occlusion.h
@@ -7,8 +7,8 @@
#include <string>
-#include "cc/base/cc_export.h"
#include "cc/base/simple_enclosed_region.h"
+#include "cc/cc_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/transform.h"
diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc
index 78f5cc66675..523b01f830f 100644
--- a/chromium/cc/trees/occlusion_tracker.cc
+++ b/chromium/cc/trees/occlusion_tracker.cc
@@ -56,23 +56,26 @@ OcclusionTracker::OcclusionSurfaceForContributingSurface() const {
return (stack_.size() < 2) ? nullptr : stack_[stack_.size() - 2].target;
}
-void OcclusionTracker::EnterLayer(const LayerIteratorPosition& layer_iterator) {
- LayerImpl* render_target = layer_iterator.target_render_surface_layer;
+void OcclusionTracker::EnterLayer(
+ const EffectTreeLayerListIterator::Position& iterator) {
+ RenderSurfaceImpl* render_target = iterator.target_render_surface;
- if (layer_iterator.represents_itself)
+ if (iterator.state == EffectTreeLayerListIterator::State::LAYER)
EnterRenderTarget(render_target);
- else if (layer_iterator.represents_target_render_surface)
+ else if (iterator.state == EffectTreeLayerListIterator::State::TARGET_SURFACE)
FinishedRenderTarget(render_target);
}
-void OcclusionTracker::LeaveLayer(const LayerIteratorPosition& layer_iterator) {
- LayerImpl* render_target = layer_iterator.target_render_surface_layer;
+void OcclusionTracker::LeaveLayer(
+ const EffectTreeLayerListIterator::Position& iterator) {
+ RenderSurfaceImpl* render_target = iterator.target_render_surface;
- if (layer_iterator.represents_itself)
- MarkOccludedBehindLayer(layer_iterator.current_layer);
+ if (iterator.state == EffectTreeLayerListIterator::State::LAYER)
+ MarkOccludedBehindLayer(iterator.current_layer);
// TODO(danakj): This should be done when entering the contributing surface,
// but in a way that the surface's own occlusion won't occlude itself.
- else if (layer_iterator.represents_contributing_render_surface)
+ else if (iterator.state ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE)
LeaveToRenderTarget(render_target);
}
@@ -117,9 +120,9 @@ static SimpleEnclosedRegion TransformSurfaceOpaqueRegion(
return transformed_region;
}
-void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) {
- DCHECK(new_target->GetRenderSurface());
- RenderSurfaceImpl* new_target_surface = new_target->GetRenderSurface();
+void OcclusionTracker::EnterRenderTarget(
+ const RenderSurfaceImpl* new_target_surface) {
+ DCHECK(new_target_surface);
if (!stack_.empty() && stack_.back().target == new_target_surface)
return;
@@ -153,7 +156,7 @@ void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) {
&inverse_new_target_screen_space_transform);
bool entering_root_target =
- new_target->layer_tree_impl()->IsRootLayer(new_target);
+ new_target_surface->render_target() == new_target_surface;
bool copy_outside_occlusion_forward =
stack_.size() > 1 &&
@@ -177,22 +180,26 @@ void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) {
gfx::Rect(), old_target_to_new_target_transform));
}
-void OcclusionTracker::FinishedRenderTarget(const LayerImpl* finished_target) {
+void OcclusionTracker::FinishedRenderTarget(
+ const RenderSurfaceImpl* finished_target_surface) {
// Make sure we know about the target surface.
- EnterRenderTarget(finished_target);
+ EnterRenderTarget(finished_target_surface);
- RenderSurfaceImpl* surface = finished_target->GetRenderSurface();
+ bool is_hidden =
+ finished_target_surface->OwningEffectNode()->screen_space_opacity == 0.f;
// Readbacks always happen on render targets so we only need to check
// for readbacks here.
bool target_is_only_for_copy_request =
- surface->HasCopyRequest() && finished_target->IsHidden();
+ finished_target_surface->HasCopyRequest() && is_hidden;
// If the occlusion within the surface can not be applied to things outside of
// the surface's subtree, then clear the occlusion here so it won't be used.
- if (surface->MaskLayer() || surface->draw_opacity() < 1 ||
- !surface->UsesDefaultBlendMode() || target_is_only_for_copy_request ||
- surface->Filters().HasFilterThatAffectsOpacity()) {
+ if (finished_target_surface->HasMask() ||
+ finished_target_surface->draw_opacity() < 1 ||
+ !finished_target_surface->UsesDefaultBlendMode() ||
+ target_is_only_for_copy_request ||
+ finished_target_surface->Filters().HasFilterThatAffectsOpacity()) {
stack_.back().occlusion_from_outside_target.Clear();
stack_.back().occlusion_from_inside_target.Clear();
}
@@ -252,13 +259,13 @@ static void ReduceOcclusionBelowSurface(
}
}
-void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) {
+void OcclusionTracker::LeaveToRenderTarget(
+ const RenderSurfaceImpl* new_target_surface) {
DCHECK(!stack_.empty());
size_t last_index = stack_.size() - 1;
- DCHECK(new_target->GetRenderSurface());
- RenderSurfaceImpl* new_surface = new_target->GetRenderSurface();
+ DCHECK(new_target_surface);
bool surface_will_be_at_top_after_pop =
- stack_.size() > 1 && stack_[last_index - 1].target == new_surface;
+ stack_.size() > 1 && stack_[last_index - 1].target == new_target_surface;
// We merge the screen occlusion from the current RenderSurfaceImpl subtree
// out to its parent target RenderSurfaceImpl. The target occlusion can be
@@ -285,23 +292,24 @@ void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) {
surface_occlusion.GetUnoccludedContentRect(old_surface->content_rect());
}
+ bool is_root = new_target_surface->render_target() == new_target_surface;
if (surface_will_be_at_top_after_pop) {
// Merge the top of the stack down.
stack_[last_index - 1].occlusion_from_inside_target.Union(
old_occlusion_from_inside_target_in_new_target);
// TODO(danakj): Strictly this should subtract the inside target occlusion
// before union.
- if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) {
+ if (!is_root) {
stack_[last_index - 1].occlusion_from_outside_target.Union(
old_occlusion_from_outside_target_in_new_target);
}
stack_.pop_back();
} else {
// Replace the top of the stack with the new pushed surface.
- stack_.back().target = new_surface;
+ stack_.back().target = new_target_surface;
stack_.back().occlusion_from_inside_target =
old_occlusion_from_inside_target_in_new_target;
- if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) {
+ if (!is_root) {
stack_.back().occlusion_from_outside_target =
old_occlusion_from_outside_target_in_new_target;
} else {
@@ -327,10 +335,6 @@ void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) {
if (layer->draw_opacity() < 1)
return;
- // The only currently supported draw_blend_mode is SrcOver mode, so
- // draw_blend_mode does not affect occlusion.
- DCHECK_EQ(layer->draw_blend_mode(), SkBlendMode::kSrcOver);
-
if (layer->Is3dSorted())
return;
diff --git a/chromium/cc/trees/occlusion_tracker.h b/chromium/cc/trees/occlusion_tracker.h
index 13ef757917f..0f360f39313 100644
--- a/chromium/cc/trees/occlusion_tracker.h
+++ b/chromium/cc/trees/occlusion_tracker.h
@@ -8,9 +8,9 @@
#include <vector>
#include "base/macros.h"
-#include "cc/base/cc_export.h"
#include "cc/base/simple_enclosed_region.h"
-#include "cc/layers/layer_iterator.h"
+#include "cc/cc_export.h"
+#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/trees/occlusion.h"
#include "ui/gfx/geometry/rect.h"
@@ -41,12 +41,12 @@ class CC_EXPORT OcclusionTracker {
const gfx::Transform& draw_transform) const;
const RenderSurfaceImpl* OcclusionSurfaceForContributingSurface() const;
- // Called at the beginning of each step in the LayerIterator's front-to-back
- // traversal.
- void EnterLayer(const LayerIteratorPosition& layer_iterator);
- // Called at the end of each step in the LayerIterator's front-to-back
- // traversal.
- void LeaveLayer(const LayerIteratorPosition& layer_iterator);
+ // Called at the beginning of each step in EffectTreeLayerListIterator's
+ // front-to-back traversal.
+ void EnterLayer(const EffectTreeLayerListIterator::Position& iterator);
+ // Called at the end of each step in EffectTreeLayerListIterator's
+ // front-to-back traversal.
+ void LeaveLayer(const EffectTreeLayerListIterator::Position& iterator);
// Gives the region of the screen that is not occluded by something opaque.
Region ComputeVisibleRegionInScreen(const LayerTreeImpl* layer_tree) const;
@@ -82,20 +82,20 @@ class CC_EXPORT OcclusionTracker {
std::vector<StackObject> stack_;
private:
- // Called when visiting a layer representing itself. If the target was not
- // already current, then this indicates we have entered a new surface subtree.
- void EnterRenderTarget(const LayerImpl* new_target);
-
- // Called when visiting a layer representing a target surface. This indicates
- // we have visited all the layers within the surface, and we may perform any
- // surface-wide operations.
- void FinishedRenderTarget(const LayerImpl* finished_target);
-
- // Called when visiting a layer representing a contributing surface. This
- // indicates that we are leaving our current surface, and entering the new
- // one. We then perform any operations required for merging results from the
- // child subtree into its parent.
- void LeaveToRenderTarget(const LayerImpl* new_target);
+ // Called when visiting a layer. If the target was not already current, then
+ // this indicates we have entered a new surface subtree.
+ void EnterRenderTarget(const RenderSurfaceImpl* new_target_surface);
+
+ // Called when visiting a target surface. This indicates we have visited all
+ // the layers within the surface, and we may perform any surface-wide
+ // operations.
+ void FinishedRenderTarget(const RenderSurfaceImpl* finished_target_surface);
+
+ // Called when visiting a contributing surface. This indicates that we are
+ // leaving our current surface, and entering the new one. We then perform any
+ // operations required for merging results from the child subtree into its
+ // parent.
+ void LeaveToRenderTarget(const RenderSurfaceImpl* new_target_surface);
// Add the layer's occlusion to the tracked state.
void MarkOccludedBehindLayer(const LayerImpl* layer);
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index 2e0d1b6d92a..8f635a30ccd 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -7,13 +7,13 @@
#include <stddef.h>
#include "cc/animation/animation_host.h"
+#include "cc/base/filter_operation.h"
+#include "cc/base/filter_operations.h"
#include "cc/base/math_util.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
-#include "cc/output/filter_operation.h"
-#include "cc/output/filter_operations.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
@@ -190,7 +190,7 @@ class OcclusionTrackerTest : public testing::Test {
host_->host_impl()->active_tree()->SetRootLayerForTesting(nullptr);
render_surface_layer_list_impl_.clear();
mask_layers_.clear();
- ResetLayerIterator();
+ layer_iterator_.reset();
}
void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {}
@@ -216,28 +216,28 @@ class OcclusionTrackerTest : public testing::Test {
// iterations, so rebuild property trees every time.
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
-
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_layer_list_impl_);
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
- layer_iterator_ = layer_iterator_begin_ =
- LayerIterator::Begin(&render_surface_layer_list_impl_);
+ layer_iterator_ = base::MakeUnique<EffectTreeLayerListIterator>(
+ host_->host_impl()->active_tree());
}
void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
- ASSERT_EQ(*layer_iterator_, layer);
- ASSERT_TRUE(layer_iterator_.represents_itself());
- occlusion->EnterLayer(layer_iterator_);
+ ASSERT_EQ(layer_iterator_->current_layer(), layer);
+ ASSERT_TRUE(layer_iterator_->state() ==
+ EffectTreeLayerListIterator::State::LAYER);
+ occlusion->EnterLayer(*layer_iterator_);
}
void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
- ASSERT_EQ(*layer_iterator_, layer);
- ASSERT_TRUE(layer_iterator_.represents_itself());
- occlusion->LeaveLayer(layer_iterator_);
- ++layer_iterator_;
+ ASSERT_EQ(layer_iterator_->current_layer(), layer);
+ ASSERT_TRUE(layer_iterator_->state() ==
+ EffectTreeLayerListIterator::State::LAYER);
+ occlusion->LeaveLayer(*layer_iterator_);
+ ++(*layer_iterator_);
}
void VisitLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
@@ -246,20 +246,25 @@ class OcclusionTrackerTest : public testing::Test {
}
void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
- ASSERT_EQ(*layer_iterator_, layer);
- ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
- occlusion->EnterLayer(layer_iterator_);
- occlusion->LeaveLayer(layer_iterator_);
- ++layer_iterator_;
- ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
- occlusion->EnterLayer(layer_iterator_);
+ ASSERT_EQ(layer_iterator_->target_render_surface(),
+ layer->GetRenderSurface());
+ ASSERT_TRUE(layer_iterator_->state() ==
+ EffectTreeLayerListIterator::State::TARGET_SURFACE);
+ occlusion->EnterLayer(*layer_iterator_);
+ occlusion->LeaveLayer(*layer_iterator_);
+ ++(*layer_iterator_);
+ ASSERT_TRUE(layer_iterator_->state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE);
+ occlusion->EnterLayer(*layer_iterator_);
}
void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
- ASSERT_EQ(*layer_iterator_, layer);
- ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
- occlusion->LeaveLayer(layer_iterator_);
- ++layer_iterator_;
+ ASSERT_EQ(layer_iterator_->current_render_surface(),
+ layer->GetRenderSurface());
+ ASSERT_TRUE(layer_iterator_->state() ==
+ EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE);
+ occlusion->LeaveLayer(*layer_iterator_);
+ ++(*layer_iterator_);
}
void VisitContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
@@ -267,7 +272,10 @@ class OcclusionTrackerTest : public testing::Test {
LeaveContributingSurface(layer, occlusion);
}
- void ResetLayerIterator() { layer_iterator_ = layer_iterator_begin_; }
+ void ResetLayerIterator() {
+ *layer_iterator_ =
+ EffectTreeLayerListIterator(host_->host_impl()->active_tree());
+ }
const gfx::Transform identity_matrix;
@@ -298,8 +306,7 @@ class OcclusionTrackerTest : public testing::Test {
std::unique_ptr<FakeLayerTreeHost> host_;
// These hold ownership of the layers for the duration of the test.
LayerImplList render_surface_layer_list_impl_;
- LayerIterator layer_iterator_begin_;
- LayerIterator layer_iterator_;
+ std::unique_ptr<EffectTreeLayerListIterator> layer_iterator_;
LayerList mask_layers_;
int next_layer_impl_id_;
};
diff --git a/chromium/cc/trees/property_animation_state.h b/chromium/cc/trees/property_animation_state.h
index a171a91c0ed..1b7c07a7ed7 100644
--- a/chromium/cc/trees/property_animation_state.h
+++ b/chromium/cc/trees/property_animation_state.h
@@ -5,7 +5,7 @@
#ifndef CC_TREES_PROPERTY_ANIMATION_STATE_H_
#define CC_TREES_PROPERTY_ANIMATION_STATE_H_
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/trees/target_property.h"
namespace cc {
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index af6e451a922..4d1ca75e387 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -48,7 +48,6 @@ TransformTree::TransformTree()
device_scale_factor_(1.f),
device_transform_scale_factor_(1.f) {
cached_data_.push_back(TransformCachedNodeData());
- cached_data_[kRootNodeId].target_id = kRootNodeId;
}
TransformTree::~TransformTree() = default;
@@ -71,6 +70,7 @@ void PropertyTree<T>::clear() {
nodes_.push_back(T());
back()->id = kRootNodeId;
back()->parent_id = kInvalidNodeId;
+ owning_layer_id_to_node_index_.clear();
#if DCHECK_IS_ON()
PropertyTree<T> tree;
@@ -80,7 +80,8 @@ void PropertyTree<T>::clear() {
template <typename T>
bool PropertyTree<T>::operator==(const PropertyTree<T>& other) const {
- return nodes_ == other.nodes() && needs_update_ == other.needs_update();
+ return nodes_ == other.nodes() && needs_update_ == other.needs_update() &&
+ owning_layer_id_to_node_index_ == other.owning_layer_id_to_node_index_;
}
template <typename T>
@@ -117,7 +118,6 @@ void TransformTree::clear() {
nodes_affected_by_outer_viewport_bounds_delta_.clear();
cached_data_.clear();
cached_data_.push_back(TransformCachedNodeData());
- cached_data_[kRootNodeId].target_id = kRootNodeId;
sticky_position_data_.clear();
#if DCHECK_IS_ON()
@@ -130,9 +130,9 @@ void TransformTree::clear() {
}
void TransformTree::set_needs_update(bool needs_update) {
- if (needs_update && !needs_update_)
+ if (needs_update && !PropertyTree<TransformNode>::needs_update())
property_trees()->UpdateTransformTreeUpdateNumber();
- needs_update_ = needs_update;
+ PropertyTree<TransformNode>::set_needs_update(needs_update);
}
bool TransformTree::ComputeTranslation(int source_id,
@@ -176,21 +176,26 @@ bool TransformTree::ComputeTranslation(int source_id,
return true;
}
-void TransformTree::OnTransformAnimated(const gfx::Transform& transform,
- int id,
- LayerTreeImpl* layer_tree_impl) {
- TransformNode* node = Node(id);
- layer_tree_impl->AddToTransformAnimationsMap(node->owning_layer_id,
- transform);
- if (node->local == transform) {
- return;
- }
+TransformNode* TransformTree::FindNodeFromElementId(ElementId id) {
+ auto iterator = property_trees()->element_id_to_transform_node_index.find(id);
+ if (iterator == property_trees()->element_id_to_transform_node_index.end())
+ return nullptr;
+
+ return Node(iterator->second);
+}
+
+bool TransformTree::OnTransformAnimated(ElementId element_id,
+ const gfx::Transform& transform) {
+ TransformNode* node = FindNodeFromElementId(element_id);
+ DCHECK(node);
+ if (node->local == transform)
+ return false;
node->local = transform;
node->needs_local_transform_update = true;
node->transform_changed = true;
property_trees()->changed = true;
set_needs_update(true);
- layer_tree_impl->set_needs_update_draw_properties();
+ return true;
}
bool TransformTree::NeedsSourceToParentUpdate(TransformNode* node) {
@@ -210,7 +215,6 @@ void TransformTree::UpdateTransforms(int id) {
TransformNode* node = Node(id);
TransformNode* parent_node = parent(node);
DCHECK(parent_node);
- TransformNode* target_node = Node(TargetId(id));
TransformNode* source_node = Node(node->source_node_id);
// TODO(flackr): Only dirty when scroll offset changes.
if (node->sticky_position_constraint_id >= 0 ||
@@ -219,7 +223,7 @@ void TransformTree::UpdateTransforms(int id) {
} else {
UndoSnapping(node);
}
- UpdateScreenSpaceTransform(node, parent_node, target_node);
+ UpdateScreenSpaceTransform(node, parent_node);
UpdateAnimationProperties(node, parent_node);
UpdateSnapping(node);
UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
@@ -346,8 +350,7 @@ bool TransformTree::CombineInversesBetween(int source_id,
gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
if (node->sticky_position_constraint_id == -1)
return gfx::Vector2dF();
- const StickyPositionNodeData* sticky_data =
- tree->StickyPositionData(node->id);
+ StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id);
const LayerStickyPositionConstraint& constraint = sticky_data->constraints;
ScrollNode* scroll_node =
tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor);
@@ -368,10 +371,36 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
scroll_position,
gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds(
scroll_node->id)));
- gfx::Vector2dF sticky_offset(
- constraint.scroll_container_relative_sticky_box_rect.OffsetFromOrigin());
gfx::Vector2dF layer_offset(sticky_data->main_thread_offset);
+ gfx::Vector2dF ancestor_sticky_box_offset;
+ if (sticky_data->nearest_node_shifting_sticky_box !=
+ TransformTree::kInvalidNodeId) {
+ ancestor_sticky_box_offset =
+ tree->StickyPositionData(sticky_data->nearest_node_shifting_sticky_box)
+ ->total_sticky_box_sticky_offset;
+ }
+
+ gfx::Vector2dF ancestor_containing_block_offset;
+ if (sticky_data->nearest_node_shifting_containing_block !=
+ TransformTree::kInvalidNodeId) {
+ ancestor_containing_block_offset =
+ tree->StickyPositionData(
+ sticky_data->nearest_node_shifting_containing_block)
+ ->total_containing_block_sticky_offset;
+ }
+
+ // Compute the current position of the constraint rects based on the original
+ // positions and the offsets from ancestor sticky elements.
+ gfx::RectF sticky_box_rect =
+ gfx::RectF(constraint.scroll_container_relative_sticky_box_rect) +
+ ancestor_sticky_box_offset + ancestor_containing_block_offset;
+ gfx::RectF containing_block_rect =
+ gfx::RectF(constraint.scroll_container_relative_containing_block_rect) +
+ ancestor_containing_block_offset;
+
+ gfx::Vector2dF sticky_offset(sticky_box_rect.OffsetFromOrigin());
+
// In each of the following cases, we measure the limit which is the point
// that the element should stick to, clamping on one side to 0 (because sticky
// only pushes elements in one direction). Then we clamp to how far we can
@@ -383,55 +412,52 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
// over bottom offset.
if (constraint.is_anchored_right) {
float right_limit = clip.right() - constraint.right_offset;
- float right_delta = std::min<float>(
- 0, right_limit -
- constraint.scroll_container_relative_sticky_box_rect.right());
- float available_space = std::min<float>(
- 0, constraint.scroll_container_relative_containing_block_rect.x() -
- constraint.scroll_container_relative_sticky_box_rect.x());
+ float right_delta =
+ std::min<float>(0, right_limit - sticky_box_rect.right());
+ float available_space =
+ std::min<float>(0, containing_block_rect.x() - sticky_box_rect.x());
if (right_delta < available_space)
right_delta = available_space;
sticky_offset.set_x(sticky_offset.x() + right_delta);
}
if (constraint.is_anchored_left) {
float left_limit = clip.x() + constraint.left_offset;
- float left_delta = std::max<float>(
- 0,
- left_limit - constraint.scroll_container_relative_sticky_box_rect.x());
+ float left_delta = std::max<float>(0, left_limit - sticky_box_rect.x());
float available_space = std::max<float>(
- 0, constraint.scroll_container_relative_containing_block_rect.right() -
- constraint.scroll_container_relative_sticky_box_rect.right());
+ 0, containing_block_rect.right() - sticky_box_rect.right());
if (left_delta > available_space)
left_delta = available_space;
sticky_offset.set_x(sticky_offset.x() + left_delta);
}
if (constraint.is_anchored_bottom) {
float bottom_limit = clip.bottom() - constraint.bottom_offset;
- float bottom_delta = std::min<float>(
- 0, bottom_limit -
- constraint.scroll_container_relative_sticky_box_rect.bottom());
- float available_space = std::min<float>(
- 0, constraint.scroll_container_relative_containing_block_rect.y() -
- constraint.scroll_container_relative_sticky_box_rect.y());
+ float bottom_delta =
+ std::min<float>(0, bottom_limit - sticky_box_rect.bottom());
+ float available_space =
+ std::min<float>(0, containing_block_rect.y() - sticky_box_rect.y());
if (bottom_delta < available_space)
bottom_delta = available_space;
sticky_offset.set_y(sticky_offset.y() + bottom_delta);
}
if (constraint.is_anchored_top) {
float top_limit = clip.y() + constraint.top_offset;
- float top_delta = std::max<float>(
- 0,
- top_limit - constraint.scroll_container_relative_sticky_box_rect.y());
+ float top_delta = std::max<float>(0, top_limit - sticky_box_rect.y());
float available_space = std::max<float>(
- 0, constraint.scroll_container_relative_containing_block_rect.bottom() -
- constraint.scroll_container_relative_sticky_box_rect.bottom());
+ 0, containing_block_rect.bottom() - sticky_box_rect.bottom());
if (top_delta > available_space)
top_delta = available_space;
sticky_offset.set_y(sticky_offset.y() + top_delta);
}
+
+ sticky_data->total_sticky_box_sticky_offset =
+ ancestor_sticky_box_offset + sticky_offset -
+ sticky_box_rect.OffsetFromOrigin();
+ sticky_data->total_containing_block_sticky_offset =
+ ancestor_sticky_box_offset + ancestor_containing_block_offset +
+ sticky_offset - sticky_box_rect.OffsetFromOrigin();
+
return sticky_offset - layer_offset - node->source_to_parent -
- constraint.scroll_container_relative_sticky_box_rect
- .OffsetFromOrigin();
+ sticky_box_rect.OffsetFromOrigin();
}
void TransformTree::UpdateLocalTransform(TransformNode* node) {
@@ -498,8 +524,7 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) {
}
void TransformTree::UpdateScreenSpaceTransform(TransformNode* node,
- TransformNode* parent_node,
- TransformNode* target_node) {
+ TransformNode* parent_node) {
DCHECK(parent_node);
gfx::Transform to_screen_space_transform = ToScreen(parent_node->id);
if (node->flattens_inherited_transform)
@@ -705,26 +730,6 @@ void TransformTree::SetToScreen(int node_id, const gfx::Transform& transform) {
cached_data_[node_id].is_showing_backface = transform.IsBackFaceVisible();
}
-int TransformTree::TargetId(int node_id) const {
- DCHECK(static_cast<int>(cached_data_.size()) > node_id);
- return cached_data_[node_id].target_id;
-}
-
-void TransformTree::SetTargetId(int node_id, int target_id) {
- DCHECK(static_cast<int>(cached_data_.size()) > node_id);
- cached_data_[node_id].target_id = target_id;
-}
-
-int TransformTree::ContentTargetId(int node_id) const {
- DCHECK(static_cast<int>(cached_data_.size()) > node_id);
- return cached_data_[node_id].content_target_id;
-}
-
-void TransformTree::SetContentTargetId(int node_id, int content_target_id) {
- DCHECK(static_cast<int>(cached_data_.size()) > node_id);
- cached_data_[node_id].content_target_id = content_target_id;
-}
-
bool TransformTree::operator==(const TransformTree& other) const {
return PropertyTree::operator==(other) &&
source_to_parent_updates_allowed_ ==
@@ -842,37 +847,59 @@ void EffectTree::UpdateSurfaceContentsScale(EffectNode* effect_node) {
transform_tree.Node(effect_node->transform_id);
if (transform_node->in_subtree_of_page_scale_layer)
layer_scale_factor *= transform_tree.page_scale_factor();
+
+ // Note: Copy requests currently expect transform to effect output size.
+ bool use_transform_for_contents_scale =
+ property_trees()->can_adjust_raster_scales ||
+ effect_node->has_copy_request;
effect_node->surface_contents_scale =
- MathUtil::ComputeTransform2dScaleComponents(
- transform_tree.ToScreen(transform_node->id), layer_scale_factor);
+ use_transform_for_contents_scale
+ ? MathUtil::ComputeTransform2dScaleComponents(
+ transform_tree.ToScreen(transform_node->id), layer_scale_factor)
+ : gfx::Vector2dF(layer_scale_factor, layer_scale_factor);
}
-void EffectTree::OnOpacityAnimated(float opacity,
- int id,
- LayerTreeImpl* layer_tree_impl) {
- EffectNode* node = Node(id);
- layer_tree_impl->AddToOpacityAnimationsMap(node->owning_layer_id, opacity);
+EffectNode* EffectTree::FindNodeFromElementId(ElementId id) {
+ auto iterator = property_trees()->element_id_to_effect_node_index.find(id);
+ if (iterator == property_trees()->element_id_to_effect_node_index.end())
+ return nullptr;
+
+ return Node(iterator->second);
+}
+
+bool EffectTree::OnOpacityAnimated(ElementId id, float opacity) {
+ EffectNode* node = FindNodeFromElementId(id);
+ DCHECK(node);
+ // TODO(crbug.com/706766): Avoid crash. Need more investigation for what is
+ // calling this without setting element id.
+ if (!node)
+ return false;
+
if (node->opacity == opacity)
- return;
+ return false;
node->opacity = opacity;
node->effect_changed = true;
property_trees()->changed = true;
property_trees()->effect_tree.set_needs_update(true);
- layer_tree_impl->set_needs_update_draw_properties();
+ return true;
}
-void EffectTree::OnFilterAnimated(const FilterOperations& filters,
- int id,
- LayerTreeImpl* layer_tree_impl) {
- EffectNode* node = Node(id);
- layer_tree_impl->AddToFilterAnimationsMap(node->owning_layer_id, filters);
+bool EffectTree::OnFilterAnimated(ElementId id,
+ const FilterOperations& filters) {
+ EffectNode* node = FindNodeFromElementId(id);
+ DCHECK(node);
+ // TODO(crbug.com/706766): Avoid crash. Need more investigation for what is
+ // calling this without setting element id.
+ if (!node)
+ return false;
+
if (node->filters == filters)
- return;
+ return false;
node->filters = filters;
node->effect_changed = true;
property_trees()->changed = true;
property_trees()->effect_tree.set_needs_update(true);
- layer_tree_impl->set_needs_update_draw_properties();
+ return true;
}
void EffectTree::UpdateEffects(int id) {
@@ -1580,6 +1607,7 @@ PropertyTreesCachedData::~PropertyTreesCachedData() {}
PropertyTrees::PropertyTrees()
: needs_rebuild(true),
non_root_surfaces_enabled(true),
+ can_adjust_raster_scales(true),
changed(false),
full_tree_damaged(false),
sequence_number(0),
@@ -1597,11 +1625,6 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const {
return transform_tree == other.transform_tree &&
effect_tree == other.effect_tree && clip_tree == other.clip_tree &&
scroll_tree == other.scroll_tree &&
- layer_id_to_transform_node_index ==
- other.layer_id_to_transform_node_index &&
- layer_id_to_effect_node_index == other.layer_id_to_effect_node_index &&
- layer_id_to_clip_node_index == other.layer_id_to_clip_node_index &&
- layer_id_to_scroll_node_index == other.layer_id_to_scroll_node_index &&
element_id_to_effect_node_index ==
other.element_id_to_effect_node_index &&
element_id_to_scroll_node_index ==
@@ -1615,6 +1638,7 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const {
is_main_thread == other.is_main_thread &&
is_active == other.is_active &&
non_root_surfaces_enabled == other.non_root_surfaces_enabled &&
+ can_adjust_raster_scales == other.can_adjust_raster_scales &&
sequence_number == other.sequence_number;
}
@@ -1623,12 +1647,8 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) {
effect_tree = from.effect_tree;
clip_tree = from.clip_tree;
scroll_tree = from.scroll_tree;
- layer_id_to_transform_node_index = from.layer_id_to_transform_node_index;
- layer_id_to_effect_node_index = from.layer_id_to_effect_node_index;
always_use_active_tree_opacity_effect_ids =
from.always_use_active_tree_opacity_effect_ids;
- layer_id_to_clip_node_index = from.layer_id_to_clip_node_index;
- layer_id_to_scroll_node_index = from.layer_id_to_scroll_node_index;
element_id_to_effect_node_index = from.element_id_to_effect_node_index;
element_id_to_scroll_node_index = from.element_id_to_scroll_node_index;
element_id_to_transform_node_index = from.element_id_to_transform_node_index;
@@ -1636,6 +1656,7 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) {
changed = from.changed;
full_tree_damaged = from.full_tree_damaged;
non_root_surfaces_enabled = from.non_root_surfaces_enabled;
+ can_adjust_raster_scales = from.can_adjust_raster_scales;
sequence_number = from.sequence_number;
is_main_thread = from.is_main_thread;
is_active = from.is_active;
@@ -1658,10 +1679,6 @@ void PropertyTrees::clear() {
clip_tree.clear();
effect_tree.clear();
scroll_tree.clear();
- layer_id_to_transform_node_index.clear();
- layer_id_to_effect_node_index.clear();
- layer_id_to_clip_node_index.clear();
- layer_id_to_scroll_node_index.clear();
element_id_to_effect_node_index.clear();
element_id_to_scroll_node_index.clear();
element_id_to_transform_node_index.clear();
@@ -1671,6 +1688,7 @@ void PropertyTrees::clear() {
full_tree_damaged = false;
changed = false;
non_root_surfaces_enabled = true;
+ can_adjust_raster_scales = true;
sequence_number++;
#if DCHECK_IS_ON()
@@ -1713,46 +1731,25 @@ void PropertyTrees::SetInnerViewportScrollBoundsDelta(
void PropertyTrees::PushOpacityIfNeeded(PropertyTrees* target_tree) {
for (int id : target_tree->always_use_active_tree_opacity_effect_ids) {
- if (layer_id_to_effect_node_index.find(id) ==
- layer_id_to_effect_node_index.end())
- continue;
- EffectNode* source_effect_node =
- effect_tree.Node(layer_id_to_effect_node_index[id]);
- EffectNode* target_effect_node = target_tree->effect_tree.Node(
- target_tree->layer_id_to_effect_node_index[id]);
- float source_opacity = source_effect_node->opacity;
- float target_opacity = target_effect_node->opacity;
- if (source_opacity == target_opacity)
- continue;
- target_effect_node->opacity = source_opacity;
- target_tree->effect_tree.set_needs_update(true);
+ if (const EffectNode* source_effect_node =
+ effect_tree.FindNodeFromOwningLayerId(id)) {
+ EffectNode* target_effect_node =
+ target_tree->effect_tree.UpdateNodeFromOwningLayerId(id);
+ float source_opacity = source_effect_node->opacity;
+ float target_opacity = target_effect_node->opacity;
+ if (source_opacity == target_opacity)
+ continue;
+ target_effect_node->opacity = source_opacity;
+ target_tree->effect_tree.set_needs_update(true);
+ }
}
}
void PropertyTrees::RemoveIdFromIdToIndexMaps(int id) {
- layer_id_to_transform_node_index.erase(id);
- layer_id_to_effect_node_index.erase(id);
- layer_id_to_clip_node_index.erase(id);
- layer_id_to_scroll_node_index.erase(id);
-}
-
-bool PropertyTrees::IsInIdToIndexMap(TreeType tree_type, int id) {
- std::unordered_map<int, int>* id_to_index_map = nullptr;
- switch (tree_type) {
- case TRANSFORM:
- id_to_index_map = &layer_id_to_transform_node_index;
- break;
- case EFFECT:
- id_to_index_map = &layer_id_to_effect_node_index;
- break;
- case CLIP:
- id_to_index_map = &layer_id_to_clip_node_index;
- break;
- case SCROLL:
- id_to_index_map = &layer_id_to_scroll_node_index;
- break;
- }
- return id_to_index_map->find(id) != id_to_index_map->end();
+ transform_tree.SetOwningLayerIdForNode(nullptr, id);
+ clip_tree.SetOwningLayerIdForNode(nullptr, id);
+ scroll_tree.SetOwningLayerIdForNode(nullptr, id);
+ effect_tree.SetOwningLayerIdForNode(nullptr, id);
}
void PropertyTrees::UpdateChangeTracking() {
@@ -1983,6 +1980,10 @@ void PropertyTrees::SetAnimationScalesForTesting(
bool PropertyTrees::GetToTarget(int transform_id,
int effect_id,
gfx::Transform* to_target) const {
+ if (effect_id == EffectTree::kContentsRootNodeId) {
+ *to_target = transform_tree.ToScreen(transform_id);
+ return true;
+ }
DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id);
if (transforms.to_valid) {
*to_target = transforms.to_target;
@@ -2001,6 +2002,12 @@ bool PropertyTrees::GetToTarget(int transform_id,
bool PropertyTrees::GetFromTarget(int transform_id,
int effect_id,
gfx::Transform* from_target) const {
+ const TransformNode* node = transform_tree.Node(transform_id);
+ if (node->ancestors_are_invertible &&
+ effect_id == EffectTree::kContentsRootNodeId) {
+ *from_target = transform_tree.FromScreen(transform_id);
+ return true;
+ }
DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id);
if (transforms.from_valid) {
*from_target = transforms.from_target;
@@ -2036,6 +2043,17 @@ DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache(
return data;
}
+ClipRectData* PropertyTrees::FetchClipRectFromCache(int clip_id,
+ int target_id) {
+ ClipNode* clip_node = clip_tree.Node(clip_id);
+ for (auto& data : clip_node->cached_clip_rects) {
+ if (data.target_id == target_id || data.target_id == -1)
+ return &data;
+ }
+ clip_node->cached_clip_rects.push_back(ClipRectData());
+ return &clip_node->cached_clip_rects.back();
+}
+
DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id,
int effect_id) const {
const EffectNode* effect_node = effect_tree.Node(effect_id);
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 8c9d158a7bc..de5cc2823de 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -11,10 +11,11 @@
#include <unordered_map>
#include <vector>
-#include "cc/base/cc_export.h"
+#include "base/containers/flat_map.h"
+#include "cc/base/filter_operations.h"
#include "cc/base/synced_property.h"
+#include "cc/cc_export.h"
#include "cc/layers/layer_sticky_position_constraint.h"
-#include "cc/output/filter_operations.h"
#include "cc/trees/element_id.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
@@ -53,7 +54,7 @@ class CC_EXPORT PropertyTree {
// they are exported by CC_EXPORT. They will be instantiated in every
// compilation units that included this header, and compilation can fail
// because T may be incomplete.
- ~PropertyTree();
+ virtual ~PropertyTree();
PropertyTree<T>& operator=(const PropertyTree<T>&);
// Property tree node starts from index 0.
@@ -82,7 +83,9 @@ class CC_EXPORT PropertyTree {
void clear();
size_t size() const { return nodes_.size(); }
- void set_needs_update(bool needs_update) { needs_update_ = needs_update; }
+ virtual void set_needs_update(bool needs_update) {
+ needs_update_ = needs_update;
+ }
bool needs_update() const { return needs_update_; }
std::vector<T>& nodes() { return nodes_; }
@@ -97,25 +100,50 @@ class CC_EXPORT PropertyTree {
void AsValueInto(base::trace_event::TracedValue* value) const;
+ const T* FindNodeFromOwningLayerId(int id) const {
+ return Node(FindNodeIndexFromOwningLayerId(id));
+ }
+ T* UpdateNodeFromOwningLayerId(int id) {
+ int index = FindNodeIndexFromOwningLayerId(id);
+ if (index == kInvalidNodeId) {
+ DCHECK(property_trees()->is_main_thread);
+ property_trees()->needs_rebuild = true;
+ }
+
+ return Node(index);
+ }
+
+ int FindNodeIndexFromOwningLayerId(int id) const {
+ auto iter = owning_layer_id_to_node_index_.find(id);
+ if (iter == owning_layer_id_to_node_index_.end())
+ return kInvalidNodeId;
+ else
+ return iter->second;
+ }
+
+ void SetOwningLayerIdForNode(const T* node, int id) {
+ if (!node) {
+ owning_layer_id_to_node_index_[id] = kInvalidNodeId;
+ return;
+ }
+
+ DCHECK(node == Node(node->id));
+ owning_layer_id_to_node_index_[id] = node->id;
+ }
+
private:
std::vector<T> nodes_;
- friend class TransformTree;
+ // Maps from layer id to the property tree node index. This container is
+ // typically very small and the memory overhead of unordered_map will
+ // dominate so use a flat_map. See http://crbug.com/709243
+ base::flat_map<int, int> owning_layer_id_to_node_index_;
+
bool needs_update_;
PropertyTrees* property_trees_;
};
-struct StickyPositionNodeData {
- int scroll_ancestor;
- LayerStickyPositionConstraint constraints;
-
- // This is the offset that blink has already applied to counteract the main
- // thread scroll offset of the scroll ancestor. We need to account for this
- // by computing the additional offset necessary to keep the element stuck.
- gfx::Vector2dF main_thread_offset;
-
- StickyPositionNodeData() : scroll_ancestor(-1) {}
-};
+struct StickyPositionNodeData;
class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
public:
@@ -126,7 +154,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
// compilation units that included this header, and compilation can fail
// because TransformCachedNodeData may be incomplete.
TransformTree(const TransformTree&) = delete;
- ~TransformTree();
+ ~TransformTree() final;
TransformTree& operator=(const TransformTree&);
bool operator==(const TransformTree& other) const;
@@ -137,9 +165,9 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
void clear();
- void OnTransformAnimated(const gfx::Transform& transform,
- int id,
- LayerTreeImpl* layer_tree_impl);
+ TransformNode* FindNodeFromElementId(ElementId id);
+ bool OnTransformAnimated(ElementId element_id,
+ const gfx::Transform& transform);
// Computes the change of basis transform from node |source_id| to |dest_id|.
// This is used by scroll children to compute transform from their scroll
// parent space (source) to their parent space (destination) and it can atmost
@@ -160,7 +188,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
TransformNode* node,
TransformNode* parent_node);
- void set_needs_update(bool needs_update);
+ void set_needs_update(bool needs_update) final;
// A TransformNode's source_to_parent value is used to account for the fact
// that fixed-position layers are positioned by Blink wrt to their layer tree
@@ -254,8 +282,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
void UpdateLocalTransform(TransformNode* node);
void UpdateScreenSpaceTransform(TransformNode* node,
- TransformNode* parent_node,
- TransformNode* target_node);
+ TransformNode* parent_node);
void UpdateAnimationProperties(TransformNode* node,
TransformNode* parent_node);
void UndoSnapping(TransformNode* node);
@@ -278,6 +305,35 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
std::vector<StickyPositionNodeData> sticky_position_data_;
};
+struct StickyPositionNodeData {
+ int scroll_ancestor;
+ LayerStickyPositionConstraint constraints;
+
+ // This is the offset that blink has already applied to counteract the main
+ // thread scroll offset of the scroll ancestor. We need to account for this
+ // by computing the additional offset necessary to keep the element stuck.
+ gfx::Vector2dF main_thread_offset;
+
+ // In order to properly compute the sticky offset, we need to know if we have
+ // any sticky ancestors both between ourselves and our containing block and
+ // between our containing block and the viewport. These ancestors are then
+ // used to correct the constraining rect locations.
+ int nearest_node_shifting_sticky_box;
+ int nearest_node_shifting_containing_block;
+
+ // For performance we cache our accumulated sticky offset to allow descendant
+ // sticky elements to offset their constraint rects. Because we can either
+ // affect the sticky box constraint rect or the containing block constraint
+ // rect, we need to accumulate both.
+ gfx::Vector2dF total_sticky_box_sticky_offset;
+ gfx::Vector2dF total_containing_block_sticky_offset;
+
+ StickyPositionNodeData()
+ : scroll_ancestor(TransformTree::kInvalidNodeId),
+ nearest_node_shifting_sticky_box(TransformTree::kInvalidNodeId),
+ nearest_node_shifting_containing_block(TransformTree::kInvalidNodeId) {}
+};
+
class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> {
public:
bool operator==(const ClipTree& other) const;
@@ -291,7 +347,7 @@ class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> {
class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
public:
EffectTree();
- ~EffectTree();
+ ~EffectTree() final;
EffectTree& operator=(const EffectTree& from);
bool operator==(const EffectTree& other) const;
@@ -306,10 +362,9 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
void UpdateSurfaceContentsScale(EffectNode* node);
- void OnOpacityAnimated(float opacity, int id, LayerTreeImpl* layer_tree_impl);
- void OnFilterAnimated(const FilterOperations& filters,
- int id,
- LayerTreeImpl* layer_tree_impl);
+ EffectNode* FindNodeFromElementId(ElementId id);
+ bool OnOpacityAnimated(ElementId id, float opacity);
+ bool OnFilterAnimated(ElementId id, const FilterOperations& filters);
void UpdateEffects(int id);
@@ -371,7 +426,7 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
public:
ScrollTree();
- ~ScrollTree();
+ ~ScrollTree() final;
ScrollTree& operator=(const ScrollTree& from);
bool operator==(const ScrollTree& other) const;
@@ -548,6 +603,18 @@ struct DrawTransformData {
transforms(gfx::Transform(), gfx::Transform()) {}
};
+struct ConditionalClip {
+ bool is_clipped;
+ gfx::RectF clip_rect;
+};
+
+struct ClipRectData {
+ int target_id;
+ ConditionalClip clip;
+
+ ClipRectData() : target_id(-1) {}
+};
+
struct PropertyTreesCachedData {
int transform_tree_update_number;
std::vector<AnimationScaleData> animation_scales;
@@ -566,14 +633,6 @@ class CC_EXPORT PropertyTrees final {
bool operator==(const PropertyTrees& other) const;
PropertyTrees& operator=(const PropertyTrees& from);
- // These maps map from layer id to the index for each of the respective
- // property node types.
- std::unordered_map<int, int> layer_id_to_transform_node_index;
- std::unordered_map<int, int> layer_id_to_effect_node_index;
- std::unordered_map<int, int> layer_id_to_clip_node_index;
- std::unordered_map<int, int> layer_id_to_scroll_node_index;
- enum TreeType { TRANSFORM, EFFECT, CLIP, SCROLL };
-
// These maps allow mapping directly from a compositor element id to the
// respective property node. This will eventually allow simplifying logic in
// various places that today has to map from element id to layer id, and then
@@ -594,6 +653,7 @@ class CC_EXPORT PropertyTrees final {
ScrollTree scroll_tree;
bool needs_rebuild;
bool non_root_surfaces_enabled;
+ bool can_adjust_raster_scales;
// Change tracking done on property trees needs to be preserved across commits
// (when they are not rebuild). We cache a global bool which stores whether
// we did any change tracking so that we can skip copying the change status
@@ -616,7 +676,6 @@ class CC_EXPORT PropertyTrees final {
void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta);
void PushOpacityIfNeeded(PropertyTrees* target_tree);
void RemoveIdFromIdToIndexMaps(int id);
- bool IsInIdToIndexMap(TreeType tree_type, int id);
void UpdateChangeTracking();
void PushChangeTrackingTo(PropertyTrees* tree);
void ResetAllChangeTracking();
@@ -654,6 +713,8 @@ class CC_EXPORT PropertyTrees final {
int transform_id,
int effect_id) const;
+ ClipRectData* FetchClipRectFromCache(int clip_id, int target_id);
+
private:
gfx::Vector2dF inner_viewport_container_bounds_delta_;
gfx::Vector2dF outer_viewport_container_bounds_delta_;
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index ef843d5d989..02fb9bd306c 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -50,7 +50,6 @@ struct DataForRecursion {
bool affected_by_outer_viewport_bounds_delta;
bool should_flatten;
bool is_hidden;
- bool apply_ancestor_clip;
uint32_t main_thread_scrolling_reasons;
bool scroll_tree_parent_created_by_uninheritable_criteria;
const gfx::Transform* device_transform;
@@ -87,93 +86,6 @@ static LayerStickyPositionConstraint StickyPositionConstraint(
return layer->test_properties()->sticky_position_constraint;
}
-struct PreCalculateMetaInformationRecursiveData {
- size_t num_unclipped_descendants;
- int num_descendants_that_draw_content;
-
- PreCalculateMetaInformationRecursiveData()
- : num_unclipped_descendants(0),
- num_descendants_that_draw_content(0) {}
-
- void Merge(const PreCalculateMetaInformationRecursiveData& data) {
- num_unclipped_descendants += data.num_unclipped_descendants;
- num_descendants_that_draw_content += data.num_descendants_that_draw_content;
- }
-};
-
-static inline bool IsRootLayer(const Layer* layer) {
- return !layer->parent();
-}
-
-static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
- return layer->layer_tree_host()->needs_meta_info_recomputation();
-}
-
-// Recursively walks the layer tree(if needed) to compute any information
-// that is needed before doing the main recursion.
-static void PreCalculateMetaInformationInternal(
- Layer* layer,
- PreCalculateMetaInformationRecursiveData* recursive_data) {
- if (!IsMetaInformationRecomputationNeeded(layer)) {
- DCHECK(IsRootLayer(layer));
- return;
- }
-
- if (layer->clip_parent())
- recursive_data->num_unclipped_descendants++;
-
- for (size_t i = 0; i < layer->children().size(); ++i) {
- Layer* child_layer = layer->child_at(i);
-
- PreCalculateMetaInformationRecursiveData data_for_child;
- PreCalculateMetaInformationInternal(child_layer, &data_for_child);
- recursive_data->Merge(data_for_child);
- }
-
- if (layer->clip_children()) {
- size_t num_clip_children = layer->clip_children()->size();
- DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
- recursive_data->num_unclipped_descendants -= num_clip_children;
- }
-
- layer->set_num_unclipped_descendants(
- recursive_data->num_unclipped_descendants);
-
- if (IsRootLayer(layer))
- layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false);
-}
-
-static void PreCalculateMetaInformationInternalForTesting(
- LayerImpl* layer,
- PreCalculateMetaInformationRecursiveData* recursive_data) {
- if (layer->test_properties()->clip_parent)
- recursive_data->num_unclipped_descendants++;
-
- for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) {
- LayerImpl* child_layer = layer->test_properties()->children[i];
-
- PreCalculateMetaInformationRecursiveData data_for_child;
- PreCalculateMetaInformationInternalForTesting(child_layer, &data_for_child);
- recursive_data->Merge(data_for_child);
- }
-
- if (layer->test_properties()->clip_children) {
- size_t num_clip_children = layer->test_properties()->clip_children->size();
- DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
- recursive_data->num_unclipped_descendants -= num_clip_children;
- }
-
- layer->test_properties()->num_unclipped_descendants =
- recursive_data->num_unclipped_descendants;
- // TODO(enne): this should be synced from the main thread, so is only
- // for tests constructing layers on the compositor thread.
- layer->test_properties()->num_descendants_that_draw_content =
- recursive_data->num_descendants_that_draw_content;
-
- if (layer->DrawsContent())
- recursive_data->num_descendants_that_draw_content++;
-}
-
static LayerImplList& Children(LayerImpl* layer) {
return layer->test_properties()->children;
}
@@ -214,14 +126,6 @@ static LayerImpl* ClipParent(LayerImpl* layer) {
return layer->test_properties()->clip_parent;
}
-static size_t NumUnclippedDescendants(Layer* layer) {
- return layer->num_unclipped_descendants();
-}
-
-static size_t NumUnclippedDescendants(LayerImpl* layer) {
- return layer->test_properties()->num_unclipped_descendants;
-}
-
static inline const FilterOperations& Filters(Layer* layer) {
return layer->filters();
}
@@ -246,6 +150,12 @@ static const gfx::Transform& Transform(LayerImpl* layer) {
return layer->test_properties()->transform;
}
+static void SetIsScrollClipLayer(Layer* layer) {
+ layer->set_is_scroll_clip_layer();
+}
+
+static void SetIsScrollClipLayer(LayerImpl* layer) {}
+
// Methods to query state from the AnimationHost ----------------------
template <typename LayerType>
bool OpacityIsAnimating(LayerType* layer) {
@@ -334,86 +244,36 @@ static LayerImpl* Parent(LayerImpl* layer) {
return layer->test_properties()->parent;
}
-template <typename LayerType>
-static void SetSurfaceIsClipped(DataForRecursion<LayerType>* data_for_children,
- bool apply_ancestor_clip,
- LayerType* layer) {
- // A surface with unclipped descendants cannot be clipped by its ancestor
- // clip at draw time since the unclipped descendants aren't affected by the
- // ancestor clip.
- EffectNode* effect_node = data_for_children->property_trees->effect_tree.Node(
- data_for_children->render_target);
- DCHECK_EQ(effect_node->owning_layer_id, layer->id());
- effect_node->surface_is_clipped =
- apply_ancestor_clip && !NumUnclippedDescendants(layer);
- // The ancestor clip should propagate to children only if the surface doesn't
- // apply the clip.
- data_for_children->apply_ancestor_clip =
- apply_ancestor_clip && !effect_node->surface_is_clipped;
+static inline int SortingContextId(Layer* layer) {
+ return layer->sorting_context_id();
+}
+
+static inline int SortingContextId(LayerImpl* layer) {
+ return layer->test_properties()->sorting_context_id;
+}
+
+static inline bool Is3dSorted(Layer* layer) {
+ return layer->Is3dSorted();
+}
+
+static inline bool Is3dSorted(LayerImpl* layer) {
+ return layer->test_properties()->sorting_context_id != 0;
}
template <typename LayerType>
void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor,
LayerType* layer,
- bool created_render_surface,
bool created_transform_node,
DataForRecursion<LayerType>* data_for_children) {
const bool inherits_clip = !ClipParent(layer);
const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent
: ClipParent(layer)->clip_tree_index();
- ClipNode* parent =
- data_from_ancestor.property_trees->clip_tree.Node(parent_id);
-
- bool apply_ancestor_clip = inherits_clip
- ? data_from_ancestor.apply_ancestor_clip
- : parent->layers_are_clipped;
-
- bool layers_are_clipped = false;
- bool has_unclipped_surface = false;
-
- if (created_render_surface) {
- SetSurfaceIsClipped(data_for_children, apply_ancestor_clip, layer);
- // Clips can usually be applied to a surface's descendants simply by
- // clipping the surface (or applied implicitly by the surface's bounds).
- // However, if the surface has unclipped descendants (layers that aren't
- // affected by the ancestor clip), we cannot clip the surface itself, and
- // must instead apply clips to the clipped descendants.
- if (apply_ancestor_clip && NumUnclippedDescendants(layer) > 0) {
- layers_are_clipped = true;
- } else if (!apply_ancestor_clip) {
- // When there are no ancestor clips that need to be applied to a render
- // surface, we reset clipping state. The surface might contribute a clip
- // of its own, but clips from ancestor nodes don't need to be considered
- // when computing clip rects or visibility.
- has_unclipped_surface = true;
- DCHECK_NE(parent->clip_type, ClipNode::ClipType::APPLIES_LOCAL_CLIP);
- }
- } else {
- // Without a new render surface, layer clipping state from ancestors needs
- // to continue to propagate.
- layers_are_clipped = apply_ancestor_clip;
- }
bool layer_clips_subtree = LayerClipsSubtree(layer);
- if (layer_clips_subtree) {
- layers_are_clipped = true;
- data_for_children->apply_ancestor_clip = true;
- }
-
- // Without surfaces, all non-viewport clips have to be applied using layer
- // clipping.
- bool layers_are_clipped_when_surfaces_disabled =
- layer_clips_subtree || parent->layers_are_clipped_when_surfaces_disabled;
-
- // Render surface's clip is needed during hit testing. So, we need to create
- // a clip node for every render surface.
- bool requires_node = layer_clips_subtree || created_render_surface;
-
+ bool requires_node =
+ layer_clips_subtree || Filters(layer).HasFilterThatMovesPixels();
if (!requires_node) {
data_for_children->clip_tree_parent = parent_id;
- DCHECK_EQ(layers_are_clipped, parent->layers_are_clipped);
- DCHECK_EQ(layers_are_clipped_when_surfaces_disabled,
- parent->layers_are_clipped_when_surfaces_disabled);
} else {
LayerType* transform_parent = data_for_children->transform_tree_parent;
if (PositionConstraint(layer).is_fixed_position() &&
@@ -424,64 +284,24 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor,
node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(),
gfx::SizeF(layer->bounds()));
node.transform_id = transform_parent->transform_tree_index();
- node.target_effect_id = data_for_children->render_target;
- node.target_transform_id = data_for_children->property_trees->effect_tree
- .Node(data_for_children->render_target)
- ->transform_id;
node.owning_layer_id = layer->id();
-
- if (apply_ancestor_clip || layer_clips_subtree) {
- // Surfaces reset the rect used for layer clipping. At other nodes, layer
- // clipping state from ancestors must continue to get propagated.
- node.layer_clipping_uses_only_local_clip =
- (created_render_surface && NumUnclippedDescendants(layer) == 0) ||
- !apply_ancestor_clip;
- } else {
- // Otherwise, we're either unclipped, or exist only in order to apply our
- // parent's clips in our space.
- node.layer_clipping_uses_only_local_clip = false;
- }
-
if (layer_clips_subtree) {
node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
- } else if (Filters(layer).HasFilterThatMovesPixels()) {
+ } else {
+ DCHECK(Filters(layer).HasFilterThatMovesPixels());
node.clip_type = ClipNode::ClipType::EXPANDS_CLIP;
node.clip_expander =
base::MakeUnique<ClipExpander>(layer->effect_tree_index());
- } else {
- node.clip_type = ClipNode::ClipType::NONE;
}
- node.resets_clip = has_unclipped_surface;
- node.layers_are_clipped = layers_are_clipped;
- node.layers_are_clipped_when_surfaces_disabled =
- layers_are_clipped_when_surfaces_disabled;
-
data_for_children->clip_tree_parent =
data_for_children->property_trees->clip_tree.Insert(node, parent_id);
- data_for_children->property_trees
- ->layer_id_to_clip_node_index[layer->id()] =
- data_for_children->clip_tree_parent;
+ data_for_children->property_trees->clip_tree.SetOwningLayerIdForNode(
+ data_for_children->property_trees->clip_tree.back(), layer->id());
}
layer->SetClipTreeIndex(data_for_children->clip_tree_parent);
}
-static inline int SortingContextId(Layer* layer) {
- return layer->sorting_context_id();
-}
-
-static inline int SortingContextId(LayerImpl* layer) {
- return layer->test_properties()->sorting_context_id;
-}
-
-static inline bool Is3dSorted(Layer* layer) {
- return layer->Is3dSorted();
-}
-
-static inline bool Is3dSorted(LayerImpl* layer) {
- return layer->test_properties()->sorting_context_id != 0;
-}
-
template <typename LayerType>
static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) {
return Parent(layer)
@@ -565,29 +385,21 @@ bool AddTransformNodeIfNeeded(
scroll_child_has_different_target || is_sticky ||
is_at_boundary_of_3d_rendering_context;
- LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
- DCHECK(is_root || transform_parent);
-
int parent_index = TransformTree::kRootNodeId;
- if (transform_parent)
- parent_index = transform_parent->transform_tree_index();
+ int source_index = TransformTree::kRootNodeId;
+ gfx::Vector2dF source_offset;
- int source_index = parent_index;
+ LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
+ DCHECK_EQ(is_root, !transform_parent);
- gfx::Vector2dF source_offset;
if (transform_parent) {
- if (ScrollParent(layer)) {
- LayerType* source = Parent(layer);
- source_offset += source->offset_to_transform_parent();
- source_index = source->transform_tree_index();
- } else if (!is_fixed) {
- source_offset = transform_parent->offset_to_transform_parent();
- } else {
- source_offset = data_from_ancestor.transform_tree_parent
- ->offset_to_transform_parent();
- source_index =
- data_from_ancestor.transform_tree_parent->transform_tree_index();
- }
+ parent_index = transform_parent->transform_tree_index();
+ // Because Blink still provides positions with respect to the parent layer,
+ // we track both a parent TransformNode (which is the parent in the
+ // TransformTree) and a 'source' TransformNode (which is the TransformNode
+ // for the parent in the Layer tree).
+ source_index = Parent(layer)->transform_tree_index();
+ source_offset = Parent(layer)->offset_to_transform_parent();
}
if (IsContainerForFixedPositionLayers(layer) || is_root) {
@@ -630,8 +442,8 @@ bool AddTransformNodeIfNeeded(
TransformNode* node =
data_for_children->property_trees->transform_tree.back();
layer->SetTransformTreeIndex(node->id);
- data_for_children->property_trees
- ->layer_id_to_transform_node_index[layer->id()] = node->id;
+ data_for_children->property_trees->transform_tree.SetOwningLayerIdForNode(
+ node, layer->id());
// For animation subsystem purposes, if this layer has a compositor element
// id, we build a map from that id to this transform node.
@@ -656,18 +468,6 @@ bool AddTransformNodeIfNeeded(
ShouldFlattenTransform(layer) || has_surface;
DCHECK_GT(data_from_ancestor.property_trees->effect_tree.size(), 0u);
- data_for_children->property_trees->transform_tree.SetTargetId(
- node->id, data_for_children->property_trees->effect_tree
- .Node(data_from_ancestor.render_target)
- ->transform_id);
- data_for_children->property_trees->transform_tree.SetContentTargetId(
- node->id, data_for_children->property_trees->effect_tree
- .Node(data_for_children->render_target)
- ->transform_id);
- DCHECK_NE(
- data_for_children->property_trees->transform_tree.TargetId(node->id),
- TransformTree::kInvalidNodeId);
-
node->has_potential_animation = has_potentially_animated_transform;
node->is_currently_animating = TransformIsAnimating(layer);
if (has_potentially_animated_transform) {
@@ -759,10 +559,36 @@ bool AddTransformNodeIfNeeded(
.AddNodeAffectedByOuterViewportBoundsDelta(node->id);
}
}
+ // TODO(smcgruer): Pass main thread sticky-shifting offsets of
+ // non-promoted ancestors, or promote all ancestor sticky elements.
+ // See http://crbug.com/702229
sticky_data->main_thread_offset =
layer->position().OffsetFromOrigin() -
sticky_data->constraints.parent_relative_sticky_box_offset
.OffsetFromOrigin();
+
+ // Copy the ancestor nodes for later use. These layers are guaranteed to
+ // have transform nodes at this point because they are our ancestors (so
+ // have already been processed) and are sticky (so have transform nodes).
+ int shifting_sticky_box_layer_id =
+ sticky_data->constraints.nearest_layer_shifting_sticky_box;
+ if (shifting_sticky_box_layer_id != Layer::INVALID_ID) {
+ sticky_data->nearest_node_shifting_sticky_box =
+ data_for_children->property_trees->transform_tree
+ .FindNodeIndexFromOwningLayerId(shifting_sticky_box_layer_id);
+ DCHECK(sticky_data->nearest_node_shifting_sticky_box !=
+ TransformTree::kInvalidNodeId);
+ }
+ int shifting_containing_block_layer_id =
+ sticky_data->constraints.nearest_layer_shifting_containing_block;
+ if (shifting_containing_block_layer_id != Layer::INVALID_ID) {
+ sticky_data->nearest_node_shifting_containing_block =
+ data_for_children->property_trees->transform_tree
+ .FindNodeIndexFromOwningLayerId(
+ shifting_containing_block_layer_id);
+ DCHECK(sticky_data->nearest_node_shifting_containing_block !=
+ TransformTree::kInvalidNodeId);
+ }
}
node->needs_local_transform_update = true;
@@ -822,8 +648,24 @@ static inline int NumDescendantsThatDrawContent(Layer* layer) {
return layer->NumDescendantsThatDrawContent();
}
+static inline int NumLayerOrDescendantsThatDrawContentRecursive(
+ LayerImpl* layer) {
+ int num = layer->DrawsContent() ? 1 : 0;
+ for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) {
+ LayerImpl* child_layer = layer->test_properties()->children[i];
+ num += NumLayerOrDescendantsThatDrawContentRecursive(child_layer);
+ }
+ return num;
+}
+
static inline int NumDescendantsThatDrawContent(LayerImpl* layer) {
- return layer->test_properties()->num_descendants_that_draw_content;
+ int num_descendants_that_draw_content = 0;
+ for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) {
+ LayerImpl* child_layer = layer->test_properties()->children[i];
+ num_descendants_that_draw_content +=
+ NumLayerOrDescendantsThatDrawContentRecursive(child_layer);
+ }
+ return num_descendants_that_draw_content;
}
static inline float EffectiveOpacity(Layer* layer) {
@@ -1088,7 +930,6 @@ bool AddEffectNodeIfNeeded(
// transform id.
node.transform_id =
data_from_ancestor.property_trees->transform_tree.next_available_id();
- node.has_unclipped_descendants = (NumUnclippedDescendants(layer) != 0);
}
node.clip_id = data_from_ancestor.clip_tree_parent;
} else {
@@ -1102,8 +943,8 @@ bool AddEffectNodeIfNeeded(
int node_id = effect_tree.Insert(node, parent_id);
data_for_children->effect_tree_parent = node_id;
layer->SetEffectTreeIndex(node_id);
- data_for_children->property_trees
- ->layer_id_to_effect_node_index[layer->id()] = node_id;
+ data_for_children->property_trees->effect_tree.SetOwningLayerIdForNode(
+ effect_tree.back(), layer->id());
// For animation subsystem purposes, if this layer has a compositor element
// id, we build a map from that id to this effect node.
@@ -1165,13 +1006,14 @@ void AddScrollNodeIfNeeded(
node.main_thread_scrolling_reasons = main_thread_scrolling_reasons;
node.non_fast_scrollable_region = layer->non_fast_scrollable_region();
gfx::Size clip_bounds;
- if (layer->scroll_clip_layer()) {
- clip_bounds = layer->scroll_clip_layer()->bounds();
- DCHECK(layer->scroll_clip_layer()->transform_tree_index() !=
+ if (LayerType* scroll_clip_layer = layer->scroll_clip_layer()) {
+ SetIsScrollClipLayer(scroll_clip_layer);
+ clip_bounds = scroll_clip_layer->bounds();
+ DCHECK(scroll_clip_layer->transform_tree_index() !=
TransformTree::kInvalidNodeId);
node.max_scroll_offset_affected_by_page_scale =
!data_from_ancestor.property_trees->transform_tree
- .Node(layer->scroll_clip_layer()->transform_tree_index())
+ .Node(scroll_clip_layer->transform_tree_index())
->in_subtree_of_page_scale_layer &&
data_from_ancestor.in_subtree_of_page_scale_layer;
}
@@ -1198,8 +1040,8 @@ void AddScrollNodeIfNeeded(
node.main_thread_scrolling_reasons;
data_for_children->scroll_tree_parent_created_by_uninheritable_criteria =
scroll_node_uninheritable_criteria;
- data_for_children->property_trees
- ->layer_id_to_scroll_node_index[layer->id()] = node_id;
+ data_for_children->property_trees->scroll_tree.SetOwningLayerIdForNode(
+ data_for_children->property_trees->scroll_tree.back(), layer->id());
// For animation subsystem purposes, if this layer has a compositor element
// id, we build a map from that id to this scroll node.
if (layer->element_id()) {
@@ -1288,17 +1130,13 @@ void BuildPropertyTreesInternal(
bool created_render_surface =
AddEffectNodeIfNeeded(data_from_parent, layer, &data_for_children);
- if (created_render_surface) {
+ if (created_render_surface)
data_for_children.render_target = data_for_children.effect_tree_parent;
- layer->set_draw_blend_mode(SkBlendMode::kSrcOver);
- } else {
- layer->set_draw_blend_mode(BlendMode(layer));
- }
bool created_transform_node = AddTransformNodeIfNeeded(
data_from_parent, layer, created_render_surface, &data_for_children);
- AddClipNodeIfNeeded(data_from_parent, layer, created_render_surface,
- created_transform_node, &data_for_children);
+ AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node,
+ &data_for_children);
AddScrollNodeIfNeeded(data_from_parent, layer, &data_for_children);
@@ -1359,18 +1197,6 @@ void BuildPropertyTreesInternal(
} // namespace
-void CC_EXPORT
-PropertyTreeBuilder::PreCalculateMetaInformation(Layer* root_layer) {
- PreCalculateMetaInformationRecursiveData recursive_data;
- PreCalculateMetaInformationInternal(root_layer, &recursive_data);
-}
-
-void CC_EXPORT PropertyTreeBuilder::PreCalculateMetaInformationForTesting(
- LayerImpl* root_layer) {
- PreCalculateMetaInformationRecursiveData recursive_data;
- PreCalculateMetaInformationInternalForTesting(root_layer, &recursive_data);
-}
-
Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) {
if (!layer)
return nullptr;
@@ -1435,8 +1261,6 @@ void BuildPropertyTreesTopLevelInternal(
data_for_recursion.affected_by_outer_viewport_bounds_delta = false;
data_for_recursion.should_flatten = false;
data_for_recursion.is_hidden = false;
- // The root clip is always applied.
- data_for_recursion.apply_ancestor_clip = true;
data_for_recursion.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
data_for_recursion.scroll_tree_parent_created_by_uninheritable_criteria =
@@ -1451,11 +1275,9 @@ void BuildPropertyTreesTopLevelInternal(
data_for_recursion.safe_opaque_background_color = color;
ClipNode root_clip;
- root_clip.resets_clip = true;
root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
root_clip.clip = gfx::RectF(viewport);
root_clip.transform_id = TransformTree::kRootNodeId;
- root_clip.target_transform_id = TransformTree::kRootNodeId;
data_for_recursion.clip_tree_parent =
data_for_recursion.property_trees->clip_tree.Insert(
root_clip, ClipTree::kRootNodeId);
diff --git a/chromium/cc/trees/property_tree_builder.h b/chromium/cc/trees/property_tree_builder.h
index d4b4eefab94..4418f94ee57 100644
--- a/chromium/cc/trees/property_tree_builder.h
+++ b/chromium/cc/trees/property_tree_builder.h
@@ -16,10 +16,6 @@ class PropertyTreeBuilder {
public:
static Layer* FindFirstScrollableLayer(Layer* root_layer);
- static void CC_EXPORT PreCalculateMetaInformation(Layer* root_layer);
- static void CC_EXPORT
- PreCalculateMetaInformationForTesting(LayerImpl* root_layer);
-
static void CC_EXPORT
BuildPropertyTrees(Layer* root_layer,
const Layer* page_scale_layer,
@@ -32,17 +28,18 @@ class PropertyTreeBuilder {
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
PropertyTrees* property_trees);
- static void BuildPropertyTrees(LayerImpl* root_layer,
- const LayerImpl* page_scale_layer,
- const LayerImpl* inner_viewport_scroll_layer,
- const LayerImpl* outer_viewport_scroll_layer,
- const LayerImpl* overscroll_elasticity_layer,
- const gfx::Vector2dF& elastic_overscroll,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- PropertyTrees* property_trees);
+ static void CC_EXPORT
+ BuildPropertyTrees(LayerImpl* root_layer,
+ const LayerImpl* page_scale_layer,
+ const LayerImpl* inner_viewport_scroll_layer,
+ const LayerImpl* outer_viewport_scroll_layer,
+ const LayerImpl* overscroll_elasticity_layer,
+ const gfx::Vector2dF& elastic_overscroll,
+ float page_scale_factor,
+ float device_scale_factor,
+ const gfx::Rect& viewport,
+ const gfx::Transform& device_transform,
+ PropertyTrees* property_trees);
};
} // namespace cc
diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc
index 40113d30f79..1c0c37692fc 100644
--- a/chromium/cc/trees/property_tree_unittest.cc
+++ b/chromium/cc/trees/property_tree_unittest.cc
@@ -23,7 +23,6 @@ TEST(PropertyTreeTest, ComputeTransformRoot) {
contents_root.local.Translate(2, 2);
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
gfx::Transform expected;
@@ -46,7 +45,6 @@ TEST(PropertyTreeTest, SetNeedsUpdate) {
TransformNode contents_root;
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
EXPECT_FALSE(tree.needs_update());
tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform(), gfx::PointF());
@@ -63,14 +61,12 @@ TEST(PropertyTreeTest, ComputeTransformChild) {
contents_root.local.Translate(2, 2);
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(contents_root.id);
TransformNode child;
child.local.Translate(3, 3);
child.source_node_id = 1;
child.id = tree.Insert(child, contents_root.id);
- tree.SetTargetId(child.id, 0);
tree.UpdateTransforms(child.id);
@@ -109,20 +105,17 @@ TEST(PropertyTreeTest, ComputeTransformSibling) {
contents_root.source_node_id = 0;
contents_root.local.Translate(2, 2);
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
TransformNode child;
child.local.Translate(3, 3);
child.source_node_id = 1;
child.id = tree.Insert(child, 1);
- tree.SetTargetId(child.id, 0);
TransformNode sibling;
sibling.local.Translate(7, 7);
sibling.source_node_id = 1;
sibling.id = tree.Insert(sibling, 1);
- tree.SetTargetId(sibling.id, 0);
tree.UpdateTransforms(2);
tree.UpdateTransforms(3);
@@ -158,26 +151,22 @@ TEST(PropertyTreeTest, ComputeTransformSiblingSingularAncestor) {
contents_root.local.Translate(2, 2);
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
TransformNode singular;
singular.local.matrix().set(2, 2, 0.0);
singular.source_node_id = 1;
singular.id = tree.Insert(singular, 1);
- tree.SetTargetId(singular.id, 0);
TransformNode child;
child.local.Translate(3, 3);
child.source_node_id = 2;
child.id = tree.Insert(child, 2);
- tree.SetTargetId(child.id, 0);
TransformNode sibling;
sibling.local.Translate(7, 7);
sibling.source_node_id = 2;
sibling.id = tree.Insert(sibling, 2);
- tree.SetTargetId(sibling.id, 0);
tree.UpdateTransforms(2);
tree.UpdateTransforms(3);
@@ -209,8 +198,6 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
effect_tree.Node(effect_grand_parent)->transform_id = grand_parent;
effect_tree.Node(effect_grand_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
- tree.SetContentTargetId(grand_parent, grand_parent);
- tree.SetTargetId(grand_parent, grand_parent);
tree.Node(grand_parent)->source_node_id = 0;
gfx::Transform rotation_about_x;
@@ -222,21 +209,15 @@ TEST(PropertyTreeTest, TransformsWithFlattening) {
effect_tree.Node(effect_parent)->has_render_surface = true;
effect_tree.Node(effect_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
- tree.SetTargetId(parent, grand_parent);
- tree.SetContentTargetId(parent, parent);
tree.Node(parent)->source_node_id = grand_parent;
tree.Node(parent)->local = rotation_about_x;
int child = tree.Insert(TransformNode(), parent);
- tree.SetTargetId(child, parent);
- tree.SetContentTargetId(child, parent);
tree.Node(child)->source_node_id = parent;
tree.Node(child)->flattens_inherited_transform = true;
tree.Node(child)->local = rotation_about_x;
int grand_child = tree.Insert(TransformNode(), child);
- tree.SetTargetId(grand_child, parent);
- tree.SetContentTargetId(grand_child, parent);
tree.Node(grand_child)->source_node_id = child;
tree.Node(grand_child)->flattens_inherited_transform = true;
tree.Node(grand_child)->local = rotation_about_x;
@@ -293,14 +274,12 @@ TEST(PropertyTreeTest, MultiplicationOrder) {
contents_root.local.Translate(2, 2);
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
TransformNode child;
child.local.Scale(2, 2);
child.source_node_id = 1;
child.id = tree.Insert(child, 1);
- tree.SetTargetId(child.id, 0);
tree.UpdateTransforms(2);
@@ -328,14 +307,12 @@ TEST(PropertyTreeTest, ComputeTransformWithUninvertibleTransform) {
TransformNode contents_root;
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
TransformNode child;
child.local.Scale(0, 0);
child.source_node_id = 1;
child.id = tree.Insert(child, 1);
- tree.SetTargetId(child.id, 0);
tree.UpdateTransforms(2);
@@ -360,31 +337,24 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) {
TransformNode contents_root;
contents_root.source_node_id = 0;
contents_root.id = tree.Insert(contents_root, 0);
- tree.SetTargetId(contents_root.id, 0);
tree.UpdateTransforms(1);
TransformNode grand_parent;
grand_parent.local.Scale(2.f, 0.f);
grand_parent.source_node_id = 1;
int grand_parent_id = tree.Insert(grand_parent, 1);
- tree.SetTargetId(grand_parent_id, 0);
- tree.SetContentTargetId(grand_parent_id, grand_parent_id);
tree.UpdateTransforms(grand_parent_id);
TransformNode parent;
parent.local.Translate(1.f, 1.f);
parent.source_node_id = grand_parent_id;
int parent_id = tree.Insert(parent, grand_parent_id);
- tree.SetTargetId(parent_id, grand_parent_id);
- tree.SetContentTargetId(parent_id, grand_parent_id);
tree.UpdateTransforms(parent_id);
TransformNode child;
child.local.Translate(3.f, 4.f);
child.source_node_id = parent_id;
int child_id = tree.Insert(child, parent_id);
- tree.SetTargetId(child_id, grand_parent_id);
- tree.SetContentTargetId(child_id, grand_parent_id);
tree.UpdateTransforms(child_id);
gfx::Transform expected_transform;
@@ -425,8 +395,6 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) {
TransformTree& tree = property_trees.transform_tree;
int parent = tree.Insert(TransformNode(), 0);
- tree.SetContentTargetId(parent, parent);
- tree.SetTargetId(parent, parent);
tree.Node(parent)->source_node_id = 0;
tree.Node(parent)->local.Translate(2, 2);
@@ -434,14 +402,10 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) {
rotation_about_x.RotateAboutXAxis(15);
int child = tree.Insert(TransformNode(), parent);
- tree.SetContentTargetId(child, child);
- tree.SetTargetId(child, child);
tree.Node(child)->source_node_id = parent;
tree.Node(child)->local = rotation_about_x;
int grand_child = tree.Insert(TransformNode(), child);
- tree.SetContentTargetId(grand_child, grand_child);
- tree.SetTargetId(grand_child, grand_child);
tree.Node(grand_child)->source_node_id = child;
tree.Node(grand_child)->flattens_inherited_transform = true;
@@ -485,12 +449,10 @@ TEST(PropertyTreeTest, NonIntegerTranslationTest) {
TransformTree& tree = property_trees.transform_tree;
int parent = tree.Insert(TransformNode(), 0);
- tree.SetTargetId(parent, parent);
tree.Node(parent)->source_node_id = 0;
tree.Node(parent)->local.Translate(1.5f, 1.5f);
int child = tree.Insert(TransformNode(), parent);
- tree.SetTargetId(child, parent);
tree.Node(child)->local.Translate(1, 1);
tree.Node(child)->source_node_id = parent;
tree.set_needs_update(true);
@@ -513,7 +475,6 @@ TEST(PropertyTreeTest, NonIntegerTranslationTest) {
tree.Node(child)->local.Translate(0.5f, 0.5f);
tree.Node(child)->needs_local_transform_update = true;
- tree.SetTargetId(child, child);
tree.set_needs_update(true);
draw_property_utils::ComputeTransforms(&tree);
EXPECT_TRUE(
@@ -534,13 +495,11 @@ TEST(PropertyTreeTest, SingularTransformSnapTest) {
effect_tree.Node(effect_parent)->has_render_surface = true;
effect_tree.Node(effect_parent)->surface_contents_scale =
gfx::Vector2dF(1.f, 1.f);
- tree.SetTargetId(parent, parent);
tree.Node(parent)->scrolls = true;
tree.Node(parent)->source_node_id = 0;
int child = tree.Insert(TransformNode(), parent);
TransformNode* child_node = tree.Node(child);
- tree.SetTargetId(child, parent);
child_node->scrolls = true;
child_node->local.Scale3d(6.0f, 6.0f, 0.0f);
child_node->local.Translate(1.3f, 1.3f);
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index 9e6c4c09596..7bb9145a894 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -13,7 +13,7 @@
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/values.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/trees/task_runner_provider.h"
diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h
index 69ffcfda262..45e16a9bd40 100644
--- a/chromium/cc/trees/proxy_common.h
+++ b/chromium/cc/trees/proxy_common.h
@@ -8,7 +8,7 @@
#include <stddef.h>
#include "base/callback_forward.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/output/begin_frame_args.h"
#include "cc/trees/layer_tree_host_common.h"
@@ -26,6 +26,7 @@ struct CC_EXPORT BeginMainFrameAndCommitState {
std::unique_ptr<ScrollAndScaleSet> scroll_info;
size_t memory_allocation_limit_bytes = 0;
bool evicted_ui_resources = false;
+ std::vector<base::Closure> completed_image_decode_callbacks;
};
} // namespace cc
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index 56919567b05..afced7e5c42 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -4,16 +4,20 @@
#include "cc/trees/proxy_impl.h"
+#include <string.h>
+
#include <algorithm>
#include <string>
#include "base/auto_reset.h"
+#include "base/debug/alias.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "base/trace_event/trace_event_synthetic_delay.h"
-#include "cc/debug/benchmark_instrumentation.h"
-#include "cc/debug/devtools_instrumentation.h"
+#include "cc/base/devtools_instrumentation.h"
+#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
#include "cc/output/compositor_frame_sink.h"
#include "cc/output/context_provider.h"
@@ -129,8 +133,8 @@ void ProxyImpl::InitializeCompositorFrameSinkOnImpl(
LayerTreeHostImpl* host_impl = layer_tree_host_impl_.get();
bool success = host_impl->InitializeRenderer(compositor_frame_sink);
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::DidInitializeCompositorFrameSink,
- proxy_main_weak_ptr_, success));
+ FROM_HERE, base::BindOnce(&ProxyMain::DidInitializeCompositorFrameSink,
+ proxy_main_weak_ptr_, success));
if (success)
scheduler_->DidCreateAndInitializeCompositorFrameSink();
}
@@ -223,6 +227,28 @@ void ProxyImpl::MainFrameWillHappenOnImplForTesting(
completion->Signal();
}
+// TODO(sunnyps): Remove this code once crbug.com/668892 is fixed.
+NOINLINE void ProxyImpl::DumpForBeginMainFrameHang() {
+ DCHECK(IsImplThread());
+ DCHECK(scheduler_);
+
+ char stack_string[20000] = "";
+ base::debug::Alias(&stack_string);
+
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> scheduler_state =
+ scheduler_->AsValue();
+ strncat(stack_string, scheduler_state->ToString().c_str(),
+ arraysize(stack_string) - strlen(stack_string) - 1);
+
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ tile_manager_state =
+ layer_tree_host_impl_->tile_manager()->ActivationStateAsValue();
+ strncat(stack_string, tile_manager_state->ToString().c_str(),
+ arraysize(stack_string) - strlen(stack_string) - 1);
+
+ base::debug::DumpWithoutCrashing();
+}
+
void ProxyImpl::NotifyReadyToCommitOnImpl(
CompletionEvent* completion,
LayerTreeHost* layer_tree_host,
@@ -259,8 +285,8 @@ void ProxyImpl::DidLoseCompositorFrameSinkOnImplThread() {
TRACE_EVENT0("cc", "ProxyImpl::DidLoseCompositorFrameSinkOnImplThread");
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ProxyMain::DidLoseCompositorFrameSink, proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::DidLoseCompositorFrameSink,
+ proxy_main_weak_ptr_));
scheduler_->DidLoseCompositorFrameSink();
}
@@ -280,8 +306,8 @@ void ProxyImpl::DidReceiveCompositorFrameAckOnImplThread() {
DCHECK(IsImplThread());
scheduler_->DidReceiveCompositorFrameAck();
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::DidReceiveCompositorFrameAck,
- proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::DidReceiveCompositorFrameAck,
+ proxy_main_weak_ptr_));
}
void ProxyImpl::OnCanDrawStateChanged(bool can_draw) {
@@ -339,8 +365,8 @@ void ProxyImpl::PostAnimationEventsToMainThreadOnImplThread(
TRACE_EVENT0("cc", "ProxyImpl::PostAnimationEventsToMainThreadOnImplThread");
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::SetAnimationEvents,
- proxy_main_weak_ptr_, base::Passed(&events)));
+ FROM_HERE, base::BindOnce(&ProxyMain::SetAnimationEvents,
+ proxy_main_weak_ptr_, base::Passed(&events)));
}
bool ProxyImpl::IsInsideDraw() {
@@ -423,8 +449,8 @@ void ProxyImpl::DidPrepareTiles() {
void ProxyImpl::DidCompletePageScaleAnimationOnImplThread() {
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::DidCompletePageScaleAnimation,
- proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::DidCompletePageScaleAnimation,
+ proxy_main_weak_ptr_));
}
void ProxyImpl::OnDrawForCompositorFrameSink(bool resourceless_software_draw) {
@@ -462,9 +488,12 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) {
layer_tree_host_impl_->ProcessScrollDeltas();
begin_main_frame_state->evicted_ui_resources =
layer_tree_host_impl_->EvictedUIResourcesExist();
+ begin_main_frame_state->completed_image_decode_callbacks =
+ layer_tree_host_impl_->TakeCompletedImageDecodeCallbacks();
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
- base::Passed(&begin_main_frame_state)));
+ FROM_HERE,
+ base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
+ base::Passed(&begin_main_frame_state)));
layer_tree_host_impl_->DidSendBeginMainFrame();
devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_);
}
@@ -493,6 +522,12 @@ void ProxyImpl::ScheduledActionCommit() {
DCHECK(IsMainThreadBlocked());
DCHECK(commit_completion_event_);
+ // Relax the cross-thread access restriction to non-thread-safe RefCount.
+ // It's safe since the main thread is blocked while a main-thread-bound
+ // compositor stuff are accessed from the impl thread.
+ base::ScopedAllowCrossThreadRefCountAccess
+ allow_cross_thread_ref_count_access;
+
layer_tree_host_impl_->BeginCommit();
blocked_main_commit().layer_tree_host->FinishCommitOnImplThread(
layer_tree_host_impl_.get());
@@ -537,8 +572,8 @@ void ProxyImpl::ScheduledActionBeginCompositorFrameSinkCreation() {
"ProxyImpl::ScheduledActionBeginCompositorFrameSinkCreation");
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::RequestNewCompositorFrameSink,
- proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::RequestNewCompositorFrameSink,
+ proxy_main_weak_ptr_));
}
void ProxyImpl::ScheduledActionPrepareTiles() {
@@ -563,8 +598,8 @@ void ProxyImpl::ScheduledActionPerformImplSideInvalidation() {
void ProxyImpl::SendBeginMainFrameNotExpectedSoon() {
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::BeginMainFrameNotExpectedSoon,
- proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::BeginMainFrameNotExpectedSoon,
+ proxy_main_weak_ptr_));
}
DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
@@ -593,6 +628,7 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
// CanDraw() as well.
LayerTreeHostImpl::FrameData frame;
+ frame.begin_frame_ack = scheduler_->CurrentBeginFrameAckForActiveTree();
bool draw_frame = false;
DrawResult result;
@@ -621,8 +657,8 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
if (next_frame_is_newly_committed_frame_) {
next_frame_is_newly_committed_frame_ = false;
MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ProxyMain::DidCommitAndDrawFrame, proxy_main_weak_ptr_));
+ FROM_HERE, base::BindOnce(&ProxyMain::DidCommitAndDrawFrame,
+ proxy_main_weak_ptr_));
}
DCHECK_NE(INVALID_RESULT, result);
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index a0482ea2ff8..68edc334515 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -56,6 +56,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient),
void MainFrameWillHappenOnImplForTesting(CompletionEvent* completion,
bool* main_frame_will_happen);
+ NOINLINE void DumpForBeginMainFrameHang();
+
private:
// The members of this struct should be accessed on the impl thread only when
// the main thread is blocked for a commit.
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index bab54a09e88..6b06f0ee80f 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -12,8 +12,8 @@
#include "base/trace_event/trace_event_argument.h"
#include "base/trace_event/trace_event_synthetic_delay.h"
#include "cc/base/completion_event.h"
-#include "cc/debug/benchmark_instrumentation.h"
-#include "cc/debug/devtools_instrumentation.h"
+#include "cc/base/devtools_instrumentation.h"
+#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/output/compositor_frame_sink.h"
#include "cc/output/swap_promise.h"
#include "cc/resources/ui_resource_manager.h"
@@ -124,16 +124,23 @@ void ProxyMain::BeginMainFrame(
DCHECK(IsMainThread());
DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_);
+ // We need to issue image decode callbacks whether or not we will abort this
+ // commit, since the callbacks are only stored in |begin_main_frame_state|.
+ for (auto& callback :
+ begin_main_frame_state->completed_image_decode_callbacks) {
+ callback.Run();
+ }
+
if (defer_commits_) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
TRACE_EVENT_SCOPE_THREAD);
std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::BeginMainFrameAbortedOnImpl,
- base::Unretained(proxy_impl_.get()),
- CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
- begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
+ FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
+ begin_main_frame_start_time,
+ base::Passed(&empty_swap_promises)));
return;
}
@@ -150,11 +157,11 @@ void ProxyMain::BeginMainFrame(
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::BeginMainFrameAbortedOnImpl,
- base::Unretained(proxy_impl_.get()),
- CommitEarlyOutReason::ABORTED_NOT_VISIBLE,
- begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
+ FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::ABORTED_NOT_VISIBLE,
+ begin_main_frame_start_time,
+ base::Passed(&empty_swap_promises)));
return;
}
@@ -180,6 +187,26 @@ void ProxyMain::BeginMainFrame(
layer_tree_host_->GetUIResourceManager()->RecreateUIResources();
layer_tree_host_->RequestMainFrameUpdate();
+
+ // At this point the main frame may have deferred commits to avoid committing
+ // right now.
+ if (defer_commits_) {
+ TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
+ TRACE_EVENT_SCOPE_THREAD);
+ std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
+ begin_main_frame_start_time,
+ base::Passed(&empty_swap_promises)));
+ current_pipeline_stage_ = NO_PIPELINE_STAGE;
+ // We intentionally don't report CommitComplete() here since it was aborted
+ // prematurely and we're waiting to do another commit in the future.
+ layer_tree_host_->DidBeginMainFrame();
+ return;
+ }
+
TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame");
bool can_cancel_this_commit = final_pipeline_stage_ < COMMIT_PIPELINE_STAGE &&
@@ -200,11 +227,11 @@ void ProxyMain::BeginMainFrame(
std::vector<std::unique_ptr<SwapPromise>> swap_promises =
layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises();
ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ProxyImpl::BeginMainFrameAbortedOnImpl,
- base::Unretained(proxy_impl_.get()),
- CommitEarlyOutReason::FINISHED_NO_UPDATES,
- begin_main_frame_start_time, base::Passed(&swap_promises)));
+ FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::FINISHED_NO_UPDATES,
+ begin_main_frame_start_time,
+ base::Passed(&swap_promises)));
// Although the commit is internally aborted, this is because it has been
// detected to be a no-op. From the perspective of an embedder, this commit
@@ -234,10 +261,11 @@ void ProxyMain::BeginMainFrame(
commit_waits_for_activation_ = false;
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::NotifyReadyToCommitOnImpl,
- base::Unretained(proxy_impl_.get()), &completion,
- layer_tree_host_, begin_main_frame_start_time,
- hold_commit_for_activation));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl,
+ base::Unretained(proxy_impl_.get()), &completion,
+ layer_tree_host_, begin_main_frame_start_time,
+ hold_commit_for_activation));
completion.Wait();
}
@@ -260,16 +288,16 @@ bool ProxyMain::CommitToActiveTree() const {
void ProxyMain::SetCompositorFrameSink(
CompositorFrameSink* compositor_frame_sink) {
ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ProxyImpl::InitializeCompositorFrameSinkOnImpl,
- base::Unretained(proxy_impl_.get()), compositor_frame_sink));
+ FROM_HERE, base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ compositor_frame_sink));
}
void ProxyMain::SetVisible(bool visible) {
TRACE_EVENT1("cc", "ProxyMain::SetVisible", "visible", visible);
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::SetVisibleOnImpl,
- base::Unretained(proxy_impl_.get()), visible));
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetVisibleOnImpl,
+ base::Unretained(proxy_impl_.get()), visible));
}
void ProxyMain::SetNeedsAnimate() {
@@ -314,8 +342,9 @@ void ProxyMain::SetNeedsRedraw(const gfx::Rect& damage_rect) {
TRACE_EVENT0("cc", "ProxyMain::SetNeedsRedraw");
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::SetNeedsRedrawOnImpl,
- base::Unretained(proxy_impl_.get()), damage_rect));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::SetNeedsRedrawOnImpl,
+ base::Unretained(proxy_impl_.get()), damage_rect));
}
void ProxyMain::SetNextCommitWaitsForActivation() {
@@ -326,8 +355,8 @@ void ProxyMain::SetNextCommitWaitsForActivation() {
void ProxyMain::NotifyInputThrottledUntilCommit() {
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::SetInputThrottledUntilCommitOnImpl,
- base::Unretained(proxy_impl_.get()), true));
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetInputThrottledUntilCommitOnImpl,
+ base::Unretained(proxy_impl_.get()), true));
}
void ProxyMain::SetDeferCommits(bool defer_commits) {
@@ -343,8 +372,8 @@ void ProxyMain::SetDeferCommits(bool defer_commits) {
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ProxyImpl::SetDeferCommitsOnImpl,
- base::Unretained(proxy_impl_.get()), defer_commits));
+ base::BindOnce(&ProxyImpl::SetDeferCommitsOnImpl,
+ base::Unretained(proxy_impl_.get()), defer_commits));
}
bool ProxyMain::CommitRequested() const {
@@ -358,8 +387,8 @@ bool ProxyMain::CommitRequested() const {
void ProxyMain::MainThreadHasStoppedFlinging() {
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::MainThreadHasStoppedFlingingOnImpl,
- base::Unretained(proxy_impl_.get())));
+ FROM_HERE, base::BindOnce(&ProxyImpl::MainThreadHasStoppedFlingingOnImpl,
+ base::Unretained(proxy_impl_.get())));
}
void ProxyMain::Start() {
@@ -370,8 +399,8 @@ void ProxyMain::Start() {
DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::InitializeOnImplThread,
- base::Unretained(this), &completion));
+ FROM_HERE, base::BindOnce(&ProxyMain::InitializeOnImplThread,
+ base::Unretained(this), &completion));
completion.Wait();
}
@@ -392,16 +421,16 @@ void ProxyMain::Stop() {
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ProxyImpl::FinishGLOnImpl,
- base::Unretained(proxy_impl_.get()), &completion));
+ base::BindOnce(&ProxyImpl::FinishGLOnImpl,
+ base::Unretained(proxy_impl_.get()), &completion));
completion.Wait();
}
{
DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyMain::DestroyProxyImplOnImplThread,
- base::Unretained(this), &completion));
+ FROM_HERE, base::BindOnce(&ProxyMain::DestroyProxyImplOnImplThread,
+ base::Unretained(this), &completion));
completion.Wait();
}
@@ -413,9 +442,9 @@ void ProxyMain::Stop() {
void ProxyMain::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
TRACE_EVENT0("compositor-worker", "ThreadProxy::SetMutator");
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::InitializeMutatorOnImpl,
- base::Unretained(proxy_impl_.get()),
- base::Passed(std::move(mutator))));
+ FROM_HERE, base::BindOnce(&ProxyImpl::InitializeMutatorOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ base::Passed(std::move(mutator))));
}
bool ProxyMain::SupportsImplScrolling() const {
@@ -429,9 +458,10 @@ bool ProxyMain::MainFrameWillHappenForTesting() {
DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::MainFrameWillHappenOnImplForTesting,
- base::Unretained(proxy_impl_.get()), &completion,
- &main_frame_will_happen));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::MainFrameWillHappenOnImplForTesting,
+ base::Unretained(proxy_impl_.get()), &completion,
+ &main_frame_will_happen));
completion.Wait();
}
return main_frame_will_happen;
@@ -442,8 +472,9 @@ void ProxyMain::ReleaseCompositorFrameSink() {
DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
CompletionEvent completion;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::ReleaseCompositorFrameSinkOnImpl,
- base::Unretained(proxy_impl_.get()), &completion));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::ReleaseCompositorFrameSinkOnImpl,
+ base::Unretained(proxy_impl_.get()), &completion));
completion.Wait();
}
@@ -452,9 +483,9 @@ void ProxyMain::UpdateBrowserControlsState(BrowserControlsState constraints,
bool animate) {
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::UpdateBrowserControlsStateOnImpl,
- base::Unretained(proxy_impl_.get()), constraints,
- current, animate));
+ FROM_HERE, base::BindOnce(&ProxyImpl::UpdateBrowserControlsStateOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ constraints, current, animate));
}
bool ProxyMain::SendCommitRequestToImplThreadIfNeeded(
@@ -467,8 +498,8 @@ bool ProxyMain::SendCommitRequestToImplThreadIfNeeded(
if (already_posted)
return false;
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&ProxyImpl::SetNeedsCommitOnImpl,
- base::Unretained(proxy_impl_.get())));
+ FROM_HERE, base::BindOnce(&ProxyImpl::SetNeedsCommitOnImpl,
+ base::Unretained(proxy_impl_.get())));
return true;
}
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index 29f4880a8b6..3d97276193a 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -6,7 +6,7 @@
#define CC_TREES_PROXY_MAIN_H_
#include "base/macros.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
#include "cc/trees/proxy.h"
#include "cc/trees/proxy_common.h"
diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h
index 09d7be86ecf..4eefe42aff1 100644
--- a/chromium/cc/trees/scroll_node.h
+++ b/chromium/cc/trees/scroll_node.h
@@ -5,9 +5,9 @@
#ifndef CC_TREES_SCROLL_NODE_H_
#define CC_TREES_SCROLL_NODE_H_
-#include "cc/base/cc_export.h"
+#include "cc/base/filter_operations.h"
#include "cc/base/region.h"
-#include "cc/output/filter_operations.h"
+#include "cc/cc_export.h"
#include "ui/gfx/geometry/size.h"
namespace base {
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 33ed54ae3a9..07b5afa607a 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -8,8 +8,8 @@
#include "base/memory/ptr_util.h"
#include "base/profiler/scoped_tracker.h"
#include "base/trace_event/trace_event.h"
-#include "cc/debug/benchmark_instrumentation.h"
-#include "cc/debug/devtools_instrumentation.h"
+#include "cc/base/devtools_instrumentation.h"
+#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/output/compositor_frame_sink.h"
#include "cc/output/context_provider.h"
#include "cc/quads/draw_quad.h"
@@ -204,6 +204,12 @@ void SingleThreadProxy::DoCommit() {
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->DidCommit();
+ // Issue decode callbacks.
+ auto completed_decode_callbacks =
+ layer_tree_host_impl_->TakeCompletedImageDecodeCallbacks();
+ for (auto& callback : completed_decode_callbacks)
+ callback.Run();
+
layer_tree_host_impl_->CommitComplete();
// Commit goes directly to the active tree, but we need to synchronously
@@ -449,8 +455,9 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
}
BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, 0, 1, frame_begin_time, base::TimeTicks(),
- BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
+ BEGINFRAME_FROM_HERE, BeginFrameArgs::kManualSourceId, 1,
+ frame_begin_time, base::TimeTicks(), BeginFrameArgs::DefaultInterval(),
+ BeginFrameArgs::NORMAL));
// Start the impl frame.
{
@@ -464,6 +471,7 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
DCHECK(inside_impl_frame_);
#endif
DoBeginMainFrame(begin_frame_args);
+ DoPainting();
DoCommit();
DCHECK_EQ(
@@ -485,6 +493,9 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
layer_tree_host_impl_->Animate();
LayerTreeHostImpl::FrameData frame;
+ frame.begin_frame_ack = BeginFrameAck(
+ begin_frame_args.source_id, begin_frame_args.sequence_number,
+ begin_frame_args.sequence_number, true);
DoComposite(&frame);
// DoComposite could abort, but because this is a synchronous composite
@@ -604,8 +615,8 @@ void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
#endif
task_runner_provider_->MainThreadTaskRunner()->PostTask(
- FROM_HERE, base::Bind(&SingleThreadProxy::BeginMainFrame,
- weak_factory_.GetWeakPtr(), begin_frame_args));
+ FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
+ weak_factory_.GetWeakPtr(), begin_frame_args));
layer_tree_host_impl_->DidSendBeginMainFrame();
}
@@ -648,6 +659,22 @@ void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) {
commit_requested_ = true;
DoBeginMainFrame(begin_frame_args);
+
+ // New commits requested inside UpdateLayers should be respected.
+ commit_requested_ = false;
+
+ // At this point the main frame may have deferred commits to avoid committing
+ // right now.
+ if (defer_commits_) {
+ TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
+ TRACE_EVENT_SCOPE_THREAD);
+ BeginMainFrameAbortedOnImplThread(
+ CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
+ layer_tree_host_->DidBeginMainFrame();
+ return;
+ }
+
+ DoPainting();
}
void SingleThreadProxy::DoBeginMainFrame(
@@ -664,10 +691,9 @@ void SingleThreadProxy::DoBeginMainFrame(
layer_tree_host_->BeginMainFrame(begin_frame_args);
layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
layer_tree_host_->RequestMainFrameUpdate();
+}
- // New commits requested inside UpdateLayers should be respected.
- commit_requested_ = false;
-
+void SingleThreadProxy::DoPainting() {
layer_tree_host_->UpdateLayers();
// TODO(enne): SingleThreadProxy does not support cancelling commits yet,
@@ -692,6 +718,8 @@ void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
DebugScopedSetImplThread impl(task_runner_provider_);
LayerTreeHostImpl::FrameData frame;
+ frame.begin_frame_ack =
+ scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
return DoComposite(&frame);
}
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 3e9487ea358..4a091950a27 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -112,6 +112,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void BeginMainFrame(const BeginFrameArgs& begin_frame_args);
void BeginMainFrameAbortedOnImplThread(CommitEarlyOutReason reason);
void DoBeginMainFrame(const BeginFrameArgs& begin_frame_args);
+ void DoPainting();
void DoCommit();
DrawResult DoComposite(LayerTreeHostImpl::FrameData* frame);
void DoSwap();
diff --git a/chromium/cc/trees/swap_promise_manager.h b/chromium/cc/trees/swap_promise_manager.h
index 8b5d9a23e56..795493dd3bb 100644
--- a/chromium/cc/trees/swap_promise_manager.h
+++ b/chromium/cc/trees/swap_promise_manager.h
@@ -9,7 +9,7 @@
#include <vector>
#include "base/macros.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "cc/output/swap_promise.h"
namespace cc {
diff --git a/chromium/cc/trees/swap_promise_monitor.h b/chromium/cc/trees/swap_promise_monitor.h
index 550176438e9..cde077e6345 100644
--- a/chromium/cc/trees/swap_promise_monitor.h
+++ b/chromium/cc/trees/swap_promise_monitor.h
@@ -5,7 +5,7 @@
#ifndef CC_TREES_SWAP_PROMISE_MONITOR_H_
#define CC_TREES_SWAP_PROMISE_MONITOR_H_
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace cc {
diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h
index e118c8db6a7..177ef965afa 100644
--- a/chromium/cc/trees/target_property.h
+++ b/chromium/cc/trees/target_property.h
@@ -7,7 +7,7 @@
#include <bitset>
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace cc {
diff --git a/chromium/cc/trees/task_runner_provider.h b/chromium/cc/trees/task_runner_provider.h
index e4c7b195cc4..1a7ebf5adca 100644
--- a/chromium/cc/trees/task_runner_provider.h
+++ b/chromium/cc/trees/task_runner_provider.h
@@ -16,7 +16,7 @@
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/values.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace base {
class SingleThreadTaskRunner;
diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc
index 8b9360f9091..6f89261dd29 100644
--- a/chromium/cc/trees/transform_node.cc
+++ b/chromium/cc/trees/transform_node.cc
@@ -108,9 +108,6 @@ void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("pre_local", pre_local, value);
MathUtil::AddToTracedValue("local", local, value);
MathUtil::AddToTracedValue("post_local", post_local, value);
- // TODO(sunxd): make frameviewer work without target_id
- value->SetInteger("target_id", 0);
- value->SetInteger("content_target_id", 0);
value->SetInteger("source_node_id", source_node_id);
value->SetInteger("sorting_context_id", sorting_context_id);
MathUtil::AddToTracedValue("scroll_offset", scroll_offset, value);
@@ -118,7 +115,7 @@ void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const {
}
TransformCachedNodeData::TransformCachedNodeData()
- : target_id(-1), content_target_id(-1), is_showing_backface(false) {}
+ : is_showing_backface(false) {}
TransformCachedNodeData::TransformCachedNodeData(
const TransformCachedNodeData& other) = default;
@@ -128,8 +125,6 @@ TransformCachedNodeData::~TransformCachedNodeData() {}
bool TransformCachedNodeData::operator==(
const TransformCachedNodeData& other) const {
return from_screen == other.from_screen && to_screen == other.to_screen &&
- target_id == other.target_id &&
- content_target_id == other.content_target_id &&
is_showing_backface == other.is_showing_backface;
}
diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h
index b98e83cdae9..76f2a7c2ffc 100644
--- a/chromium/cc/trees/transform_node.h
+++ b/chromium/cc/trees/transform_node.h
@@ -5,7 +5,7 @@
#ifndef CC_TREES_TRANSFORM_NODE_H_
#define CC_TREES_TRANSFORM_NODE_H_
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/transform.h"
@@ -148,10 +148,6 @@ struct CC_EXPORT TransformCachedNodeData {
gfx::Transform from_screen;
gfx::Transform to_screen;
- int target_id;
- // This id is used for all content that draws into a render surface associated
- // with this transform node.
- int content_target_id;
bool is_showing_backface : 1;
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index b593a9d66e9..52f1bb384c7 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -28,8 +28,10 @@ void SynchronizeTreesInternal(LayerTreeType* source_tree,
std::unique_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers());
OwnedLayerImplMap old_layer_map;
- for (auto& it : *old_layers)
+ for (auto& it : *old_layers) {
+ DCHECK(it);
old_layer_map[it->id()] = std::move(it);
+ }
PushLayerList(&old_layer_map, source_tree, tree_impl);
diff --git a/chromium/cc/trees/tree_synchronizer.h b/chromium/cc/trees/tree_synchronizer.h
index e5a0b62a0f6..1f0a1a1c8cf 100644
--- a/chromium/cc/trees/tree_synchronizer.h
+++ b/chromium/cc/trees/tree_synchronizer.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/macros.h"
-#include "cc/base/cc_export.h"
+#include "cc/cc_export.h"
namespace cc {