diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/cc/trees | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) |
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/trees')
62 files changed, 6974 insertions, 9328 deletions
diff --git a/chromium/cc/trees/animated_paint_worklet_tracker.cc b/chromium/cc/trees/animated_paint_worklet_tracker.cc new file mode 100644 index 00000000000..36b6d18f8a8 --- /dev/null +++ b/chromium/cc/trees/animated_paint_worklet_tracker.cc @@ -0,0 +1,113 @@ +// Copyright 2019 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/animated_paint_worklet_tracker.h" + +#include "cc/layers/picture_layer_impl.h" + +namespace cc { + +AnimatedPaintWorkletTracker::AnimatedPaintWorkletTracker() = default; + +AnimatedPaintWorkletTracker::~AnimatedPaintWorkletTracker() = default; + +AnimatedPaintWorkletTracker::PropertyState::PropertyState( + PaintWorkletInput::PropertyValue value, + base::flat_set<PictureLayerImpl*> layers) + : animation_value(value), associated_layers(std::move(layers)) {} + +AnimatedPaintWorkletTracker::PropertyState::PropertyState() = default; + +AnimatedPaintWorkletTracker::PropertyState::PropertyState( + const PropertyState& other) = default; + +AnimatedPaintWorkletTracker::PropertyState::~PropertyState() = default; + +void AnimatedPaintWorkletTracker::OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value) { + // This function is called to update custom property value only. + DCHECK(!custom_property_name.empty()); + PaintWorkletInput::PropertyKey key{custom_property_name, element_id}; + auto iter = input_properties_.find(key); + // OnCustomPropertyMutated is called for all composited custom property + // animations, but there may not be a matching PaintWorklet, and thus no entry + // in |input_properties_|. + // TODO(xidachen): Only create composited custom property animations if they + // affect paint worklet. + if (iter == input_properties_.end()) + return; + iter->second.animation_value = std::move(custom_property_value); + // Keep track of which input properties have been changed so that the + // associated PaintWorklets can be invalidated before activating the pending + // tree. + input_properties_animated_on_impl_.insert(key); +} + +bool AnimatedPaintWorkletTracker::InvalidatePaintWorkletsOnPendingTree() { + for (const auto& prop_key : input_properties_animated_on_impl_) { + auto it = input_properties_.find(prop_key); + // Since the invalidations happen on a newly created pending tree, + // previously animated input properties may not exist on this tree. + if (it == input_properties_.end()) + continue; + for (auto* layer : it->second.associated_layers) + layer->InvalidatePaintWorklets(prop_key); + } + bool return_value = !input_properties_animated_on_impl_.empty(); + input_properties_animated_on_impl_.clear(); + return return_value; +} + +PaintWorkletInput::PropertyValue +AnimatedPaintWorkletTracker::GetPropertyAnimationValue( + const PaintWorkletInput::PropertyKey& key) const { + return input_properties_.find(key)->second.animation_value; +} + +void AnimatedPaintWorkletTracker::UpdatePaintWorkletInputProperties( + const std::vector<DiscardableImageMap::PaintWorkletInputWithImageId>& + inputs, + PictureLayerImpl* layer) { + // Flatten the |inputs| into a set of all PropertyKeys, as we only care about + // PropertyKeys and PictureLayerImpls. + std::vector<PaintWorkletInput::PropertyKey> all_input_properties_vector; + for (const auto& input : inputs) { + all_input_properties_vector.insert( + all_input_properties_vector.end(), + std::begin(input.first->GetPropertyKeys()), + std::end(input.first->GetPropertyKeys())); + } + base::flat_set<PaintWorkletInput::PropertyKey> all_input_properties( + std::move(all_input_properties_vector)); + + // Update all existing properties, marking whether or not the input |layer| is + // associated with them. + for (auto& entry : input_properties_) { + if (all_input_properties.contains(entry.first)) + entry.second.associated_layers.insert(layer); + else + entry.second.associated_layers.erase(layer); + } + + // Handle any new properties that we did not previously track. + for (const auto& prop_key : all_input_properties) { + if (!input_properties_.contains(prop_key)) + input_properties_[prop_key].associated_layers.insert(layer); + } +} + +void AnimatedPaintWorkletTracker::ClearUnusedInputProperties() { + // base::flat_map::erase takes linear time, which causes O(N^2) behavior when + // using a naive loop + erase approach. Using base::EraseIf avoids that. + base::EraseIf( + input_properties_, + [](const std::pair<PaintWorkletInput::PropertyKey, PropertyState>& + entry) { return entry.second.associated_layers.empty(); }); + for (auto& entry : input_properties_) + entry.second.animation_value.reset(); +} + +} // namespace cc diff --git a/chromium/cc/trees/animated_paint_worklet_tracker.h b/chromium/cc/trees/animated_paint_worklet_tracker.h new file mode 100644 index 00000000000..996a6edc2f6 --- /dev/null +++ b/chromium/cc/trees/animated_paint_worklet_tracker.h @@ -0,0 +1,109 @@ +// Copyright 2019 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_ANIMATED_PAINT_WORKLET_TRACKER_H_ +#define CC_TREES_ANIMATED_PAINT_WORKLET_TRACKER_H_ + +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "base/memory/scoped_refptr.h" +#include "cc/cc_export.h" +#include "cc/paint/discardable_image_map.h" +#include "cc/paint/element_id.h" +#include "cc/paint/paint_worklet_input.h" + +namespace cc { + +class PictureLayerImpl; + +// AnimatedPaintWorkletTracker is responsible for managing the state needed to +// hook up the compositor animation system to PaintWorklets. This allows a +// PaintWorklet to be animated (i.e. have its input values changed) entirely on +// the compositor without requiring a main frame commit. +// +// This class tracks all properties that any PaintWorklet depends on, whether or +// not they are animated by the compositor. +// +// At the current time only custom properties are supported. +class CC_EXPORT AnimatedPaintWorkletTracker { + public: + AnimatedPaintWorkletTracker(); + AnimatedPaintWorkletTracker(const AnimatedPaintWorkletTracker&) = delete; + AnimatedPaintWorkletTracker& operator=(const AnimatedPaintWorkletTracker&) = + delete; + ~AnimatedPaintWorkletTracker(); + + // Update the |input_properties_| map, which is a map from a property to all + // picture layers that have a PaintWorkletInput that depends on the property. + void UpdatePaintWorkletInputProperties( + const std::vector<DiscardableImageMap::PaintWorkletInputWithImageId>& + inputs, + PictureLayerImpl* layer); + + // Called when the value of a property is changed by the CC animation system. + // Responsible for updating the property value in |input_properties_|, and + // marking any relevant PaintWorkletInputs as needs-invalidation. + void OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value); + // Invalidate all the paint worklets that uses the set of dirtied properties. + // Returns whether the set of dirtied properties is empty or not. + bool InvalidatePaintWorkletsOnPendingTree(); + + // Given a property, return its latest value if the property is animated. + // Otherwise return a PropertyValue with no value. + PaintWorkletInput::PropertyValue GetPropertyAnimationValue( + const PaintWorkletInput::PropertyKey& key) const; + + // Called right after Blink commit, clears the entries in |input_properties_| + // that is never mutated by CC animations from the previous Blink commit. Also + // reset the property value in the map. + void ClearUnusedInputProperties(); + + private: + // PropertyState contains the state we track for each property that any + // PaintWorklet depends on. This consists of: + // + // 1. The latest animation value if this property has been animated and is + // not independently tracked by property trees (i.e. opacity). + // + // 2. All the PictureLayerImpls which are associated (via a PaintWorklet) + // with the given property. This helps us to find all the + // PaintWorkletInputs that depend on the property, so that we can + // invalidate them when the property's value is changed by an animation. + struct PropertyState { + PropertyState(); + explicit PropertyState(PaintWorkletInput::PropertyValue value, + base::flat_set<PictureLayerImpl*> layers); + PropertyState(const PropertyState&); + ~PropertyState(); + + // The values for all properties mutated by CC animations are set on every + // commit. So we reset this value on every commit to identify properties + // still being animated in CC. This allows us to continue using the final + // value of the animation, after it finishes on the impl thread, until the + // next commit. + PaintWorkletInput::PropertyValue animation_value; + base::flat_set<PictureLayerImpl*> associated_layers; + }; + + // The set of input properties managed by AnimatedPaintWorkletTracker. + base::flat_map<PaintWorkletInput::PropertyKey, PropertyState> + input_properties_; + + // Tracks the set of input properties that were invalidated by an animation + // in the current frame. These are used to invalidate the relevant + // PaintWorklets after either an impl side invalidation or commit, so that + // they will be repainted. The set is emptied once all paint worklets have + // been invalidated. + base::flat_set<PaintWorkletInput::PropertyKey> + input_properties_animated_on_impl_; +}; + +} // namespace cc + +#endif // CC_TREES_ANIMATED_PAINT_WORKLET_TRACKER_H_ diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index b9046c6644b..f5bb60b229d 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -65,7 +65,8 @@ void ExecuteCalculateDrawProperties(LayerImpl* root, ASSERT_FALSE(render_surface_list->size()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), device_scale_factor, render_surface_list); + root, gfx::Rect(root->bounds()), device_scale_factor, + render_surface_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(GetRenderSurface(root)); } diff --git a/chromium/cc/trees/de_jelly_state.cc b/chromium/cc/trees/de_jelly_state.cc new file mode 100644 index 00000000000..3e41056e388 --- /dev/null +++ b/chromium/cc/trees/de_jelly_state.cc @@ -0,0 +1,181 @@ +// Copyright 2019 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/de_jelly_state.h" + +#include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scroll_node.h" +#include "cc/trees/transform_node.h" +#include "components/viz/common/display/de_jelly.h" + +namespace cc { + +DeJellyState::DeJellyState() = default; +DeJellyState::~DeJellyState() = default; + +void DeJellyState::AdvanceFrame(LayerTreeImpl* layer_tree_impl) { + if (!layer_tree_impl->settings().allow_de_jelly_effect) + return; + + should_de_jelly_ = false; + + // Move the |new_transforms_| from the previous draw into + // |previous_transforms_|. + std::swap(previous_transforms_, new_transforms_); + new_transforms_.clear(); + + // Make sure we have an active scroll node. Otherwise we won't perform any + // de-jelly. + ScrollNode* current_scroll = + layer_tree_impl->property_trees()->scroll_tree.Node( + layer_tree_impl->property_trees() + ->scroll_tree.currently_scrolling_node()); + if (!current_scroll) { + new_scroll_node_transform_.reset(); + return; + } + + scroll_transform_node_ = current_scroll->transform_id; + + // Check to make sure the ToScreen transform of our scroll node is not a + // complex transform (doesn't work well with de-jelly). Also make sure the + // scale is not changing. + base::Optional<gfx::Transform> previous_scroll_transform = + new_scroll_node_transform_; + new_scroll_node_transform_ = + layer_tree_impl->property_trees()->transform_tree.ToScreen( + current_scroll->transform_id); + if (!previous_scroll_transform || + !previous_scroll_transform->IsScaleOrTranslation() || + !new_scroll_node_transform_->IsScaleOrTranslation() || + new_scroll_node_transform_->Scale2d() != + previous_scroll_transform->Scale2d()) { + return; + } + + // Compute the fallback movement of a scrolling element based purely on the + // scroll offset of the currently scrolling node. + float previous_scroll_offset = scroll_offset_; + scroll_offset_ = layer_tree_impl->property_trees() + ->transform_tree.Node(scroll_transform_node_) + ->scroll_offset.y(); + fallback_delta_y_ = scroll_offset_ - previous_scroll_offset; + gfx::Vector3dF vector(0, fallback_delta_y_, 0); + new_scroll_node_transform_->TransformVector(&vector); + fallback_delta_y_ = vector.y(); + + // Don't attempt de-jelly while the omnibox is transitioning in or out. There + // is no correct way to handle this. + float top_controls_shown_ratio = + layer_tree_impl->top_controls_shown_ratio()->Current( + true /* is_active_tree */); + if (top_controls_shown_ratio != 0.0f && top_controls_shown_ratio != 1.0f) + return; + + // We've passed our initial checks, allow de-jelly in UpdateSharedQuadState. + should_de_jelly_ = true; +} + +void DeJellyState::UpdateSharedQuadState(LayerTreeImpl* layer_tree_impl, + int transform_id, + viz::RenderPass* target_render_pass) { + if (!should_de_jelly_) + return; + DCHECK(layer_tree_impl->settings().allow_de_jelly_effect); + + viz::SharedQuadState* state = + target_render_pass->shared_quad_state_list.back(); + state->de_jelly_delta_y = 0.0f; + + // Check if |transform_id| is a child of our |scroll_transform_node_| + // and if it scrolls (is not sticky or fixed). + bool does_not_scroll = false; + auto node_id = transform_id; + while (node_id != scroll_transform_node_ && node_id != kInvalidNodeId) { + auto* current_node = + layer_tree_impl->property_trees()->transform_tree.Node(node_id); + + // Position fixed. + if (current_node->moved_by_outer_viewport_bounds_delta_y) { + does_not_scroll = true; + break; + } + // Position sticky. + if (current_node->sticky_position_constraint_id > -1) { + const StickyPositionNodeData* sticky_data = + layer_tree_impl->property_trees() + ->transform_tree.GetStickyPositionData(node_id); + if (sticky_data && + sticky_data->total_containing_block_sticky_offset.y() > 0.0f) { + does_not_scroll = true; + break; + } + } + + node_id = current_node->parent_id; + } + does_not_scroll |= node_id == kInvalidNodeId; + if (does_not_scroll) + return; + + // Get the current node's ToScreen transform. + gfx::Transform transform = + layer_tree_impl->property_trees()->transform_tree.ToScreen(transform_id); + new_transforms_[transform_id] = transform; + + // Get the previous transform (if any). + const auto& found = previous_transforms_.find(transform_id); + + float delta_y = 0.0f; + if (found == previous_transforms_.end()) { + delta_y = fallback_delta_y_; + } else { + // Calculate the delta of point (0, 0) from the previous frame. + gfx::Transform previous_transform = found->second; + gfx::PointF new_point(0, 0); + transform.TransformPoint(&new_point); + gfx::PointF old_point(0, 0); + previous_transform.TransformPoint(&old_point); + delta_y = old_point.y() - new_point.y(); + } + + if (delta_y == 0.0f) { + return; + } + + // To minimize jarring visible effects, we de-jelly differently at + // different magnitudes of |delta_y|. This is controlled by three variables: + // kLinearDeJellyStart, kFixedDeJellyStart, kZeroDeJellyStart. + // _____________ + // | | _/| | + // de_jelly_delta_y | | _/ | | + // |_____|_/ | |_______________ + // +---------------------------------------- + // kLinear kFixed kZero + // + const float kLinearDeJellyStart = 2.0f; + const float kFixedDeJellyStart = + viz::MaxDeJellyHeight() + kLinearDeJellyStart; + const float kZeroDeJellyStart = 100.0f + kLinearDeJellyStart; + float sign = std::abs(delta_y) / delta_y; + float de_jelly_delta_y = std::abs(delta_y); + if (de_jelly_delta_y > kZeroDeJellyStart) { + de_jelly_delta_y = 0.0f; + } else if (de_jelly_delta_y > kFixedDeJellyStart) { + de_jelly_delta_y = kFixedDeJellyStart - kLinearDeJellyStart; + } else if (de_jelly_delta_y > kLinearDeJellyStart) { + de_jelly_delta_y = std::max(0.0f, de_jelly_delta_y - kLinearDeJellyStart); + } else { + de_jelly_delta_y = 0.0f; + } + // Re-apply the sign. + de_jelly_delta_y *= sign; + if (de_jelly_delta_y == 0.0f) { + return; + } + + state->de_jelly_delta_y = de_jelly_delta_y; +} + +} // namespace cc diff --git a/chromium/cc/trees/de_jelly_state.h b/chromium/cc/trees/de_jelly_state.h new file mode 100644 index 00000000000..40d249ddda6 --- /dev/null +++ b/chromium/cc/trees/de_jelly_state.h @@ -0,0 +1,54 @@ +// Copyright 2019 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_DE_JELLY_STATE_H_ +#define CC_TREES_DE_JELLY_STATE_H_ + +#include <map> + +#include "base/containers/flat_map.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "cc/cc_export.h" +#include "ui/gfx/transform.h" + +namespace viz { +class SharedQuadState; +class RenderPass; +} // namespace viz + +namespace cc { +class LayerTreeImpl; + +// Helper class which tracks the movement of layers and renderpasses +// and computes the |de_jelly_delta_y| for their SharedQuadState. +class CC_EXPORT DeJellyState { + public: + DeJellyState(); + ~DeJellyState(); + + // Called once per frame to move tracking structure to the next frame and + // determine if we should apply de-jelly at all. + void AdvanceFrame(LayerTreeImpl* layer_tree_impl); + + // Populates |de_jelly_delta_y| for the most recent SharedQuadState on + // |target_render_pass|. + void UpdateSharedQuadState(LayerTreeImpl* layer_tree_impl, + int transform_id, + viz::RenderPass* target_render_pass); + + private: + bool should_de_jelly_ = false; + int scroll_transform_node_ = 0; + float scroll_offset_ = 0; + float fallback_delta_y_ = 0; + + base::Optional<gfx::Transform> new_scroll_node_transform_; + std::map<int, gfx::Transform> previous_transforms_; + std::map<int, gfx::Transform> new_transforms_; +}; + +} // namespace cc + +#endif // CC_TREES_DE_JELLY_STATE_H_ diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index cf566cb9b6e..57241bad713 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -21,6 +21,7 @@ #include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" +#include "components/viz/common/display/de_jelly.h" #include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -610,11 +611,7 @@ static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, bool non_root_copy_request_or_cache_render_surface = lower_effect_closest_ancestor > EffectTree::kContentsRootNodeId; gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); - if (layer->layer_tree_impl()->IsRootLayer(layer) && - !layer->layer_tree_impl()->viewport_visible_rect().IsEmpty()) { - layer_content_rect.Intersect( - layer->layer_tree_impl()->viewport_visible_rect()); - } + gfx::RectF accumulated_clip_in_root_space; if (non_root_copy_request_or_cache_render_surface) { bool include_expanding_clips = true; @@ -647,6 +644,13 @@ static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); gfx::Rect visible_rect = ToEnclosingClipRect(clip_in_layer_space); + if (layer->layer_tree_impl()->settings().allow_de_jelly_effect) { + float padding_amount = viz::MaxDeJellyHeight(); + if (layer->IsAffectedByPageScale()) { + padding_amount /= layer->layer_tree_impl()->current_page_scale_factor(); + } + visible_rect.Inset(0.0f, -padding_amount); + } visible_rect.Intersect(layer_content_rect); return visible_rect; } @@ -1040,9 +1044,7 @@ void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, void UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, - float page_scale_factor, - float device_scale_factor, - const gfx::Transform device_transform) { + float page_scale_factor) { // TODO(wjmaclean): Once Issue #845097 is resolved, we can change the nullptr // check below to a DCHECK. if (property_trees->transform_tree.page_scale_factor() == page_scale_factor || @@ -1052,11 +1054,8 @@ void UpdatePageScaleFactor(PropertyTrees* property_trees, property_trees->transform_tree.set_page_scale_factor(page_scale_factor); - float post_local_scale_factor = page_scale_factor * device_scale_factor; - page_scale_node->post_local_scale_factor = post_local_scale_factor; - page_scale_node->post_local = device_transform; - page_scale_node->post_local.Scale(post_local_scale_factor, - post_local_scale_factor); + page_scale_node->local.MakeIdentity(); + page_scale_node->local.Scale(page_scale_factor, page_scale_factor); page_scale_node->needs_local_transform_update = true; property_trees->transform_tree.set_needs_update(true); diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index 6ca984986bd..54c7a458d33 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -90,9 +90,7 @@ gfx::Transform CC_EXPORT ScreenSpaceTransform(const LayerImpl* layer, void CC_EXPORT UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, - float page_scale_factor, - float device_scale_factor, - const gfx::Transform device_transform); + float page_scale_factor); void CC_EXPORT UpdateElasticOverscroll(PropertyTrees* property_trees, diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 847432950b3..339be0b576b 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -20,7 +20,7 @@ EffectNode::EffectNode() cache_render_surface(false), has_copy_request(false), hidden_by_backface_visibility(false), - double_sided(false), + double_sided(true), trilinear_filtering(false), is_drawn(true), subtree_hidden(false), diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index eaddb83fb4e..0f9d220d218 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -93,6 +93,8 @@ struct CC_EXPORT EffectNode { bool cache_render_surface : 1; bool has_copy_request : 1; bool hidden_by_backface_visibility : 1; + // Whether the contents should continue to be visible when rotated such that + // its back face is facing toward the camera. It's true by default. bool double_sided : 1; bool trilinear_filtering : 1; bool is_drawn : 1; diff --git a/chromium/cc/trees/frame_sequence_tracker.cc b/chromium/cc/trees/frame_sequence_tracker.cc deleted file mode 100644 index a4020409e7a..00000000000 --- a/chromium/cc/trees/frame_sequence_tracker.cc +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2019 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_sequence_tracker.h" - -#include "base/metrics/histogram.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/strcat.h" -#include "base/trace_event/trace_event.h" -#include "base/trace_event/traced_value.h" -#include "components/viz/common/frame_sinks/begin_frame_args.h" -#include "components/viz/common/quads/compositor_frame_metadata.h" -#include "ui/gfx/presentation_feedback.h" - -namespace cc { - -namespace { - -enum class ThreadType { - kMain, - kCompositor, -}; - -constexpr const char* const kBuiltinSequences[] = { - [FrameSequenceTrackerType::kCompositorAnimation] = "CompositorAnimation", - [FrameSequenceTrackerType::kMainThreadAnimation] = "MainThreadAnimation", - [FrameSequenceTrackerType::kPinchZoom] = "PinchZoom", - [FrameSequenceTrackerType::kRAF] = "RAF", - [FrameSequenceTrackerType::kTouchScroll] = "TouchScroll", - [FrameSequenceTrackerType::kWheelScroll] = "WheelScroll", -}; - -constexpr int kBuiltinSequenceNum = base::size(kBuiltinSequences); -constexpr int kMaximumHistogramIndex = 2 * kBuiltinSequenceNum; - -int GetIndexForMetric(ThreadType thread_type, FrameSequenceTrackerType type) { - return thread_type == ThreadType::kMain - ? static_cast<int>(type) - : static_cast<int>(type + kBuiltinSequenceNum); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// FrameSequenceTrackerCollection - -FrameSequenceTrackerCollection::FrameSequenceTrackerCollection() {} -FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() { - removal_trackers_.clear(); - DCHECK(frame_trackers_.empty()); -} - -std::unique_ptr<FrameSequenceTracker> -FrameSequenceTrackerCollection::CreateTracker(FrameSequenceTrackerType type) { - // The collection always outlives the trackers. So using Unretained() here is - // safe. - auto tracker = base::WrapUnique(new FrameSequenceTracker( - type, base::BindOnce(&FrameSequenceTrackerCollection::RemoveFrameTracker, - base::Unretained(this)))); - AddFrameTracker(tracker.get()); - return tracker; -} - -void FrameSequenceTrackerCollection::ScheduleRemoval( - std::unique_ptr<FrameSequenceTracker> tracker) { - if (!tracker) - return; - tracker->ScheduleTerminate(); - removal_trackers_.push_back(std::move(tracker)); -} - -void FrameSequenceTrackerCollection::ClearAll() { - removal_trackers_.clear(); - DCHECK(frame_trackers_.empty()); -} - -void FrameSequenceTrackerCollection::NotifyBeginImplFrame( - const viz::BeginFrameArgs& args) { - for (auto* tracker : frame_trackers_) { - tracker->ReportBeginImplFrame(args); - } -} - -void FrameSequenceTrackerCollection::NotifyBeginMainFrame( - const viz::BeginFrameArgs& args) { - for (auto* tracker : frame_trackers_) { - tracker->ReportBeginMainFrame(args); - } -} - -void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage( - const viz::BeginFrameAck& ack) { - for (auto* tracker : frame_trackers_) { - tracker->ReportImplFrameCausedNoDamage(ack); - } -} - -void FrameSequenceTrackerCollection::NotifyMainFrameCausedNoDamage( - const viz::BeginFrameArgs& args) { - for (auto* tracker : frame_trackers_) { - tracker->ReportMainFrameCausedNoDamage(args); - } -} - -void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() { - for (auto* tracker : frame_trackers_) - tracker->PauseFrameProduction(); -} - -void FrameSequenceTrackerCollection::NotifySubmitFrame( - uint32_t frame_token, - const viz::BeginFrameAck& ack, - const viz::BeginFrameArgs& origin_args) { - for (auto* tracker : frame_trackers_) { - tracker->ReportSubmitFrame(frame_token, ack, origin_args); - } -} - -void FrameSequenceTrackerCollection::NotifyFramePresented( - uint32_t frame_token, - const gfx::PresentationFeedback& feedback) { - for (auto* tracker : frame_trackers_) - tracker->ReportFramePresented(frame_token, feedback); - - // Destroy the trackers that are ready to be terminated. - base::EraseIf( - removal_trackers_, - [](const std::unique_ptr<FrameSequenceTracker>& tracker) { - return tracker->termination_status() == - FrameSequenceTracker::TerminationStatus::kReadyForTermination; - }); -} - -void FrameSequenceTrackerCollection::AddFrameTracker( - FrameSequenceTracker* tracker) { - frame_trackers_.push_back(tracker); -} - -void FrameSequenceTrackerCollection::RemoveFrameTracker( - FrameSequenceTracker* tracker) { - base::Erase(frame_trackers_, tracker); -} - -//////////////////////////////////////////////////////////////////////////////// -// FrameSequenceTracker - -FrameSequenceTracker::FrameSequenceTracker( - FrameSequenceTrackerType type, - base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback) - : type_(type), destroy_callback_(std::move(destroy_callback)) { - DCHECK_LT(type_, FrameSequenceTrackerType::kMaxType); - TRACE_EVENT_ASYNC_BEGIN1("cc,benchmark", "FrameSequenceTracker", this, "name", - TRACE_STR_COPY(kBuiltinSequences[type_])); -} - -FrameSequenceTracker::~FrameSequenceTracker() { - DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected); - DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected); - DCHECK_LE(main_throughput_.frames_produced, impl_throughput_.frames_produced); - TRACE_EVENT_ASYNC_END1( - "cc,benchmark", "FrameSequenceTracker", this, "args", - ThroughputData::ToTracedValue(impl_throughput_, main_throughput_)); - ThroughputData::ReportHistogram( - type_, "CompositorThread", - GetIndexForMetric(ThreadType::kCompositor, type_), impl_throughput_); - ThroughputData::ReportHistogram(type_, "MainThread", - GetIndexForMetric(ThreadType::kMain, type_), - main_throughput_); - std::move(destroy_callback_).Run(this); -} - -void FrameSequenceTracker::ReportBeginImplFrame( - const viz::BeginFrameArgs& args) { - if (termination_status_ != TerminationStatus::kActive) - return; - - if (ShouldIgnoreBeginFrameSource(args.source_id)) - return; - - UpdateTrackedFrameData(&begin_impl_frame_data_, args.source_id, - args.sequence_number); - impl_throughput_.frames_expected += - begin_impl_frame_data_.previous_sequence_delta; -} - -void FrameSequenceTracker::ReportBeginMainFrame( - const viz::BeginFrameArgs& args) { - if (termination_status_ != TerminationStatus::kActive) - return; - - if (ShouldIgnoreBeginFrameSource(args.source_id)) - return; - - UpdateTrackedFrameData(&begin_main_frame_data_, args.source_id, - args.sequence_number); - if (first_received_main_sequence_ == 0) - first_received_main_sequence_ = args.sequence_number; - main_throughput_.frames_expected += - begin_main_frame_data_.previous_sequence_delta; -} - -void FrameSequenceTracker::ReportSubmitFrame( - uint32_t frame_token, - const viz::BeginFrameAck& ack, - const viz::BeginFrameArgs& origin_args) { - if (termination_status_ != TerminationStatus::kActive) - return; - - if (ShouldIgnoreBeginFrameSource(ack.source_id)) - return; - - if (begin_impl_frame_data_.previous_sequence == 0 || - ack.sequence_number < begin_impl_frame_data_.previous_sequence) { - return; - } - - if (first_submitted_frame_ == 0) - first_submitted_frame_ = frame_token; - last_submitted_frame_ = frame_token; - - if (!ShouldIgnoreBeginFrameSource(origin_args.source_id) && - first_received_main_sequence_ && - origin_args.sequence_number >= first_received_main_sequence_) { - if (last_submitted_main_sequence_ == 0 || - origin_args.sequence_number > last_submitted_main_sequence_) { - last_submitted_main_sequence_ = origin_args.sequence_number; - main_frames_.push_back(frame_token); - DCHECK_GE(main_throughput_.frames_expected, main_frames_.size()); - } - } -} - -void FrameSequenceTracker::ReportFramePresented( - uint32_t frame_token, - const gfx::PresentationFeedback& feedback) { - const bool frame_token_acks_last_frame = - frame_token == last_submitted_frame_ || - viz::FrameTokenGT(frame_token, last_submitted_frame_); - - // Update termination status if this is scheduled for termination, and it is - // not waiting for any frames, or it has received the presentation-feedback - // for the latest frame it is tracking. - if (termination_status_ == TerminationStatus::kScheduledForTermination && - (last_submitted_frame_ == 0 || frame_token_acks_last_frame)) { - termination_status_ = TerminationStatus::kReadyForTermination; - } - - if (first_submitted_frame_ == 0 || - viz::FrameTokenGT(first_submitted_frame_, frame_token)) { - // We are getting presentation feedback for frames that were submitted - // before this sequence started. So ignore these. - return; - } - - const bool was_presented = !feedback.timestamp.is_null(); - if (was_presented && last_submitted_frame_) { - DCHECK_LT(impl_throughput_.frames_produced, - impl_throughput_.frames_expected); - ++impl_throughput_.frames_produced; - - if (frame_token_acks_last_frame) - last_submitted_frame_ = 0; - } - - while (!main_frames_.empty() && - !viz::FrameTokenGT(main_frames_.front(), frame_token)) { - if (was_presented && main_frames_.front() == frame_token) { - DCHECK_LT(main_throughput_.frames_produced, - main_throughput_.frames_expected); - ++main_throughput_.frames_produced; - } - main_frames_.pop_front(); - } -} - -void FrameSequenceTracker::ReportImplFrameCausedNoDamage( - const viz::BeginFrameAck& ack) { - if (termination_status_ != TerminationStatus::kActive) - return; - - if (ShouldIgnoreBeginFrameSource(ack.source_id)) - return; - - // It is possible that this is called before a begin-impl-frame has been - // dispatched for this frame-sequence. In such cases, ignore this call. - if (begin_impl_frame_data_.previous_sequence == 0 || - ack.sequence_number < begin_impl_frame_data_.previous_sequence) { - return; - } - DCHECK_GT(impl_throughput_.frames_expected, 0u); - DCHECK_GT(impl_throughput_.frames_expected, impl_throughput_.frames_produced); - --impl_throughput_.frames_expected; - - if (begin_impl_frame_data_.previous_sequence == ack.sequence_number) - begin_impl_frame_data_.previous_sequence = 0; -} - -void FrameSequenceTracker::ReportMainFrameCausedNoDamage( - const viz::BeginFrameArgs& args) { - if (termination_status_ != TerminationStatus::kActive) - return; - - if (ShouldIgnoreBeginFrameSource(args.source_id)) - return; - - // It is possible that this is called before a begin-main-frame has been - // dispatched for this frame-sequence. In such cases, ignore this call. - if (begin_main_frame_data_.previous_sequence == 0 || - args.sequence_number < begin_main_frame_data_.previous_sequence) { - return; - } - - DCHECK_GT(main_throughput_.frames_expected, 0u); - DCHECK_GT(main_throughput_.frames_expected, main_throughput_.frames_produced); - --main_throughput_.frames_expected; - DCHECK_GE(main_throughput_.frames_expected, main_frames_.size()); - - if (begin_main_frame_data_.previous_sequence == args.sequence_number) - begin_main_frame_data_.previous_sequence = 0; -} - -void FrameSequenceTracker::PauseFrameProduction() { - // Reset the states, so that the tracker ignores the vsyncs until the next - // received begin-frame. - begin_impl_frame_data_ = {0, 0, 0}; - begin_main_frame_data_ = {0, 0, 0}; -} - -void FrameSequenceTracker::UpdateTrackedFrameData(TrackedFrameData* frame_data, - uint64_t source_id, - uint64_t sequence_number) { - if (frame_data->previous_sequence && - frame_data->previous_source == source_id) { - uint8_t current_latency = sequence_number - frame_data->previous_sequence; - frame_data->previous_sequence_delta = current_latency; - } else { - frame_data->previous_sequence_delta = 1; - } - frame_data->previous_source = source_id; - frame_data->previous_sequence = sequence_number; -} - -bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource( - uint64_t source_id) const { - if (begin_impl_frame_data_.previous_source == 0) - return false; - return source_id != begin_impl_frame_data_.previous_source; -} - -std::unique_ptr<base::trace_event::TracedValue> -FrameSequenceTracker::ThroughputData::ToTracedValue( - const ThroughputData& impl, - const ThroughputData& main) { - auto dict = std::make_unique<base::trace_event::TracedValue>(); - dict->SetInteger("impl-frames-produced", impl.frames_produced); - dict->SetInteger("impl-frames-expected", impl.frames_expected); - dict->SetInteger("main-frames-produced", main.frames_produced); - dict->SetInteger("main-frames-expected", main.frames_expected); - return dict; -} - -void FrameSequenceTracker::ThroughputData::ReportHistogram( - FrameSequenceTrackerType sequence_type, - const char* thread_name, - int metric_index, - const ThroughputData& data) { - DCHECK_LT(sequence_type, FrameSequenceTrackerType::kMaxType); - - UMA_HISTOGRAM_COUNTS_1000("Graphics.Smoothness.FrameSequenceLength", - data.frames_expected); - - // Avoid reporting any throughput metric for sequences that had a small amount - // of frames. - constexpr int kMinFramesForThroughputMetric = 4; - if (data.frames_expected < kMinFramesForThroughputMetric) - return; - - const std::string name = - base::StrCat({"Graphics.Smoothness.Throughput.", thread_name, ".", - kBuiltinSequences[sequence_type]}); - const int percent = - static_cast<int>(100 * data.frames_produced / data.frames_expected); - STATIC_HISTOGRAM_POINTER_GROUP( - name, metric_index, kMaximumHistogramIndex, Add(percent), - base::LinearHistogram::FactoryGet( - name, 1, 100, 101, base::HistogramBase::kUmaTargetedHistogramFlag)); -} - -} // namespace cc diff --git a/chromium/cc/trees/frame_sequence_tracker.h b/chromium/cc/trees/frame_sequence_tracker.h deleted file mode 100644 index 57b370eb316..00000000000 --- a/chromium/cc/trees/frame_sequence_tracker.h +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2019 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_SEQUENCE_TRACKER_H_ -#define CC_TREES_FRAME_SEQUENCE_TRACKER_H_ - -#include <stdint.h> -#include <memory> -#include <set> -#include <utility> -#include <vector> - -#include "base/callback_helpers.h" -#include "base/containers/circular_deque.h" -#include "base/macros.h" -#include "base/trace_event/traced_value.h" -#include "cc/cc_export.h" - -namespace gfx { -struct PresentationFeedback; -} - -namespace viz { -struct BeginFrameAck; -struct BeginFrameArgs; -} // namespace viz - -namespace cc { -class FrameSequenceTracker; - -enum FrameSequenceTrackerType { - kCompositorAnimation, - kMainThreadAnimation, - kPinchZoom, - kRAF, - kTouchScroll, - kWheelScroll, - kMaxType -}; - -// Used for notifying attached FrameSequenceTracker's of begin-frames and -// submitted frames. -class CC_EXPORT FrameSequenceTrackerCollection { - public: - FrameSequenceTrackerCollection(); - ~FrameSequenceTrackerCollection(); - - FrameSequenceTrackerCollection(const FrameSequenceTrackerCollection&) = - delete; - FrameSequenceTrackerCollection& operator=( - const FrameSequenceTrackerCollection&) = delete; - - // Creates a tracker for the specified sequence-type. - std::unique_ptr<FrameSequenceTracker> CreateTracker( - FrameSequenceTrackerType type); - - // Schedules |tracker| for destruction. This is preferred instead of outright - // desrtruction of the tracker, since this ensures that the actual tracker - // instance is destroyed *after* the presentation-feedbacks have been received - // for all submitted frames. - void ScheduleRemoval(std::unique_ptr<FrameSequenceTracker> tracker); - - // Removes all trackers. This also immediately destroys all trackers that had - // been scheduled for destruction, even if there are pending - // presentation-feedbacks. This is typically used if the client no longer - // expects to receive presentation-feedbacks for the previously submitted - // frames (e.g. when the gpu process dies). - void ClearAll(); - - // Notifies all trackers of various events. - void NotifyBeginImplFrame(const viz::BeginFrameArgs& args); - void NotifyBeginMainFrame(const viz::BeginFrameArgs& args); - void NotifyImplFrameCausedNoDamage(const viz::BeginFrameAck& ack); - void NotifyMainFrameCausedNoDamage(const viz::BeginFrameArgs& args); - void NotifyPauseFrameProduction(); - void NotifySubmitFrame(uint32_t frame_token, - const viz::BeginFrameAck& ack, - const viz::BeginFrameArgs& origin_args); - - // Note that this notifies the trackers of the presentation-feedbacks, and - // destroys any tracker that had been scheduled for destruction (using - // |ScheduleRemoval()|) if it has no more pending frames. - void NotifyFramePresented(uint32_t frame_token, - const gfx::PresentationFeedback& feedback); - - private: - void AddFrameTracker(FrameSequenceTracker* tracker); - void RemoveFrameTracker(FrameSequenceTracker* tracker); - - std::vector<FrameSequenceTracker*> frame_trackers_; - std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_; -}; - -// Tracks a sequence of frames to determine the throughput. It tracks this by -// tracking the vsync sequence-numbers (from |BeginFrameArgs::sequence_number|), -// and the presentation-timestamps (from |gfx::PresentationFeedback|). It also -// tracks which frames were expected to include update from the main-thread, and -// which presented frames did include updates from the main-thread. -// This object should be created through -// FrameSequenceTrackerCollection::CreateTracker() API. -class CC_EXPORT FrameSequenceTracker { - public: - enum class TerminationStatus { - kActive, - kScheduledForTermination, - kReadyForTermination, - }; - - ~FrameSequenceTracker(); - - FrameSequenceTracker(const FrameSequenceTracker&) = delete; - FrameSequenceTracker& operator=(const FrameSequenceTracker&) = delete; - - // Notifies the tracker when the compositor thread starts to process a - // BeginFrameArgs. - void ReportBeginImplFrame(const viz::BeginFrameArgs& args); - - // Notifies the tracker when a BeginFrameArgs is dispatched to the main - // thread. - void ReportBeginMainFrame(const viz::BeginFrameArgs& args); - - // Notifies the tracker when the compositor submits a CompositorFrame. - // |origin_args| represents the BeginFrameArgs that triggered the update from - // the main-thread. - void ReportSubmitFrame(uint32_t frame_token, - const viz::BeginFrameAck& ack, - const viz::BeginFrameArgs& origin_args); - - // Notifies the tracker of the presentation-feedback of a previously submitted - // CompositorFrame with |frame_token|. - void ReportFramePresented(uint32_t frame_token, - const gfx::PresentationFeedback& feedback); - - // Notifies the tracker that a CompositorFrame is not going to be submitted - // for a particular BeginFrameArgs because it did not cause any damage (visual - // change). Note that if a begin-main-frame was dispatched, then a separate - // call to |ReportMainFrameCausedNoDamage()| is made to notify that the - // main-thread did not cause any damage/updates. - void ReportImplFrameCausedNoDamage(const viz::BeginFrameAck& ack); - - // Notifies the tracker that a |BeginFrameArgs| either was not dispatched to - // the main-thread (because it did not ask for it), or that a |BeginFrameArgs| - // that was dispatched to the main-thread did not cause any updates/damage. - void ReportMainFrameCausedNoDamage(const viz::BeginFrameArgs& args); - - // Notifies that frame production has currently paused. This is typically used - // for interactive frame-sequences, e.g. during touch-scroll. - void PauseFrameProduction(); - - TerminationStatus termination_status() const { return termination_status_; } - - private: - friend class FrameSequenceTrackerCollection; - - FrameSequenceTracker( - FrameSequenceTrackerType type, - base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback); - - void ScheduleTerminate() { - termination_status_ = TerminationStatus::kScheduledForTermination; - } - - struct TrackedFrameData { - // Represents the |BeginFrameArgs::source_id| and - // |BeginFrameArgs::sequence_number| fields of the last processed - // BeginFrameArgs. - uint64_t previous_source = 0; - uint64_t previous_sequence = 0; - - // The difference in |BeginFrameArgs::sequence_number| fields of the last - // two processed BeginFrameArgs. - uint8_t previous_sequence_delta = 0; - }; - - struct ThroughputData { - static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue( - const ThroughputData& impl, - const ThroughputData& main); - static void ReportHistogram(FrameSequenceTrackerType sequence_type, - const char* thread_name, - int metric_index, - const ThroughputData& data); - // Tracks the number of frames that were expected to be shown during this - // frame-sequence. - uint32_t frames_expected = 0; - - // Tracks the number of frames that were actually presented to the user - // during this frame-sequence. - uint32_t frames_produced = 0; - }; - - void UpdateTrackedFrameData(TrackedFrameData* frame_data, - uint64_t source_id, - uint64_t sequence_number); - - bool ShouldIgnoreBeginFrameSource(uint64_t source_id) const; - - const FrameSequenceTrackerType type_; - base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback_; - - TerminationStatus termination_status_ = TerminationStatus::kActive; - - TrackedFrameData begin_impl_frame_data_; - TrackedFrameData begin_main_frame_data_; - - ThroughputData impl_throughput_; - ThroughputData main_throughput_; - - // Tracks the list of frame-tokens for compositor-frames that included new - // updates from the main-thread, whose presentation-feedback have not been - // received yet. When the presentation-feedback for a frame is received, the - // corresponding frame-token is removed from this collection. - base::circular_deque<uint32_t> main_frames_; - - // Keeps track of the sequence-number of the first received begin-main-frame. - // This is used to ignore submitted frames that include updates from earlier - // begin-main-frames. - uint64_t first_received_main_sequence_ = 0; - - // Keeps track of the first submitted compositor-frame. This is used to ignore - // reports from frames that were submitted before this tracker had been - // created. - uint32_t first_submitted_frame_ = 0; - - // Keeps track of the latest submitted compositor-frame, so that it can - // determine when it has received presentation-feedback for submitted frames. - // This is used to decide when to terminate this FrameSequenceTracker object. - uint32_t last_submitted_frame_ = 0; - - // Keeps track of the last sequence-number that produced a frame from the - // main-thread. - uint64_t last_submitted_main_sequence_ = 0; -}; - -} // namespace cc - -#endif // CC_TREES_FRAME_SEQUENCE_TRACKER_H_ diff --git a/chromium/cc/trees/frame_sequence_tracker_unittest.cc b/chromium/cc/trees/frame_sequence_tracker_unittest.cc deleted file mode 100644 index 1de4c9c38a9..00000000000 --- a/chromium/cc/trees/frame_sequence_tracker_unittest.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2019 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_sequence_tracker.h" - -#include "base/macros.h" -#include "components/viz/common/frame_sinks/begin_frame_args.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -class FrameSequenceTrackerTest; - -class FrameSequenceTrackerTest : public testing::Test { - public: - const uint32_t kImplDamage = 0x1; - const uint32_t kMainDamage = 0x2; - - FrameSequenceTrackerTest() - : tracker_( - collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll)) { - } - ~FrameSequenceTrackerTest() override = default; - - std::unique_ptr<FrameSequenceTracker> CreateNewTracker() { - return collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll); - } - - viz::BeginFrameArgs CreateBeginFrameArgs(uint64_t source_id, - uint64_t sequence_number) { - auto now = base::TimeTicks::Now(); - auto interval = base::TimeDelta::FromMilliseconds(16); - auto deadline = now + interval; - return viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id, - sequence_number, now, deadline, interval, - viz::BeginFrameArgs::NORMAL); - } - - void StartImplAndMainFrames(const viz::BeginFrameArgs& args) { - collection_.NotifyBeginImplFrame(args); - collection_.NotifyBeginMainFrame(args); - } - - uint32_t DispatchCompleteFrame(const viz::BeginFrameArgs& args, - uint32_t damage_type) { - StartImplAndMainFrames(args); - - if (damage_type & kImplDamage) { - if (!(damage_type & kMainDamage)) { - collection_.NotifyMainFrameCausedNoDamage(args); - } - uint32_t frame_token = NextFrameToken(); - collection_.NotifySubmitFrame(frame_token, viz::BeginFrameAck(args, true), - args); - return frame_token; - } else { - collection_.NotifyImplFrameCausedNoDamage( - viz::BeginFrameAck(args, false)); - collection_.NotifyMainFrameCausedNoDamage(args); - } - return 0; - } - - uint32_t NextFrameToken() { - static uint32_t frame_token = 0; - return ++frame_token; - } - - protected: - FrameSequenceTrackerCollection collection_; - - std::unique_ptr<FrameSequenceTracker> tracker_; -}; - -// Tests that the tracker works correctly when the source-id for the -// begin-frames change. -TEST_F(FrameSequenceTrackerTest, SourceIdChangeDuringSequence) { - const uint64_t source_1 = 1; - uint64_t sequence_1 = 0; - - // Dispatch some frames, both causing damage to impl/main, and both impl and - // main providing damage to the frame. - auto args_1 = CreateBeginFrameArgs(source_1, ++sequence_1); - DispatchCompleteFrame(args_1, kImplDamage | kMainDamage); - args_1 = CreateBeginFrameArgs(source_1, ++sequence_1); - DispatchCompleteFrame(args_1, kImplDamage | kMainDamage); - - // Start a new tracker. - auto tracker = CreateNewTracker(); - - // Change the source-id, and start an impl frame. This time, the main-frame - // does not provide any damage. - const uint64_t source_2 = 2; - uint64_t sequence_2 = 0; - auto args_2 = CreateBeginFrameArgs(source_2, ++sequence_2); - collection_.NotifyBeginImplFrame(args_2); - collection_.NotifyBeginMainFrame(args_2); - collection_.NotifyMainFrameCausedNoDamage(args_2); - // Since the main-frame did not have any new damage from the latest - // BeginFrameArgs, the submit-frame will carry the previous BeginFrameArgs - // (from source_1); - collection_.NotifySubmitFrame(NextFrameToken(), - viz::BeginFrameAck(args_2, true), args_1); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h index 68b9734737a..9753aca1bb6 100644 --- a/chromium/cc/trees/layer_tree_frame_sink.h +++ b/chromium/cc/trees/layer_tree_frame_sink.h @@ -132,10 +132,6 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter, const viz::SharedBitmapId& id) override = 0; void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0; - // Ensure next CompositorFrame is submitted to a new surface. Only used when - // surface synchronization is off. - virtual void ForceAllocateNewId() {} - protected: class ContextLostForwarder; diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 5270f43d422..1fab49e82ec 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -566,6 +566,10 @@ LayerTreeHost::DeferMainFrameUpdate() { return std::make_unique<ScopedDeferMainFrameUpdate>(this); } +void LayerTreeHost::OnDeferMainFrameUpdatesChanged(bool defer_status) { + client_->OnDeferMainFrameUpdatesChanged(defer_status); +} + void LayerTreeHost::StartDeferringCommits(base::TimeDelta timeout) { proxy_->StartDeferringCommits(timeout); } @@ -574,6 +578,10 @@ void LayerTreeHost::StopDeferringCommits(PaintHoldingCommitTrigger trigger) { proxy_->StopDeferringCommits(trigger); } +void LayerTreeHost::OnDeferCommitsChanged(bool defer_status) { + client_->OnDeferCommitsChanged(defer_status); +} + DISABLE_CFI_PERF void LayerTreeHost::SetNeedsAnimate() { proxy_->SetNeedsAnimate(); @@ -789,24 +797,17 @@ bool LayerTreeHost::DoUpdateLayers() { UpdateHudLayer(debug_state_.ShowHudInfo()); - // The non-layer-list mode is used when blink provides cc with a layer tree - // and cc needs to compute property trees from that. - // In layer lists mode, blink sends cc property trees directly so they do not - // need to be built here. Layer lists mode is used by BlinkGenPropertyTrees - // and CompositeAfterPaint. + // In layer lists mode, the cc property trees are built directly and do not + // need to be built here. if (!IsUsingLayerLists()) { TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees"); - Layer* root_scroll = - PropertyTreeBuilder::FindFirstScrollableLayer(root_layer_.get()); Layer* page_scale_layer = viewport_layers_.page_scale.get(); - if (!page_scale_layer && root_scroll) - page_scale_layer = root_scroll->parent(); gfx::Transform identity_transform; PropertyTreeBuilder::BuildPropertyTrees( root_layer_.get(), page_scale_layer, inner_viewport_scroll_layer(), outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), elastic_overscroll_, page_scale_factor_, device_scale_factor_, - gfx::Rect(device_viewport_size_), identity_transform, &property_trees_); + device_viewport_rect_, identity_transform, &property_trees_); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerTreeHost::UpdateLayers_BuiltPropertyTrees", TRACE_EVENT_SCOPE_THREAD, "property_trees", @@ -1180,8 +1181,8 @@ void LayerTreeHost::SetEventListenerProperties( SetNeedsCommit(); } -void LayerTreeHost::SetViewportSizeAndScale( - const gfx::Size& device_viewport_size, +void LayerTreeHost::SetViewportRectAndScale( + const gfx::Rect& device_viewport_rect, float device_scale_factor, const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent) { @@ -1190,10 +1191,10 @@ void LayerTreeHost::SetViewportSizeAndScale( SetLocalSurfaceIdAllocationFromParent( local_surface_id_allocation_from_parent); - bool device_viewport_size_changed = false; - if (device_viewport_size_ != device_viewport_size) { - device_viewport_size_ = device_viewport_size; - device_viewport_size_changed = true; + bool device_viewport_rect_changed = false; + if (device_viewport_rect_ != device_viewport_rect) { + device_viewport_rect_ = device_viewport_rect; + device_viewport_rect_changed = true; } bool painted_device_scale_factor_changed = false; bool device_scale_factor_changed = false; @@ -1211,7 +1212,7 @@ void LayerTreeHost::SetViewportSizeAndScale( } } - if (device_viewport_size_changed || painted_device_scale_factor_changed || + if (device_viewport_rect_changed || painted_device_scale_factor_changed || device_scale_factor_changed) { SetPropertyTreesNeedRebuild(); SetNeedsCommit(); @@ -1225,7 +1226,7 @@ void LayerTreeHost::SetViewportSizeAndScale( << new_local_surface_id_request_ << " !valid_parent_id " << !local_surface_id_allocation_from_parent_.IsValid() << ". Changed state: device_viewport_size " - << device_viewport_size_changed << " painted_device_scale_factor " + << device_viewport_rect_changed << " painted_device_scale_factor " << painted_device_scale_factor_changed << " device_scale_factor " << device_scale_factor_changed << " cached LSId " << previous_local_surface_id.ToString() << " new LSId " @@ -1239,8 +1240,6 @@ void LayerTreeHost::SetViewportVisibleRect(const gfx::Rect& visible_rect) { return; viewport_visible_rect_ = visible_rect; - SetPropertyTreesNeedRebuild(); - SetNeedsCommit(); } void LayerTreeHost::SetBrowserControlsHeight(float top_height, @@ -1513,7 +1512,7 @@ void LayerTreeHost::UpdateHudLayer(bool show_hud_info) { hud_layer_ = HeadsUpDisplayLayer::Create(); if (root_layer_.get() && !hud_layer_->parent()) root_layer_->AddChild(hud_layer_); - hud_layer_->UpdateLocationAndSize(device_viewport_size_, + hud_layer_->UpdateLocationAndSize(device_viewport_rect_.size(), device_scale_factor_); } else if (hud_layer_.get()) { hud_layer_->RemoveFromParent(); @@ -1561,19 +1560,21 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { ids.overscroll_elasticity_element_id = viewport_layers_.overscroll_elasticity_element_id; } - ids.page_scale = viewport_layers_.page_scale->id(); - if (viewport_layers_.inner_viewport_container) + if (viewport_layers_.page_scale) { + ids.page_scale = viewport_layers_.page_scale->id(); + } + if (viewport_layers_.inner_viewport_container) { ids.inner_viewport_container = viewport_layers_.inner_viewport_container->id(); - if (viewport_layers_.outer_viewport_container) + } + if (viewport_layers_.outer_viewport_container) { ids.outer_viewport_container = viewport_layers_.outer_viewport_container->id(); + } ids.inner_viewport_scroll = viewport_layers_.inner_viewport_scroll->id(); if (viewport_layers_.outer_viewport_scroll) ids.outer_viewport_scroll = viewport_layers_.outer_viewport_scroll->id(); tree_impl->SetViewportLayersFromIds(ids); - DCHECK(IsUsingLayerLists() || viewport_layers_.inner_viewport_scroll - ->IsContainerForFixedPositionLayers()); } else { tree_impl->ClearViewportLayers(); } @@ -1600,8 +1601,7 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_); tree_impl->SetDeviceScaleFactor(device_scale_factor_); - tree_impl->SetDeviceViewportSize(device_viewport_size_); - tree_impl->SetViewportVisibleRect(viewport_visible_rect_); + tree_impl->SetDeviceViewportRect(device_viewport_rect_); if (TakeNewLocalSurfaceIdRequest()) tree_impl->RequestNewLocalSurfaceId(); @@ -1619,6 +1619,15 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->RequestForceSendMetadata(); tree_impl->set_has_ever_been_drawn(false); + + // TODO(ericrk): The viewport changes caused by |top_controls_shown_ratio_| + // changes should propagate back to the main tree. This does not currently + // happen, so we must force the impl tree to update its viewports if + // |top_controls_shown_ratio_| is greater than 0.0f and less than 1.0f + // (partially shown). crbug.com/875943 + if (top_controls_shown_ratio_ > 0.0f && top_controls_shown_ratio_ < 1.0f) { + tree_impl->UpdateViewportContainerSizes(); + } } void LayerTreeHost::PushSurfaceRangesTo(LayerTreeImpl* tree_impl) { @@ -1689,7 +1698,7 @@ void LayerTreeHost::BuildPropertyTreesForTesting() { root_layer(), page_scale_layer(), inner_viewport_scroll_layer(), outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), elastic_overscroll(), page_scale_factor(), device_scale_factor(), - gfx::Rect(device_viewport_size()), identity_transform, property_trees()); + device_viewport_rect(), identity_transform, property_trees()); } bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id, diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index 54000cfece0..0c3405f8cb7 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -47,7 +47,6 @@ #include "components/viz/common/resources/resource_format.h" #include "components/viz/common/surfaces/local_surface_id_allocation.h" #include "services/metrics/public/cpp/ukm_source_id.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" namespace gfx { @@ -239,6 +238,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // StopDeferringCommits is called. std::unique_ptr<ScopedDeferMainFrameUpdate> DeferMainFrameUpdate(); + // Notification that the proxy started or stopped deferring main frame updates + void OnDeferMainFrameUpdatesChanged(bool); + // Prevents the proxy from committing the layer tree to the compositor, // while still allowing main frame lifecycle updates. |timeout| // is the interval after which commits will restart if nothing stops @@ -249,6 +251,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Stop deferring commits immediately. void StopDeferringCommits(PaintHoldingCommitTrigger); + // Notification that the proxy started or stopped deferring commits. + void OnDeferCommitsChanged(bool); + // Returns whether there are any outstanding ScopedDeferMainFrameUpdate, // though commits may be deferred also when the local_surface_id_from_parent() // is not valid. @@ -387,7 +392,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { return event_listener_properties_[static_cast<size_t>(event_class)]; } - void SetViewportSizeAndScale(const gfx::Size& device_viewport_size, + void SetViewportRectAndScale(const gfx::Rect& device_viewport_rect, float device_scale_factor, const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent); @@ -396,7 +401,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { gfx::Rect viewport_visible_rect() const { return viewport_visible_rect_; } - gfx::Size device_viewport_size() const { return device_viewport_size_; } + gfx::Rect device_viewport_rect() const { return device_viewport_rect_; } void SetBrowserControlsHeight(float top_height, float bottom_height, @@ -652,6 +657,11 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { float maximum_scale, float starting_scale) override; + void OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value) override {} + void ScrollOffsetAnimationFinished() override {} gfx::ScrollOffset GetScrollOffsetForAnimation( ElementId element_id) const override; @@ -814,7 +824,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { LayerSelection selection_; - gfx::Size device_viewport_size_; + gfx::Rect device_viewport_rect_; gfx::Rect viewport_visible_rect_; diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index f48af6c6d1e..7f424be64e6 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -95,6 +95,12 @@ class LayerTreeHostClient { virtual void WillUpdateLayers() = 0; virtual void DidUpdateLayers() = 0; + // Notification that the proxy started or stopped deferring main frame updates + virtual void OnDeferMainFrameUpdatesChanged(bool) = 0; + + // Notification that the proxy started or stopped deferring commits. + virtual void OnDeferCommitsChanged(bool) = 0; + // Visual frame-based updates to the state of the LayerTreeHost are expected // to happen only in calls to LayerTreeHostClient::UpdateLayerTreeHost, which // should mutate/invalidate the layer tree or other page parameters as diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index 7ea7995ee11..e91bd95593a 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -30,48 +30,45 @@ namespace cc { LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, float page_scale_factor, const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - TransformNode* page_scale_transform_node) + const Layer* outer_viewport_scroll_layer) : root_layer(root_layer), - device_viewport_size(device_viewport_size), + device_viewport_rect(device_viewport_rect), device_transform(device_transform), device_scale_factor(device_scale_factor), page_scale_factor(page_scale_factor), page_scale_layer(page_scale_layer), inner_viewport_scroll_layer(inner_viewport_scroll_layer), - outer_viewport_scroll_layer(outer_viewport_scroll_layer), - page_scale_transform_node(page_scale_transform_node) {} + outer_viewport_scroll_layer(outer_viewport_scroll_layer) {} LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform) : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_size, + device_viewport_rect, device_transform, 1.f, 1.f, nullptr, nullptr, - nullptr, nullptr) {} LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size) + const gfx::Rect& device_viewport_rect) : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_size, + device_viewport_rect, gfx::Transform()) {} LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, float page_scale_factor, @@ -85,7 +82,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( PropertyTrees* property_trees, TransformNode* page_scale_transform_node) : root_layer(root_layer), - device_viewport_size(device_viewport_size), + device_viewport_rect(device_viewport_rect), device_transform(device_transform), device_scale_factor(device_scale_factor), page_scale_factor(page_scale_factor), @@ -101,12 +98,12 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputs(root_layer, - device_viewport_size, + device_viewport_rect, device_transform, device_scale_factor, 1.f, @@ -125,32 +122,32 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_size, + device_viewport_rect, device_transform, 1.f, render_surface_list) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_size, + device_viewport_rect, gfx::Transform(), 1.f, render_surface_list) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, float device_scale_factor, RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_size, + device_viewport_rect, gfx::Transform(), device_scale_factor, render_surface_list) {} @@ -517,9 +514,10 @@ static void RecordRenderSurfaceReasonsForTracing( } } -void CalculateDrawPropertiesInternal( +static void CalculateDrawPropertiesInternal( LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs, - PropertyTreeOption property_tree_option) { + PropertyTreeOption property_tree_option, + LayerImplList* output_update_layer_list) { inputs->render_surface_list->clear(); LayerImplList visible_layer_list; @@ -534,18 +532,10 @@ void CalculateDrawPropertiesInternal( inputs->outer_viewport_scroll_layer, inputs->elastic_overscroll_element_id, inputs->elastic_overscroll, inputs->page_scale_factor, inputs->device_scale_factor, - gfx::Rect(inputs->device_viewport_size), inputs->device_transform, + inputs->device_viewport_rect, inputs->device_transform, inputs->property_trees); draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( inputs->root_layer, inputs->property_trees); - - // Property trees are normally constructed on the main thread and - // passed to compositor thread. Source to parent updates on them are not - // allowed in the compositor thread. Some tests build them on the - // compositor thread, so we need to explicitly disallow source to parent - // updates when they are built on compositor thread. - inputs->property_trees->transform_tree - .set_source_to_parent_updates_allowed(false); break; } case DONT_BUILD_PROPERTY_TREES: { @@ -554,21 +544,6 @@ void CalculateDrawPropertiesInternal( // trying to update property trees whenever these values change, we // update property trees before using them. - // 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. - // TODO(bokan): Need to implement this behavior for - // BlinkGeneratedPropertyTrees. i.e. (no page scale layer). Ideally by - // not baking these into the page scale layer. - bool combine_dsf_and_psf = inputs->page_scale_layer == inputs->root_layer; - float device_scale_factor_for_page_scale_node = 1.f; - gfx::Transform device_transform_for_page_scale_node; - if (combine_dsf_and_psf) { - DCHECK( - !inputs->root_layer->layer_tree_impl()->settings().use_layer_lists); - device_transform_for_page_scale_node = inputs->device_transform; - device_scale_factor_for_page_scale_node = inputs->device_scale_factor; - } - // We should never be setting a non-unit page scale factor on an oopif // subframe ... if we attempt this log it and fail. // TODO(wjmaclean): Remove as part of conditions for closing the bug. @@ -586,10 +561,10 @@ void CalculateDrawPropertiesInternal( NOTREACHED(); } + DCHECK_NE(inputs->page_scale_layer, inputs->root_layer); draw_property_utils::UpdatePageScaleFactor( inputs->property_trees, inputs->page_scale_transform_node, - inputs->page_scale_factor, device_scale_factor_for_page_scale_node, - device_transform_for_page_scale_node); + inputs->page_scale_factor); draw_property_utils::UpdateElasticOverscroll( inputs->property_trees, inputs->elastic_overscroll_element_id, inputs->elastic_overscroll); @@ -597,12 +572,9 @@ void CalculateDrawPropertiesInternal( // by both trees. PropertyTrees* property_trees = inputs->property_trees; property_trees->clip_tree.SetViewportClip( - gfx::RectF(gfx::SizeF(inputs->device_viewport_size))); - float page_scale_factor_for_root = - combine_dsf_and_psf ? inputs->page_scale_factor : 1.f; - property_trees->transform_tree.SetRootTransformsAndScales( - inputs->device_scale_factor, page_scale_factor_for_root, - inputs->device_transform); + gfx::RectF(inputs->device_viewport_rect)); + property_trees->transform_tree.SetRootScaleAndTransform( + inputs->device_scale_factor, inputs->device_transform); draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( inputs->root_layer, inputs->property_trees); break; @@ -637,6 +609,9 @@ void CalculateDrawPropertiesInternal( // CalculateDrawProperties. DCHECK(inputs->property_trees->effect_tree.GetRenderSurface( EffectTree::kContentsRootNodeId)); + + if (output_update_layer_list) + *output_update_layer_list = std::move(visible_layer_list); } void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( @@ -644,37 +619,68 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( LayerList update_layer_list; PropertyTrees* property_trees = inputs->root_layer->layer_tree_host()->property_trees(); - gfx::Vector2dF elastic_overscroll; - PropertyTreeBuilder::BuildPropertyTrees( - inputs->root_layer, inputs->page_scale_layer, - inputs->inner_viewport_scroll_layer, inputs->outer_viewport_scroll_layer, - ElementId(), elastic_overscroll, inputs->page_scale_factor, - inputs->device_scale_factor, gfx::Rect(inputs->device_viewport_size), - inputs->device_transform, property_trees); + if (inputs->root_layer->layer_tree_host()->IsUsingLayerLists()) { + // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all + // unnecessary setting of the flag in layer list mode. + property_trees->needs_rebuild = false; + } else { + gfx::Vector2dF elastic_overscroll; + PropertyTreeBuilder::BuildPropertyTrees( + inputs->root_layer, inputs->page_scale_layer, + inputs->inner_viewport_scroll_layer, + inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll, + inputs->page_scale_factor, inputs->device_scale_factor, + inputs->device_viewport_rect, inputs->device_transform, property_trees); + } draw_property_utils::UpdatePropertyTrees( inputs->root_layer->layer_tree_host(), property_trees); draw_property_utils::FindLayersThatNeedUpdates( inputs->root_layer->layer_tree_host(), property_trees, &update_layer_list); + + if (inputs->update_layer_list) + *inputs->update_layer_list = std::move(update_layer_list); } void LayerTreeHostCommon::CalculateDrawProperties( CalcDrawPropsImplInputs* inputs) { - CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES); + CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES, nullptr); +} + +void LayerTreeHostCommon::PrepareForUpdateDrawPropertiesForTesting( + LayerTreeImpl* layer_tree_impl) { + if (layer_tree_impl->settings().use_layer_lists) { + // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all + // unnecessary setting of the flag in layer list mode. + auto* property_trees = layer_tree_impl->property_trees(); + property_trees->needs_rebuild = false; + // The following are needed for tests that modify impl-side property trees. + // In production code impl-side property trees are pushed from the main + // thread and the following are done in other ways. + std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces; + property_trees->effect_tree.TakeRenderSurfaces(&old_render_surfaces); + property_trees->effect_tree.CreateOrReuseRenderSurfaces( + &old_render_surfaces, layer_tree_impl); + property_trees->ResetCachedData(); + } } void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( CalcDrawPropsImplInputsForTesting* inputs) { - CalculateDrawPropertiesInternal(inputs, inputs->property_trees->needs_rebuild - ? BUILD_PROPERTY_TREES - : DONT_BUILD_PROPERTY_TREES); + PrepareForUpdateDrawPropertiesForTesting( + inputs->root_layer->layer_tree_impl()); + CalculateDrawPropertiesInternal(inputs, + inputs->property_trees->needs_rebuild + ? BUILD_PROPERTY_TREES + : DONT_BUILD_PROPERTY_TREES, + inputs->update_layer_list); } -PropertyTrees* GetPropertyTrees(Layer* layer) { +PropertyTrees* GetPropertyTrees(const Layer* layer) { return layer->layer_tree_host()->property_trees(); } -PropertyTrees* GetPropertyTrees(LayerImpl* layer) { +PropertyTrees* GetPropertyTrees(const LayerImpl* layer) { return layer->layer_tree_impl()->property_trees(); } diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index 07c0bc586c2..6c9dfd5f065 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -37,34 +37,34 @@ class CC_EXPORT LayerTreeHostCommon { struct CC_EXPORT CalcDrawPropsMainInputsForTesting { public: CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, float page_scale_factor, const Layer* page_scale_layer, const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - TransformNode* page_scale_transform_node); + const Layer* outer_viewport_scroll_layer); CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform); CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Size& device_viewport_size); + const gfx::Rect& device_viewport_rect); Layer* root_layer; - gfx::Size device_viewport_size; + gfx::Rect device_viewport_rect; gfx::Transform device_transform; float device_scale_factor; float page_scale_factor; const Layer* page_scale_layer; const Layer* inner_viewport_scroll_layer; const Layer* outer_viewport_scroll_layer; - TransformNode* page_scale_transform_node; + // If not null, accepts layers output from FindLayersThatNeedUpdates(). + LayerList* update_layer_list = nullptr; }; struct CC_EXPORT CalcDrawPropsImplInputs { public: CalcDrawPropsImplInputs(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, float page_scale_factor, @@ -79,7 +79,7 @@ class CC_EXPORT LayerTreeHostCommon { TransformNode* page_scale_transform_node); LayerImpl* root_layer; - gfx::Size device_viewport_size; + gfx::Rect device_viewport_rect; gfx::Transform device_transform; float device_scale_factor; float page_scale_factor; @@ -97,21 +97,24 @@ class CC_EXPORT LayerTreeHostCommon { struct CC_EXPORT CalcDrawPropsImplInputsForTesting : public CalcDrawPropsImplInputs { CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, float device_scale_factor, RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, const gfx::Transform& device_transform, RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Size& device_viewport_size, + const gfx::Rect& device_viewport_rect, float device_scale_factor, RenderSurfaceList* render_surface_list); + + // If not null, accepts layers output from FindLayersThatNeedUpdates(). + LayerImplList* update_layer_list = nullptr; }; static int CalculateLayerJitter(LayerImpl* scrolling_layer); @@ -119,6 +122,9 @@ class CC_EXPORT LayerTreeHostCommon { CalcDrawPropsMainInputsForTesting* inputs); static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs); + + // TODO(wangxianzhu): Move these functions into testing classes. + static void PrepareForUpdateDrawPropertiesForTesting(LayerTreeImpl*); static void CalculateDrawPropertiesForTesting( CalcDrawPropsImplInputsForTesting* inputs); @@ -218,8 +224,8 @@ void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeImpl* tree_impl, } } -CC_EXPORT PropertyTrees* GetPropertyTrees(Layer* layer); -CC_EXPORT PropertyTrees* GetPropertyTrees(LayerImpl* layer); +CC_EXPORT PropertyTrees* GetPropertyTrees(const Layer* layer); +CC_EXPORT PropertyTrees* GetPropertyTrees(const LayerImpl* layer); } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc index 4cb8bc9e760..14283d082f6 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -49,7 +49,7 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { void SetupTree() override { gfx::Size viewport = gfx::Size(720, 1038); - layer_tree_host()->SetViewportSizeAndScale(viewport, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport), 1.f, viz::LocalSurfaceIdAllocation()); scoped_refptr<Layer> root = ParseTreeFromJson(json_, &content_layer_client_); @@ -98,9 +98,8 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { LayerTreeHostImpl* host_impl) { RenderSurfaceList update_list; LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - active_tree->root_layer_for_testing(), - active_tree->GetDeviceViewport().size(), host_impl->DrawTransform(), - active_tree->device_scale_factor(), + active_tree->root_layer_for_testing(), active_tree->GetDeviceViewport(), + host_impl->DrawTransform(), active_tree->device_scale_factor(), active_tree->current_page_scale_factor(), active_tree->InnerViewportContainerLayer(), active_tree->InnerViewportScrollLayer(), diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index 12652e57e9f..6a511ff0898 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -27,7 +27,8 @@ #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface_impl.h" -#include "cc/layers/texture_layer_impl.h" +#include "cc/layers/texture_layer.h" +#include "cc/layers/texture_layer_client.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -60,21 +61,13 @@ namespace cc { namespace { bool LayerSubtreeHasCopyRequest(Layer* layer) { - LayerTreeHost* host = layer->layer_tree_host(); - int index = layer->effect_tree_index(); - auto* node = host->property_trees()->effect_tree.Node(index); - return node->subtree_has_copy_request; + return GetEffectNode(layer)->subtree_has_copy_request; } -class VerifyTreeCalcsLayerTreeSettings : public LayerTreeSettings { - public: - VerifyTreeCalcsLayerTreeSettings() = default; -}; - class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { public: LayerTreeHostCommonTestBase() - : LayerTestCommon::LayerImplTest(VerifyTreeCalcsLayerTreeSettings()) {} + : LayerTestCommon::LayerImplTest(LayerListSettings()) {} explicit LayerTreeHostCommonTestBase(const LayerTreeSettings& settings) : LayerTestCommon::LayerImplTest(settings) {} @@ -104,190 +97,83 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { .starting_animation_scale; } - void ExecuteCalculateDrawProperties(Layer* root_layer, - float device_scale_factor, - float page_scale_factor, - Layer* page_scale_layer, - Layer* inner_viewport_scroll_layer, - Layer* outer_viewport_scroll_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, - root_layer->bounds().height() * device_scale_factor); - - root_layer->layer_tree_host()->SetViewportSizeAndScale( - device_viewport_size, device_scale_factor, - viz::LocalSurfaceIdAllocation()); + // Inherits the impl version from LayerImplTest. + using LayerImplTest::ExecuteCalculateDrawProperties; - // We are probably not testing what is intended if the root_layer bounds are - // empty. - DCHECK(!root_layer->bounds().IsEmpty()); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root_layer, device_viewport_size); - inputs.device_scale_factor = device_scale_factor; - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_layer = page_scale_layer; - inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer; - inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer; - if (page_scale_layer) { - PropertyTrees* property_trees = - root_layer->layer_tree_host()->property_trees(); - inputs.page_scale_transform_node = property_trees->transform_tree.Node( - page_scale_layer->transform_tree_index()); + // This is the main version. + void ExecuteCalculateDrawProperties(Layer* root_layer, + float device_scale_factor = 1.0f, + float page_scale_factor = 1.0f, + Layer* page_scale_layer = nullptr) { + if (!host()->IsUsingLayerLists()) { + if (device_scale_factor != host()->device_scale_factor() || + page_scale_factor != host()->page_scale_factor()) { + host()->property_trees()->needs_rebuild = true; + } } - 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) { - if (device_scale_factor != - root_layer->layer_tree_impl()->device_scale_factor()) - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - - root_layer->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor); EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f)); - - gfx::Size device_viewport_size = - gfx::Size(root_layer->bounds().width() * device_scale_factor, + gfx::Rect device_viewport_rect = + gfx::Rect(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - render_surface_list_impl_.reset(new RenderSurfaceList); + root_layer->layer_tree_host()->SetViewportRectAndScale( + device_viewport_rect, device_scale_factor, + viz::LocalSurfaceIdAllocation()); // We are probably not testing what is intended if the root_layer bounds are // empty. DCHECK(!root_layer->bounds().IsEmpty()); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, render_surface_list_impl_.get()); + LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( + root_layer, device_viewport_rect); inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = page_scale_layer; - inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer; - inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer; - if (page_scale_layer) { - PropertyTrees* property_trees = - root_layer->layer_tree_impl()->property_trees(); - inputs.page_scale_transform_node = property_trees->transform_tree.Node( - page_scale_layer->transform_tree_index()); - } - + inputs.update_layer_list = &update_layer_list_; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } - template <class LayerType> - void ExecuteCalculateDrawProperties(LayerType* root_layer) { - LayerType* page_scale_application_layer = nullptr; - LayerType* inner_viewport_scroll_layer = nullptr; - LayerType* outer_viewport_scroll_layer = nullptr; - ExecuteCalculateDrawProperties( - root_layer, 1.f, 1.f, page_scale_application_layer, - inner_viewport_scroll_layer, outer_viewport_scroll_layer); - } - - template <class LayerType> - void ExecuteCalculateDrawProperties(LayerType* root_layer, - float device_scale_factor) { - LayerType* page_scale_application_layer = nullptr; - LayerType* inner_viewport_scroll_layer = nullptr; - LayerType* outer_viewport_scroll_layer = nullptr; - ExecuteCalculateDrawProperties( - root_layer, device_scale_factor, 1.f, page_scale_application_layer, - inner_viewport_scroll_layer, outer_viewport_scroll_layer); + LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) { + return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr; } - - const LayerList* GetUpdateLayerList() { return &update_layer_list_; } - - void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(Layer* root_layer) { - DCHECK(root_layer->layer_tree_host()); - const Layer* page_scale_layer = - root_layer->layer_tree_host()->page_scale_layer(); - Layer* inner_viewport_scroll_layer = - root_layer->layer_tree_host()->inner_viewport_scroll_layer(); - Layer* outer_viewport_scroll_layer = - root_layer->layer_tree_host()->outer_viewport_scroll_layer(); - const ElementId overscroll_elasticity_element_id = - root_layer->layer_tree_host()->overscroll_elasticity_element_id(); - gfx::Vector2dF elastic_overscroll = - root_layer->layer_tree_host()->elastic_overscroll(); - float page_scale_factor = 1.f; - float device_scale_factor = 1.f; - gfx::Size device_viewport_size = - gfx::Size(root_layer->bounds().width() * device_scale_factor, - root_layer->bounds().height() * device_scale_factor); - PropertyTrees* property_trees = - root_layer->layer_tree_host()->property_trees(); - update_layer_list_.clear(); - PropertyTreeBuilder::BuildPropertyTrees( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_scale_factor, - gfx::Rect(device_viewport_size), gfx::Transform(), property_trees); - draw_property_utils::UpdatePropertyTrees(root_layer->layer_tree_host(), - property_trees); - draw_property_utils::FindLayersThatNeedUpdates( - root_layer->layer_tree_host(), property_trees, &update_layer_list_); + LayerImpl* PendingImplOf(const scoped_refptr<Layer>& layer) { + return layer ? host_impl()->pending_tree()->LayerById(layer->id()) + : nullptr; } - - void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList( - LayerImpl* root_layer) { - DCHECK(root_layer->layer_tree_impl()); - - 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(); - const ElementId overscroll_elasticity_element_id = - root_layer->layer_tree_impl()->OverscrollElasticityElementId(); - gfx::Vector2dF elastic_overscroll = - root_layer->layer_tree_impl()->elastic_overscroll()->Current( - root_layer->layer_tree_impl()->IsActiveTree()); - float page_scale_factor = 1.f; - float device_scale_factor = 1.f; - gfx::Size device_viewport_size = - gfx::Size(root_layer->bounds().width() * device_scale_factor, - root_layer->bounds().height() * device_scale_factor); - update_layer_impl_list_.reset(new LayerImplList); - root_layer->layer_tree_impl()->BuildLayerListForTesting(); - PropertyTrees* property_trees = - root_layer->layer_tree_impl()->property_trees(); - PropertyTreeBuilder::BuildPropertyTrees( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_scale_factor, - gfx::Rect(device_viewport_size), gfx::Transform(), property_trees); - draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(root_layer, - property_trees); - draw_property_utils::FindLayersThatNeedUpdates( - root_layer->layer_tree_impl(), property_trees, - update_layer_impl_list_.get()); - draw_property_utils::ComputeDrawPropertiesOfVisibleLayers( - update_layer_impl_list(), property_trees); + RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) { + return GetRenderSurface(ImplOf(layer)); } - void ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales( - LayerImpl* root_layer) { - gfx::Size device_viewport_size = - gfx::Size(root_layer->bounds().width(), root_layer->bounds().height()); - render_surface_list_impl_.reset(new RenderSurfaceList); - - DCHECK(!root_layer->bounds().IsEmpty()); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, render_surface_list_impl_.get()); - - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + // Updates main thread draw properties, commits main thread tree to + // impl-side pending tree, and updates pending tree draw properties. + void Commit(float device_scale_factor = 1.0f, + float page_scale_factor = 1.0f, + Layer* page_scale_layer = nullptr) { + ExecuteCalculateDrawProperties(host()->root_layer(), device_scale_factor, + page_scale_factor, page_scale_layer); + if (!host_impl()->pending_tree()) + host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + // TODO(https://crbug.com/939968) This call should be handled by + // FakeLayerTreeHost instead of manually pushing the properties from the + // layer tree host to the pending tree. + host()->PushLayerTreePropertiesTo(host_impl()->pending_tree()); + ExecuteCalculateDrawProperties( + host_impl()->pending_tree()->root_layer_for_testing(), + device_scale_factor, gfx::Transform(), page_scale_factor, + PendingImplOf(page_scale_layer)); } - bool UpdateLayerImplListContains(int id) const { - for (auto* layer : *update_layer_impl_list_) { - if (layer->id() == id) - return true; - } - return false; + // Calls Commit(), then activates the pending tree, and updates active tree + // draw properties. + void CommitAndActivate(float device_scale_factor = 1.0f, + float page_scale_factor = 1.0f, + Layer* page_scale_layer = nullptr) { + Commit(device_scale_factor, page_scale_factor, page_scale_layer); + host_impl()->ActivateSyncTree(); + ExecuteCalculateDrawProperties(root_layer_for_testing(), + device_scale_factor, gfx::Transform(), + page_scale_factor, ImplOf(page_scale_layer)); } bool UpdateLayerListContains(int id) const { @@ -298,82 +184,81 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { return false; } - const RenderSurfaceList* render_surface_list_impl() const { - return render_surface_list_impl_.get(); - } - const LayerImplList* update_layer_impl_list() const { - return update_layer_impl_list_.get(); - } const LayerList& update_layer_list() const { return update_layer_list_; } - bool VerifyLayerInList(scoped_refptr<Layer> layer, - const LayerList* layer_list) { - return base::Contains(*layer_list, layer); - } - private: - std::unique_ptr<RenderSurfaceList> render_surface_list_impl_; LayerList update_layer_list_; - std::unique_ptr<LayerImplList> update_layer_impl_list_; }; class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase, public testing::Test {}; -class LayerTreeHostCommonScalingTest : public LayerTreeHostCommonTestBase, - public testing::Test { +class LayerTreeHostCommonTestWithLayerTree : public LayerTreeHostCommonTestBase, + public testing::Test { public: - LayerTreeHostCommonScalingTest() - : LayerTreeHostCommonTestBase(VerifyTreeCalcsLayerTreeSettings()) {} + LayerTreeHostCommonTestWithLayerTree() + : LayerTreeHostCommonTestBase(LayerTreeSettings()) {} }; class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { public: LayerTreeHostCommonDrawRectsTest() : LayerTreeHostCommonTest() {} + void SetUp() override { + LayerImpl* root = root_layer_for_testing(); + root->SetDrawsContent(true); + root->SetBounds(gfx::Size(500, 500)); + SetupRootProperties(root); + } + LayerImpl* TestVisibleRectAndDrawableContentRect( const gfx::Rect& target_rect, const gfx::Transform& layer_transform, const gfx::Rect& layer_rect) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* target = AddChild<LayerImpl>(root); - LayerImpl* drawing_layer = AddChild<LayerImpl>(target); + LayerImpl* target = AddLayer<LayerImpl>(); + LayerImpl* drawing_layer = AddLayer<LayerImpl>(); - root->SetDrawsContent(true); target->SetDrawsContent(true); target->SetMasksToBounds(true); drawing_layer->SetDrawsContent(true); - root->SetBounds(gfx::Size(500, 500)); - root->test_properties()->force_render_surface = true; - target->test_properties()->position = gfx::PointF(target_rect.origin()); target->SetBounds(target_rect.size()); - target->test_properties()->force_render_surface = true; - drawing_layer->test_properties()->transform = layer_transform; - drawing_layer->test_properties()->position = - gfx::PointF(layer_rect.origin()); drawing_layer->SetBounds(layer_rect.size()); - drawing_layer->test_properties()->should_flatten_transform = false; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + CopyProperties(root, target); + CreateTransformNode(target).post_translation = + gfx::PointF(target_rect.origin()).OffsetFromOrigin(); + CreateEffectNode(target).render_surface_reason = RenderSurfaceReason::kTest; + CreateClipNode(target); + CopyProperties(target, drawing_layer); + auto& drawing_layer_transform_node = CreateTransformNode(drawing_layer); + drawing_layer_transform_node.local = layer_transform; + drawing_layer_transform_node.post_translation = + gfx::PointF(layer_rect.origin()).OffsetFromOrigin(); + drawing_layer_transform_node.flattens_inherited_transform = false; + ExecuteCalculateDrawProperties(root); return drawing_layer; } }; +// Sanity check: For layers positioned at zero, with zero size, +// and with identity transforms, then the draw transform, +// screen space transform, and the hierarchy passed on to children +// layers should also be identity transforms. TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { - // Sanity check: For layers positioned at zero, with zero size, - // and with identity transforms, then the draw transform, - // screen space transform, and the hierarchy passed on to children - // layers should also be identity transforms. - LayerImpl* parent = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); + SetupRootProperties(parent); + CopyProperties(parent, child); + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(parent); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); @@ -385,30 +270,30 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { grand_child->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, EffectTreeTransformIdTest) { +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, EffectTreeTransformIdTest) { // Tests that effect tree node gets a valid transform id when a layer // has opacity but doesn't create a render surface. - LayerImpl* parent = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(parent); - child->SetDrawsContent(true); + auto parent = Layer::Create(); + host()->SetRootLayer(parent); + auto child = Layer::Create(); + parent->AddChild(child); + child->SetIsDrawable(true); parent->SetBounds(gfx::Size(100, 100)); - child->test_properties()->position = gfx::PointF(10, 10); + child->SetPosition(gfx::PointF(10, 10)); child->SetBounds(gfx::Size(100, 100)); - child->test_properties()->opacity = 0.f; - ExecuteCalculateDrawProperties(parent); - EffectTree& effect_tree = - parent->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = effect_tree.Node(child->effect_tree_index()); - const int transform_tree_size = parent->layer_tree_impl() - ->property_trees() - ->transform_tree.next_available_id(); + child->SetOpacity(0.f); + ExecuteCalculateDrawProperties(parent.get()); + EffectNode* node = GetEffectNode(child.get()); + const int transform_tree_size = + GetPropertyTrees(parent.get())->transform_tree.next_available_id(); EXPECT_LT(node->transform_id, transform_tree_size); } TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* layer = AddChild<LayerImpl>(root); + LayerImpl* layer = AddLayer<LayerImpl>(); TransformTree& transform_tree = host_impl()->active_tree()->property_trees()->transform_tree; @@ -416,6 +301,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { host_impl()->active_tree()->property_trees()->effect_tree; root->SetBounds(gfx::Size(1, 2)); + SetupRootProperties(root); + CopyProperties(root, layer); // Case 1: Setting the bounds of the layer should not affect either the draw // transform or the screenspace transform. @@ -430,9 +317,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // Case 2: The anchor point by itself (without a layer transform) should have // no effect on the transforms. - layer->test_properties()->transform_origin = gfx::Point3F(2.5f, 3.0f, 0.f); + CreateTransformNode(layer).origin = gfx::Point3F(2.5f, 3.0f, 0.f); layer->SetBounds(gfx::Size(10, 12)); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), @@ -445,8 +331,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // screen space transform. gfx::Transform position_transform; position_transform.Translate(0.f, 1.2f); - layer->test_properties()->position = gfx::PointF(0.f, 1.2f); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( position_transform, @@ -460,10 +345,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // scale transform, because scale and translation are not commutative. gfx::Transform layer_transform; layer_transform.Scale3d(2.0, 2.0, 1.0); - layer->test_properties()->transform = layer_transform; - layer->test_properties()->transform_origin = gfx::Point3F(); - layer->test_properties()->position = gfx::PointF(); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetTransform(layer, layer_transform); + SetTransformOrigin(layer, gfx::Point3F()); + SetPostTranslation(layer, gfx::Vector2dF()); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( layer_transform, @@ -477,8 +361,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { translation_to_anchor.Translate(5.0, 0.0); gfx::Transform expected_result = translation_to_anchor * layer_transform * Inverse(translation_to_anchor); - layer->test_properties()->transform_origin = gfx::Point3F(5.f, 0.f, 0.f); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f)); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, @@ -492,8 +375,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // it is still worth testing to detect accidental regressions. expected_result = position_transform * translation_to_anchor * layer_transform * Inverse(translation_to_anchor); - layer->test_properties()->position = gfx::PointF(0.f, 1.2f); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, @@ -512,19 +394,11 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { float page_scale = 0.888f; const float kDeviceScale = 1.666f; - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> sublayer_scoped_ptr( - LayerImpl::Create(host_impl.active_tree(), 1)); - LayerImpl* sublayer = sublayer_scoped_ptr.get(); + LayerImpl* sublayer = AddLayer<LayerImpl>(); sublayer->SetDrawsContent(true); sublayer->SetBounds(gfx::Size(500, 500)); - std::unique_ptr<LayerImpl> scroll_layer_scoped_ptr( - LayerImpl::Create(host_impl.active_tree(), 2)); - LayerImpl* scroll_layer = scroll_layer_scoped_ptr.get(); + LayerImpl* scroll_layer = AddLayer<LayerImpl>(); scroll_layer->SetBounds(gfx::Size(10, 20)); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); @@ -532,23 +406,28 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(), scroll_layer->bounds().height() + kMaxScrollOffset.y())); - scroll_layer->test_properties()->AddChild(std::move(sublayer_scoped_ptr)); + LayerImpl* page_scale_layer = AddLayer<LayerImpl>(); + page_scale_layer->SetBounds(gfx::Size(3, 4)); + + LayerImpl* root_layer = root_layer_for_testing(); + root_layer->SetBounds(gfx::Size(3, 4)); + + SetupRootProperties(root_layer); + CopyProperties(root_layer, page_scale_layer); + CreateTransformNode(page_scale_layer); + CopyProperties(page_scale_layer, scroll_layer); + CreateTransformNode(scroll_layer); + CreateScrollNode(scroll_layer); + CopyProperties(scroll_layer, sublayer); - std::unique_ptr<LayerImpl> root( - LayerImpl::Create(host_impl.active_tree(), 3)); - root->SetBounds(gfx::Size(3, 4)); - root->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr)); - LayerImpl* root_layer = root.get(); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); - auto& scroll_tree = host_impl.active_tree()->property_trees()->scroll_tree; + auto& scroll_tree = GetPropertyTrees(scroll_layer)->scroll_tree; scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), kScrollOffset); SetScrollOffsetDelta(scroll_layer, kScrollDelta); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent, - nullptr, nullptr); + const gfx::Transform kDeviceTransform; + ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, + page_scale, page_scale_layer); gfx::Transform expected_transform; gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta; expected_transform.Translate( @@ -565,11 +444,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { const float kTranslateX = 10.6f; const float kTranslateY = 20.6f; arbitrary_translate.Translate(kTranslateX, kTranslateY); - scroll_layer->test_properties()->transform = arbitrary_translate; - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent, - nullptr, nullptr); + SetTransform(scroll_layer, arbitrary_translate); + ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, + page_scale, page_scale_layer); expected_transform.MakeIdentity(); expected_transform.Translate( std::round(kTranslateX * page_scale * kDeviceScale + @@ -585,13 +462,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { page_scale = 1.888f; LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = scroll_layer->test_properties()->parent->id(); + viewport_ids.page_scale = page_scale_layer->id(); root_layer->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); root_layer->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale); EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent, - nullptr, nullptr); + ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, + page_scale, page_scale_layer); expected_transform.MakeIdentity(); expected_transform.Translate( @@ -607,9 +483,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); // One-time setup of root layer root->SetBounds(gfx::Size(1, 2)); @@ -620,10 +496,16 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { host_impl()->active_tree()->property_trees()->effect_tree; // Case 1: parent's anchor point should not affect child or grand_child. - parent->test_properties()->transform_origin = gfx::Point3F(2.5f, 3.0f, 0.f); parent->SetBounds(gfx::Size(10, 12)); child->SetBounds(gfx::Size(16, 18)); grand_child->SetBounds(gfx::Size(76, 78)); + + SetupRootProperties(root); + CopyProperties(root, parent); + CreateTransformNode(parent).origin = gfx::Point3F(2.5f, 3.0f, 0.f); + CopyProperties(parent, child); + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -642,8 +524,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { // Case 2: parent's position affects child and grand_child. gfx::Transform parent_position_transform; parent_position_transform.Translate(0.f, 1.2f); - parent->test_properties()->position = gfx::PointF(0.f, 1.2f); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetPostTranslation(parent, gfx::Vector2dF(0.f, 1.2f)); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_position_transform, @@ -666,9 +547,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { gfx::Transform parent_composite_transform = parent_translation_to_anchor * parent_layer_transform * Inverse(parent_translation_to_anchor); - parent->test_properties()->transform = parent_layer_transform; - parent->test_properties()->position = gfx::PointF(); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetTransform(parent, parent_layer_transform); + SetPostTranslation(parent, gfx::Vector2dF()); ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_composite_transform, @@ -687,9 +567,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform parent_layer_transform; parent_layer_transform.Scale3d(1.f, 0.9f, 1.f); @@ -709,13 +589,20 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { parent_composite_transform * Inverse(surface_sublayer_transform); root->SetBounds(gfx::Size(1, 2)); - parent->test_properties()->transform = parent_layer_transform; - parent->test_properties()->transform_origin = gfx::Point3F(2.5f, 30.f, 0.f); parent->SetBounds(gfx::Size(100, 120)); child->SetBounds(gfx::Size(16, 18)); - child->test_properties()->force_render_surface = true; grand_child->SetBounds(gfx::Size(8, 10)); grand_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, parent); + auto& parent_transform_node = CreateTransformNode(parent); + parent_transform_node.origin = gfx::Point3F(2.5f, 30.f, 0.f); + parent_transform_node.local = parent_layer_transform; + CopyProperties(parent, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(root); // Render surface should have been created now. @@ -755,30 +642,25 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // and render target values. LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); + LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetDrawsContent(true); - LayerImpl* render_surface1 = AddChild<LayerImpl>(parent); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); render_surface1->SetDrawsContent(true); - LayerImpl* render_surface2 = AddChild<LayerImpl>(render_surface1); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); render_surface2->SetDrawsContent(true); - LayerImpl* child_of_root = AddChild<LayerImpl>(parent); + LayerImpl* child_of_root = AddLayer<LayerImpl>(); child_of_root->SetDrawsContent(true); - LayerImpl* child_of_rs1 = AddChild<LayerImpl>(render_surface1); + LayerImpl* child_of_rs1 = AddLayer<LayerImpl>(); child_of_rs1->SetDrawsContent(true); - LayerImpl* child_of_rs2 = AddChild<LayerImpl>(render_surface2); + LayerImpl* child_of_rs2 = AddLayer<LayerImpl>(); child_of_rs2->SetDrawsContent(true); - LayerImpl* grand_child_of_root = AddChild<LayerImpl>(child_of_root); + LayerImpl* grand_child_of_root = AddLayer<LayerImpl>(); grand_child_of_root->SetDrawsContent(true); - LayerImpl* grand_child_of_rs1 = AddChild<LayerImpl>(child_of_rs1); + LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>(); grand_child_of_rs1->SetDrawsContent(true); - LayerImpl* grand_child_of_rs2 = AddChild<LayerImpl>(child_of_rs2); + LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>(); grand_child_of_rs2->SetDrawsContent(true); - // In combination with descendant draws content, opacity != 1 forces the layer - // to have a new render surface. - render_surface1->test_properties()->opacity = 0.5f; - render_surface2->test_properties()->opacity = 0.33f; - // All layers in the tree are initialized with an anchor at .25 and a size of // (10,10). Matrix "A" is the composite layer transform used in all layers. gfx::Transform translation_to_anchor; @@ -814,44 +696,65 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { gfx::Transform S2 = Inverse(surface2_sublayer_transform); root->SetBounds(gfx::Size(1, 2)); - parent->test_properties()->transform_origin = gfx::Point3F(2.5f, 0.f, 0.f); - parent->test_properties()->transform = layer_transform; parent->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - render_surface1->test_properties()->transform = layer_transform; render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - render_surface2->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - render_surface2->test_properties()->transform = layer_transform; render_surface2->SetBounds(gfx::Size(10, 10)); - render_surface2->test_properties()->force_render_surface = true; - child_of_root->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - child_of_root->test_properties()->transform = layer_transform; child_of_root->SetBounds(gfx::Size(10, 10)); - child_of_rs1->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - child_of_rs1->test_properties()->transform = layer_transform; child_of_rs1->SetBounds(gfx::Size(10, 10)); - child_of_rs2->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - child_of_rs2->test_properties()->transform = layer_transform; child_of_rs2->SetBounds(gfx::Size(10, 10)); - grand_child_of_root->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - grand_child_of_root->test_properties()->transform = layer_transform; grand_child_of_root->SetBounds(gfx::Size(10, 10)); - grand_child_of_rs1->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - grand_child_of_rs1->test_properties()->transform = layer_transform; grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); - grand_child_of_rs2->test_properties()->transform_origin = - gfx::Point3F(2.5f, 0.f, 0.f); - grand_child_of_rs2->test_properties()->transform = layer_transform; grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); + SetupRootProperties(root); + CopyProperties(root, parent); + auto& parent_transform_node = CreateTransformNode(parent); + parent_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + parent_transform_node.local = layer_transform; + CopyProperties(parent, child_of_root); + auto& child_of_root_transform_node = CreateTransformNode(child_of_root); + child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + child_of_root_transform_node.local = layer_transform; + CopyProperties(child_of_root, grand_child_of_root); + auto& grand_child_of_root_transform_node = + CreateTransformNode(grand_child_of_root); + grand_child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + grand_child_of_root_transform_node.local = layer_transform; + CopyProperties(parent, render_surface1); + auto& render_surface1_transform_node = CreateTransformNode(render_surface1); + render_surface1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + render_surface1_transform_node.local = layer_transform; + auto& render_surface1_effect_node = CreateEffectNode(render_surface1); + render_surface1_effect_node.render_surface_reason = + RenderSurfaceReason::kTest; + render_surface1_effect_node.opacity = 0.5f; + CopyProperties(render_surface1, child_of_rs1); + auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1); + child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + child_of_rs1_transform_node.local = layer_transform; + CopyProperties(child_of_rs1, grand_child_of_rs1); + auto& grand_child_of_rs1_transform_node = + CreateTransformNode(grand_child_of_rs1); + grand_child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + grand_child_of_rs1_transform_node.local = layer_transform; + CopyProperties(render_surface1, render_surface2); + auto& render_surface2_transform_node = CreateTransformNode(render_surface2); + render_surface2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + render_surface2_transform_node.local = layer_transform; + auto& render_surface2_effect_node = CreateEffectNode(render_surface2); + render_surface2_effect_node.render_surface_reason = + RenderSurfaceReason::kTest; + render_surface2_effect_node.opacity = 0.33f; + CopyProperties(render_surface2, child_of_rs2); + auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2); + child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + child_of_rs2_transform_node.local = layer_transform; + CopyProperties(child_of_rs2, grand_child_of_rs2); + auto& grand_child_of_rs2_transform_node = + CreateTransformNode(grand_child_of_rs2); + grand_child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); + grand_child_of_rs2_transform_node.local = layer_transform; + ExecuteCalculateDrawProperties(root); // Only layers that are associated with render surfaces should have an actual @@ -965,36 +868,42 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3)); } -TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { +// Needs layer tree mode: testing PropertyTreeBuilder (forcing flattening on +// surface). +TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformsForFlatteningLayer) { // For layers that flatten their subtree, there should be an orthographic // projection (for x and y values) in the middle of the transform sequence. // Note that the way the code is currently implemented, it is not expected to // use a canonical orthographic projection. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - child->SetDrawsContent(true); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - grand_child->SetDrawsContent(true); - LayerImpl* great_grand_child = AddChild<LayerImpl>(grand_child); - great_grand_child->SetDrawsContent(true); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + child->SetIsDrawable(true); + auto grand_child = Layer::Create(); + child->AddChild(grand_child); + grand_child->SetIsDrawable(true); + auto great_grand_child = Layer::Create(); + grand_child->AddChild(great_grand_child); + great_grand_child->SetIsDrawable(true); gfx::Transform rotation_about_y_axis; rotation_about_y_axis.RotateAboutYAxis(30.0); root->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = rotation_about_y_axis; + child->SetTransform(rotation_about_y_axis); child->SetBounds(gfx::Size(10, 10)); - child->test_properties()->force_render_surface = true; - grand_child->test_properties()->transform = rotation_about_y_axis; + child->SetForceRenderSurfaceForTesting(true); + grand_child->SetTransform(rotation_about_y_axis); grand_child->SetBounds(gfx::Size(10, 10)); great_grand_child->SetBounds(gfx::Size(10, 10)); // No layers in this test should preserve 3d. - ASSERT_TRUE(root->test_properties()->should_flatten_transform); - ASSERT_TRUE(child->test_properties()->should_flatten_transform); - ASSERT_TRUE(grand_child->test_properties()->should_flatten_transform); - ASSERT_TRUE(great_grand_child->test_properties()->should_flatten_transform); + ASSERT_TRUE(root->should_flatten_transform()); + ASSERT_TRUE(child->should_flatten_transform()); + ASSERT_TRUE(grand_child->should_flatten_transform()); + ASSERT_TRUE(great_grand_child->should_flatten_transform()); gfx::Transform expected_child_draw_transform = rotation_about_y_axis; gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis; @@ -1009,33 +918,35 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { gfx::Transform expected_great_grand_child_screen_space_transform = flattened_rotation_about_y * flattened_rotation_about_y; - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); // The child's draw transform should have been taken by its surface. - ASSERT_TRUE(GetRenderSurface(child)); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform, - GetRenderSurface(child)->draw_transform()); + ASSERT_TRUE(GetRenderSurfaceImpl(child)); + EXPECT_TRANSFORMATION_MATRIX_EQ( + expected_child_draw_transform, + GetRenderSurfaceImpl(child)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_child_screen_space_transform, - GetRenderSurface(child)->screen_space_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); + GetRenderSurfaceImpl(child)->screen_space_transform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), + ImplOf(child)->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform, - child->ScreenSpaceTransform()); + ImplOf(child)->ScreenSpaceTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform, - grand_child->DrawTransform()); + ImplOf(grand_child)->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - grand_child->ScreenSpaceTransform()); + ImplOf(grand_child)->ScreenSpaceTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_draw_transform, - great_grand_child->DrawTransform()); + ImplOf(great_grand_child)->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_great_grand_child_screen_space_transform, - great_grand_child->ScreenSpaceTransform()); + ImplOf(great_grand_child)->ScreenSpaceTransform()); } TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform child_transform; child_transform.Translate(50.0, 50.0); @@ -1045,20 +956,19 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child_transform.RotateAboutYAxis(90.0); root->SetBounds(gfx::Size(200, 200)); - child->test_properties()->transform = child_transform; child->SetBounds(gfx::Size(10, 10)); - grand_child->test_properties()->transform = grand_child_transform; grand_child->SetBounds(gfx::Size(100, 100)); - grand_child->test_properties()->should_flatten_transform = false; grand_child->SetDrawsContent(true); - float device_scale_factor = 1.f; - float page_scale_factor = 1.f; - LayerImpl* page_scale_layer = nullptr; - LayerImpl* inner_viewport_scroll_layer = nullptr; - LayerImpl* outer_viewport_scroll_layer = nullptr; - ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child).local = child_transform; + CopyProperties(child, grand_child); + auto& grand_child_transform_node = CreateTransformNode(grand_child); + grand_child_transform_node.flattens_inherited_transform = false; + grand_child_transform_node.local = grand_child_transform; + + ExecuteCalculateDrawProperties(root); // 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 @@ -1081,16 +991,21 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { // incorrectly as a result. LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); grand_child->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); // The child height is zero, but has non-zero width that should be accounted // for while computing draw transforms. child->SetBounds(gfx::Size(10, 0)); - child->test_properties()->force_render_surface = true; grand_child->SetBounds(gfx::Size(10, 10)); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(child)); @@ -1104,31 +1019,32 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(render_surface); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform translate; translate.Translate3d(5, 5, 5); root->SetBounds(gfx::Size(100, 100)); - render_surface->test_properties()->transform = translate; render_surface->SetBounds(gfx::Size(100, 100)); - render_surface->test_properties()->force_render_surface = true; - child->test_properties()->transform = translate; child->SetBounds(gfx::Size(100, 100)); - grand_child->test_properties()->transform = translate; grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateTransformNode(render_surface).local = translate; + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, child); + CreateTransformNode(child).local = translate; + CopyProperties(child, grand_child); + CreateTransformNode(grand_child).local = translate; + // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_list_impl); - inputs.device_scale_factor = device_scale_factor; - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor); // Between grand_child and render_surface, we translate by (10, 10) and scale // by a factor of 2. @@ -1141,7 +1057,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { // Transformations applied at the root of the tree should be forwarded // to child layers instead of applied to the root RenderSurface. LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); @@ -1149,14 +1065,15 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); + SetupRootProperties(root); + CopyProperties(root, child); + CreateClipNode(child); + + float device_scale_factor = 1.0f; gfx::Transform translate; translate.Translate(50, 50); { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_list_impl); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor, translate); EXPECT_TRANSFORMATION_MATRIX_EQ( translate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1170,11 +1087,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform scale; scale.Scale(2, 2); { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), scale, &render_surface_list_impl); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor, scale); EXPECT_TRANSFORMATION_MATRIX_EQ( scale, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1188,11 +1101,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform rotate; rotate.Rotate(2); { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), rotate, &render_surface_list_impl); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor, rotate); EXPECT_TRANSFORMATION_MATRIX_EQ( rotate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1208,11 +1117,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { composite.ConcatTransform(scale); composite.ConcatTransform(rotate); { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_list_impl); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor, composite); EXPECT_TRANSFORMATION_MATRIX_EQ( composite, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1224,15 +1129,10 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { } // Verify it composes correctly with device scale. - float device_scale_factor = 1.5f; + device_scale_factor = 1.5f; { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_list_impl); - inputs.device_scale_factor = device_scale_factor; - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor, translate); gfx::Transform device_scaled_translate = translate; device_scaled_translate.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1247,100 +1147,60 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(50, 50, 150, 150), child->clip_rect()); } - - // Verify it composes correctly with page scale. - float page_scale_factor = 2.f; - - { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_list_impl); - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_layer = root; - inputs.page_scale_transform_node = - inputs.property_trees->transform_tree.Node( - inputs.page_scale_layer->transform_tree_index()); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - gfx::Transform page_scaled_translate = translate; - page_scaled_translate.Scale(page_scale_factor, page_scale_factor); - EXPECT_TRANSFORMATION_MATRIX_EQ( - page_scaled_translate, root->draw_properties().target_space_transform); - EXPECT_TRANSFORMATION_MATRIX_EQ( - page_scaled_translate, child->draw_properties().target_space_transform); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - GetRenderSurface(root)->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(page_scaled_translate, - child->ScreenSpaceTransform()); - EXPECT_EQ(gfx::Rect(50, 50, 200, 200), child->clip_rect()); - } - - // Verify that it composes correctly with transforms directly on root layer. - root->test_properties()->transform = composite; - - { - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_list_impl); - inputs.property_trees->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - gfx::Transform compositeSquared = composite; - compositeSquared.ConcatTransform(composite); - EXPECT_TRANSFORMATION_MATRIX_EQ( - compositeSquared, root->draw_properties().target_space_transform); - EXPECT_TRANSFORMATION_MATRIX_EQ( - compositeSquared, child->draw_properties().target_space_transform); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - GetRenderSurface(root)->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(compositeSquared, - child->ScreenSpaceTransform()); - EXPECT_EQ(gfx::Rect(254, 316, 428, 428), child->clip_rect()); - } } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceForNonAxisAlignedClipping) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* rotated_and_transparent = AddChildToRoot<LayerImpl>(); - LayerImpl* clips_subtree = AddChild<LayerImpl>(rotated_and_transparent); - LayerImpl* draws_content = AddChild<LayerImpl>(clips_subtree); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RenderSurfaceForNonAxisAlignedClipping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotated_and_transparent = Layer::Create(); + root->AddChild(rotated_and_transparent); + auto clips_subtree = Layer::Create(); + rotated_and_transparent->AddChild(clips_subtree); + auto draws_content = Layer::Create(); + clips_subtree->AddChild(draws_content); root->SetBounds(gfx::Size(10, 10)); rotated_and_transparent->SetBounds(gfx::Size(10, 10)); - rotated_and_transparent->test_properties()->opacity = 0.5f; + rotated_and_transparent->SetOpacity(0.5f); gfx::Transform rotate; rotate.Rotate(2); - rotated_and_transparent->test_properties()->transform = rotate; + rotated_and_transparent->SetTransform(rotate); clips_subtree->SetBounds(gfx::Size(10, 10)); clips_subtree->SetMasksToBounds(true); draws_content->SetBounds(gfx::Size(10, 10)); - draws_content->SetDrawsContent(true); + draws_content->SetIsDrawable(true); - ExecuteCalculateDrawProperties(root); - EffectTree& effect_tree = - root->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = effect_tree.Node(clips_subtree->effect_tree_index()); - EXPECT_TRUE(node->HasRenderSurface()); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface()); } -TEST_F(LayerTreeHostCommonTest, EffectNodesForNonAxisAlignedClips) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* rotate_and_clip = AddChildToRoot<LayerImpl>(); - LayerImpl* only_clip = AddChild<LayerImpl>(rotate_and_clip); - LayerImpl* rotate_and_clip2 = AddChild<LayerImpl>(only_clip); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + EffectNodesForNonAxisAlignedClips) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotate_and_clip = Layer::Create(); + root->AddChild(rotate_and_clip); + auto only_clip = Layer::Create(); + rotate_and_clip->AddChild(only_clip); + auto rotate_and_clip2 = Layer::Create(); + only_clip->AddChild(rotate_and_clip2); gfx::Transform rotate; rotate.Rotate(2); root->SetBounds(gfx::Size(10, 10)); rotate_and_clip->SetBounds(gfx::Size(10, 10)); - rotate_and_clip->test_properties()->transform = rotate; + rotate_and_clip->SetTransform(rotate); rotate_and_clip->SetMasksToBounds(true); only_clip->SetBounds(gfx::Size(10, 10)); only_clip->SetMasksToBounds(true); rotate_and_clip2->SetBounds(gfx::Size(10, 10)); - rotate_and_clip2->test_properties()->transform = rotate; + rotate_and_clip2->SetTransform(rotate); rotate_and_clip2->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root); + ExecuteCalculateDrawProperties(root.get()); // non-axis aligned clip should create an effect node EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index()); // Since only_clip's clip is in the same non-axis aligned space as @@ -1353,161 +1213,167 @@ TEST_F(LayerTreeHostCommonTest, EffectNodesForNonAxisAlignedClips) { only_clip->effect_tree_index()); } -TEST_F(LayerTreeHostCommonTest, +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceListForRenderSurfaceWithClippedLayer) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(render_surface1); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); root->SetBounds(gfx::Size(10, 10)); root->SetMasksToBounds(true); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - child->SetDrawsContent(true); - child->test_properties()->position = gfx::PointF(30.f, 30.f); + render_surface1->SetForceRenderSurfaceForTesting(true); + child->SetIsDrawable(true); + child->SetPosition(gfx::PointF(30.f, 30.f)); child->SetBounds(gfx::Size(10, 10)); - ExecuteCalculateDrawProperties(root); + + CommitAndActivate(); // The child layer's content is entirely outside the root's clip rect, so // the intermediate render surface should not be listed here, even if it was // forced to be created. Render surfaces without children or visible content // are unexpected at draw time (e.g. we might try to create a content texture // of size 0). - ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_TRUE(GetRenderSurfaceImpl(root)); EXPECT_EQ(1U, render_surface_list_impl()->size()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(render_surface1); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RenderSurfaceListForTransparentChild) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + root->SetBounds(gfx::Size(10, 10)); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - render_surface1->test_properties()->opacity = 0.f; + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); - // Since the layer is transparent, render_surface1->GetRenderSurface() should - // not have gotten added anywhere. Also, the drawable content rect should not - // have been extended by the children. - ASSERT_TRUE(GetRenderSurface(root)); - EXPECT_EQ(0, GetRenderSurface(root)->num_contributors()); - EXPECT_EQ(1U, render_surface_list.size()); + // Since the layer is transparent, render_surface1_impl->GetRenderSurface() + // should not have gotten added anywhere. Also, the drawable content rect + // should not have been extended by the children. + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_EQ(1U, render_surface_list_impl()->size()); EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()), - render_surface_list.at(0)->id()); - EXPECT_EQ(gfx::Rect(), root->drawable_content_rect()); + render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceListForTransparentChildWithBackdropFilter) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(render_surface1); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); root->SetBounds(gfx::Size(10, 10)); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - render_surface1->test_properties()->opacity = 0.f; - render_surface1->SetDrawsContent(true); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); + render_surface1->SetIsDrawable(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(1.5f)); - render_surface1->test_properties()->backdrop_filters = filters; + render_surface1->SetBackdropFilters(filters); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); - root->layer_tree_impl()->SetElementIdsForTesting(); + child->SetIsDrawable(true); + host()->SetElementIdsForTesting(); + + CommitAndActivate(); + EXPECT_EQ(2U, render_surface_list_impl()->size()); - { - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - EXPECT_EQ(2U, render_surface_list.size()); - } // The layer is fully transparent, but has a backdrop filter, so it // shouldn't be skipped and should be drawn. - ASSERT_TRUE(GetRenderSurface(root)); - EXPECT_EQ(1, GetRenderSurface(root)->num_contributors()); + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); EXPECT_EQ(gfx::RectF(0, 0, 10, 10), - GetRenderSurface(root)->DrawableContentRect()); - EffectTree& effect_tree = - root->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = effect_tree.Node(render_surface1->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); + GetRenderSurfaceImpl(root)->DrawableContentRect()); + EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn); // When root is transparent, the layer should not be drawn. - 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()); - { - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - } + host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f); + host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(), + 1.f); + ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect()); + ExecuteCalculateDrawProperties(ImplOf(root)); - node = effect_tree.Node(render_surface1->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - EXPECT_EQ(gfx::Rect(), render_surface1->visible_layer_rect()); + EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn); + EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceListForFilter) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); gfx::Transform scale_matrix; scale_matrix.Scale(2.0f, 2.0f); root->SetBounds(gfx::Size(100, 100)); - parent->test_properties()->transform = scale_matrix; + parent->SetTransform(scale_matrix); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.0f)); - parent->test_properties()->filters = filters; - parent->test_properties()->force_render_surface = true; + parent->SetFilters(filters); + parent->SetForceRenderSurfaceForTesting(true); child1->SetBounds(gfx::Size(25, 25)); - child1->SetDrawsContent(true); - child1->test_properties()->force_render_surface = true; - child2->test_properties()->position = gfx::PointF(25, 25); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(25, 25)); child2->SetBounds(gfx::Size(25, 25)); - child2->SetDrawsContent(true); - child2->test_properties()->force_render_surface = true; + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); - ASSERT_TRUE(GetRenderSurface(parent)); - EXPECT_EQ(2, GetRenderSurface(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list.size()); + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, render_surface_list_impl()->size()); // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the // blur (-30,-30 110x110), and then scaled by the scale matrix // (-60,-60 220x220). EXPECT_EQ(gfx::RectF(-60, -60, 220, 220), - GetRenderSurface(parent)->DrawableContentRect()); + GetRenderSurfaceImpl(parent)->DrawableContentRect()); } TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(25, 25)); child->SetDrawsContent(true); - child->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - child->test_properties()->filters = filters; + + SetupRootProperties(root); + CopyProperties(root, child); + auto& child_effect_node = CreateEffectNode(child); + child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + child_effect_node.filters = filters; + ExecuteCalculateDrawProperties(root); // The render surface's size should be unaffected by the offset image filter; @@ -1522,17 +1388,21 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { const float device_scale_factor = 2.0f; LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(25, 25)); child->SetDrawsContent(true); - child->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - child->test_properties()->filters = filters; + + SetupRootProperties(root); + CopyProperties(root, child); + auto& child_effect_node = CreateEffectNode(child); + child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + child_effect_node.filters = filters; ExecuteCalculateDrawProperties(root, device_scale_factor); @@ -1547,14 +1417,19 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(10, 10)); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - child->test_properties()->blend_mode = SkBlendMode::kMultiply; - child->test_properties()->opacity = 0.5f; - child->test_properties()->force_render_surface = true; + + SetupRootProperties(root); + CopyProperties(root, child); + auto& child_effect_node = CreateEffectNode(child); + child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + child_effect_node.blend_mode = SkBlendMode::kMultiply; + child_effect_node.opacity = 0.5f; + ExecuteCalculateDrawProperties(root); // Since the child layer has a blend mode other than normal, it should get @@ -1567,21 +1442,29 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* not_surface = AddChild<LayerImpl>(surface1); - LayerImpl* surface2 = AddChild<LayerImpl>(not_surface); + LayerImpl* surface1 = AddLayer<LayerImpl>(); + LayerImpl* not_surface = AddLayer<LayerImpl>(); + LayerImpl* surface2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(10, 10)); surface1->SetBounds(gfx::Size(10, 10)); surface1->SetDrawsContent(true); - surface1->test_properties()->opacity = 0.5f; - surface1->test_properties()->force_render_surface = true; not_surface->SetBounds(gfx::Size(10, 10)); - not_surface->test_properties()->opacity = 0.5f; surface2->SetBounds(gfx::Size(10, 10)); surface2->SetDrawsContent(true); - surface2->test_properties()->opacity = 0.5f; - surface2->test_properties()->force_render_surface = true; + + SetupRootProperties(root); + CopyProperties(root, surface1); + auto& surface1_effect_node = CreateEffectNode(surface1); + surface1_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + surface1_effect_node.opacity = 0.5f; + CopyProperties(surface1, not_surface); + CreateEffectNode(not_surface).opacity = 0.5f; + CopyProperties(not_surface, surface2); + auto& surface2_effect_node = CreateEffectNode(surface2); + surface2_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + surface2_effect_node.opacity = 0.5f; + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(surface1)); @@ -1593,73 +1476,83 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity()); } -TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(render_surface1); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, ForceRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); root->SetBounds(gfx::Size(10, 10)); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; + render_surface1->SetForceRenderSurfaceForTesting(true); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); - { - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + CommitAndActivate(); - // The root layer always creates a render surface - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root)); - } + // The root layer always creates a render surface + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); - { - render_surface1->test_properties()->force_render_surface = false; - render_surface1->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(render_surface1), GetRenderSurface(root)); - } + render_surface1->SetForceRenderSurfaceForTesting(false); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); } -TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) { +// Needs layer tree mode: testing PropertyTreeBuilder (force flattening on +// surface). +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RenderSurfacesFlattenScreenSpaceTransform) { // Render surfaces act as a flattening point for their subtree, so should // always flatten the target-to-screen space transform seen by descendants. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child = Layer::Create(); + parent->AddChild(child); + auto grand_child = Layer::Create(); + child->AddChild(grand_child); gfx::Transform rotation_about_y_axis; rotation_about_y_axis.RotateAboutYAxis(30.0); root->SetBounds(gfx::Size(100, 100)); - parent->test_properties()->transform = rotation_about_y_axis; + parent->SetTransform(rotation_about_y_axis); parent->SetBounds(gfx::Size(10, 10)); - parent->test_properties()->force_render_surface = true; + parent->SetForceRenderSurfaceForTesting(true); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); grand_child->SetBounds(gfx::Size(10, 10)); - grand_child->SetDrawsContent(true); - grand_child->test_properties()->should_flatten_transform = false; - ExecuteCalculateDrawProperties(root); + grand_child->SetIsDrawable(true); + grand_child->SetShouldFlattenTransform(false); - EXPECT_TRUE(GetRenderSurface(parent)); - EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(parent)); - EXPECT_EQ(GetRenderSurface(grand_child), GetRenderSurface(parent)); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(parent)); + EXPECT_EQ(GetRenderSurfaceImpl(grand_child), GetRenderSurfaceImpl(parent)); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - grand_child->DrawTransform()); + ImplOf(child)->DrawTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), + ImplOf(grand_child)->DrawTransform()); - // The screen-space transform inherited by |child| and |grand_child| should - // have been flattened at their render target. In particular, the fact that - // |grand_child| happens to preserve 3d shouldn't affect this flattening. + // The screen-space transform inherited by |child| and |grand_child| + // should have been flattened at their render target. In particular, the fact + // that |grand_child| happens to preserve 3d shouldn't affect this + // flattening. gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; flattened_rotation_about_y.FlattenTo2d(); EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - child->ScreenSpaceTransform()); + ImplOf(child)->ScreenSpaceTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - grand_child->ScreenSpaceTransform()); + ImplOf(grand_child)->ScreenSpaceTransform()); } TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { @@ -1679,26 +1572,39 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { // render surfaces. LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - LayerImpl* great_grand_child = AddChild<LayerImpl>(grand_child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* great_grand_child = AddLayer<LayerImpl>(); // leaf_node1 ensures that root and child are kept on the render_surface_list, // even though grand_child and great_grand_child should be clipped. - LayerImpl* leaf_node1 = AddChild<LayerImpl>(child); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(great_grand_child); + LayerImpl* leaf_node1 = AddLayer<LayerImpl>(); + LayerImpl* leaf_node2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(500, 500)); child->SetBounds(gfx::Size(20, 20)); child->SetMasksToBounds(true); - child->test_properties()->force_render_surface = true; - grand_child->test_properties()->position = gfx::PointF(45.f, 45.f); grand_child->SetBounds(gfx::Size(10, 10)); great_grand_child->SetBounds(gfx::Size(10, 10)); leaf_node1->SetBounds(gfx::Size(500, 500)); leaf_node1->SetDrawsContent(true); leaf_node1->SetBounds(gfx::Size(20, 20)); leaf_node2->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateClipNode(child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, leaf_node1); + CopyProperties(child, grand_child); + grand_child->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f)); + CopyProperties(grand_child, great_grand_child); + great_grand_child->SetOffsetToTransformParent( + grand_child->offset_to_transform_parent()); + CopyProperties(great_grand_child, leaf_node2); + leaf_node2->SetOffsetToTransformParent( + great_grand_child->offset_to_transform_parent()); + ExecuteCalculateDrawProperties(root); ASSERT_EQ(2U, render_surface_list_impl()->size()); @@ -1724,23 +1630,32 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { // render_surface_list. LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* leaf_node = AddLayer<LayerImpl>(); root->SetMasksToBounds(true); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(20, 20)); - child->test_properties()->force_render_surface = true; - grand_child->test_properties()->position = gfx::PointF(200.f, 200.f); grand_child->SetBounds(gfx::Size(10, 10)); - grand_child->test_properties()->force_render_surface = true; leaf_node->SetBounds(gfx::Size(10, 10)); leaf_node->SetDrawsContent(true); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + grand_child->SetOffsetToTransformParent(gfx::Vector2dF(200.f, 200.f)); + CreateEffectNode(grand_child).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(grand_child, leaf_node); + leaf_node->SetOffsetToTransformParent( + grand_child->offset_to_transform_parent()); + ExecuteCalculateDrawProperties(root); - // We should cull child and grand_child from the - // render_surface_list. + // We should cull child and grand_child from the render_surface_list. ASSERT_EQ(1U, render_surface_list_impl()->size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), render_surface_list_impl()->at(0)->id()); @@ -1761,12 +1676,12 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { // and propagates the clip to the subtree. LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child1); - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* leaf_node1 = AddLayer<LayerImpl>(); + LayerImpl* leaf_node2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); parent->SetBounds(gfx::Size(100, 100)); @@ -1775,7 +1690,6 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { child1->SetDrawsContent(true); child2->SetBounds(gfx::Size(100, 100)); child2->SetDrawsContent(true); - child2->test_properties()->force_render_surface = true; grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); leaf_node1->SetBounds(gfx::Size(100, 100)); @@ -1783,6 +1697,16 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { leaf_node2->SetBounds(gfx::Size(100, 100)); leaf_node2->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, parent); + CopyProperties(parent, child1); + CopyProperties(child1, grand_child); + CopyProperties(grand_child, leaf_node1); + CopyProperties(parent, child2); + CreateTransformNode(child2); + CreateEffectNode(child2).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child2, leaf_node2); + // Case 1: nothing is clipped except the root render surface. ExecuteCalculateDrawProperties(root); @@ -1804,7 +1728,13 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { // not clipped explicitly because child2's surface already accounts for // that clip. parent->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + CreateClipNode(parent); + child1->SetClipTreeIndex(parent->clip_tree_index()); + grand_child->SetClipTreeIndex(parent->clip_tree_index()); + leaf_node1->SetClipTreeIndex(parent->clip_tree_index()); + child2->SetClipTreeIndex(parent->clip_tree_index()); + GetEffectNode(child2)->clip_id = parent->clip_tree_index(); + leaf_node2->SetClipTreeIndex(parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -1822,11 +1752,19 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { EXPECT_FALSE(leaf_node2->is_clipped()); parent->SetMasksToBounds(false); + parent->SetClipTreeIndex(root->clip_tree_index()); + child1->SetClipTreeIndex(root->clip_tree_index()); + grand_child->SetClipTreeIndex(root->clip_tree_index()); + leaf_node1->SetClipTreeIndex(root->clip_tree_index()); + child2->SetClipTreeIndex(root->clip_tree_index()); + GetEffectNode(child2)->clip_id = root->clip_tree_index(); + leaf_node2->SetClipTreeIndex(root->clip_tree_index()); // Case 3: child2 MasksToBounds. The layer and subtree are clipped, and // child2's render surface is not clipped. child2->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + CreateClipNode(child2); + leaf_node2->SetClipTreeIndex(child2->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -1848,8 +1786,8 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { // Tests that when as long as layer is clipped, it's clip rect is set to // correct value. LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(parent); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); @@ -1859,6 +1797,11 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { child->SetDrawsContent(true); child->SetMasksToBounds(true); + SetupRootProperties(root); + CopyProperties(root, parent); + CopyProperties(parent, child); + CreateClipNode(child); + ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->is_clipped()); @@ -1867,8 +1810,10 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { EXPECT_EQ(gfx::Rect(100, 100), child->clip_rect()); parent->SetMasksToBounds(true); - child->test_properties()->position = gfx::PointF(100.f, 100.f); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + CreateClipNode(parent); + GetClipNode(child)->parent_id = parent->clip_tree_index(); + child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); + GetClipNode(child)->clip += gfx::Vector2dF(100.f, 100.f); ExecuteCalculateDrawProperties(root); @@ -1893,29 +1838,40 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { // be empty. LayerImpl* parent = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child1 = AddChild<LayerImpl>(child); - LayerImpl* grand_child2 = AddChild<LayerImpl>(child); - LayerImpl* grand_child3 = AddChild<LayerImpl>(child); - LayerImpl* grand_child4 = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + LayerImpl* grand_child2 = AddLayer<LayerImpl>(); + LayerImpl* grand_child3 = AddLayer<LayerImpl>(); + LayerImpl* grand_child4 = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(500, 500)); child->SetMasksToBounds(true); child->SetBounds(gfx::Size(20, 20)); - child->test_properties()->force_render_surface = true; - grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f); grand_child1->SetBounds(gfx::Size(10, 10)); grand_child1->SetDrawsContent(true); - grand_child2->test_properties()->position = gfx::PointF(15.f, 15.f); grand_child2->SetBounds(gfx::Size(10, 10)); grand_child2->SetDrawsContent(true); - grand_child3->test_properties()->position = gfx::PointF(15.f, 15.f); - grand_child3->SetMasksToBounds(true); grand_child3->SetBounds(gfx::Size(10, 10)); + grand_child3->SetMasksToBounds(true); grand_child3->SetDrawsContent(true); - grand_child4->test_properties()->position = gfx::PointF(45.f, 45.f); grand_child4->SetBounds(gfx::Size(10, 10)); grand_child4->SetDrawsContent(true); + + SetupRootProperties(parent); + CopyProperties(parent, child); + CreateTransformNode(child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CreateClipNode(child); + CopyProperties(child, grand_child1); + grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(child, grand_child2); + grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f)); + CopyProperties(child, grand_child3); + grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f)); + CreateClipNode(grand_child3); + CopyProperties(child, grand_child4); + grand_child4->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f)); + ExecuteCalculateDrawProperties(parent); EXPECT_EQ(gfx::Rect(5, 5, 10, 10), grand_child1->drawable_content_rect()); @@ -1933,36 +1889,27 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { // They may still have a clip rect of their own layer bounds, however, if // MasksToBounds was true. LayerImpl* parent = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child1 = AddChild<LayerImpl>(child); - LayerImpl* grand_child2 = AddChild<LayerImpl>(child); - LayerImpl* grand_child3 = AddChild<LayerImpl>(child); - LayerImpl* grand_child4 = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + LayerImpl* grand_child2 = AddLayer<LayerImpl>(); + LayerImpl* grand_child3 = AddLayer<LayerImpl>(); + LayerImpl* grand_child4 = AddLayer<LayerImpl>(); // The leaf nodes ensure that these grand_children become render surfaces for // this test. - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child1); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(grand_child2); - LayerImpl* leaf_node3 = AddChild<LayerImpl>(grand_child3); - LayerImpl* leaf_node4 = AddChild<LayerImpl>(grand_child4); + LayerImpl* leaf_node1 = AddLayer<LayerImpl>(); + LayerImpl* leaf_node2 = AddLayer<LayerImpl>(); + LayerImpl* leaf_node3 = AddLayer<LayerImpl>(); + LayerImpl* leaf_node4 = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(500, 500)); child->SetBounds(gfx::Size(20, 20)); child->SetMasksToBounds(true); - child->test_properties()->force_render_surface = true; - grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f); grand_child1->SetBounds(gfx::Size(10, 10)); - grand_child1->test_properties()->force_render_surface = true; - grand_child2->test_properties()->position = gfx::PointF(15.f, 15.f); grand_child2->SetBounds(gfx::Size(10, 10)); - grand_child2->test_properties()->force_render_surface = true; - grand_child3->test_properties()->position = gfx::PointF(15.f, 15.f); grand_child3->SetBounds(gfx::Size(10, 10)); grand_child3->SetMasksToBounds(true); - grand_child3->test_properties()->force_render_surface = true; - grand_child4->test_properties()->position = gfx::PointF(45.f, 45.f); grand_child4->SetBounds(gfx::Size(10, 10)); grand_child4->SetMasksToBounds(true); - grand_child4->test_properties()->force_render_surface = true; leaf_node1->SetBounds(gfx::Size(10, 10)); leaf_node1->SetDrawsContent(true); leaf_node2->SetBounds(gfx::Size(10, 10)); @@ -1971,6 +1918,37 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { leaf_node3->SetDrawsContent(true); leaf_node4->SetBounds(gfx::Size(10, 10)); leaf_node4->SetDrawsContent(true); + + SetupRootProperties(parent); + CopyProperties(parent, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CreateClipNode(child); + CopyProperties(child, grand_child1); + CreateTransformNode(grand_child1).post_translation = gfx::Vector2dF(5.f, 5.f); + CreateEffectNode(grand_child1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(grand_child1, leaf_node1); + CopyProperties(child, grand_child2); + CreateTransformNode(grand_child2).post_translation = + gfx::Vector2dF(15.f, 15.f); + CreateEffectNode(grand_child2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(grand_child2, leaf_node2); + CopyProperties(child, grand_child3); + CreateTransformNode(grand_child3).post_translation = + gfx::Vector2dF(15.f, 15.f); + CreateEffectNode(grand_child3).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(grand_child3); + CopyProperties(grand_child3, leaf_node3); + CopyProperties(child, grand_child4); + CreateTransformNode(grand_child4).post_translation = + gfx::Vector2dF(45.f, 45.f); + CreateEffectNode(grand_child4).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(grand_child4); + CopyProperties(grand_child4, leaf_node4); + ExecuteCalculateDrawProperties(parent); ASSERT_TRUE(GetRenderSurface(grand_child1)); @@ -1989,104 +1967,122 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* child_of_rs1 = AddChild<LayerImpl>(render_surface1); - LayerImpl* grand_child_of_rs1 = AddChild<LayerImpl>(child_of_rs1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(render_surface1); - LayerImpl* child_of_rs2 = AddChild<LayerImpl>(render_surface2); - LayerImpl* grand_child_of_rs2 = AddChild<LayerImpl>(child_of_rs2); - LayerImpl* child_of_root = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child_of_root = AddChild<LayerImpl>(child_of_root); + LayerImpl* top = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* child_of_rs1 = AddLayer<LayerImpl>(); + LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* child_of_rs2 = AddLayer<LayerImpl>(); + LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>(); + LayerImpl* child_of_top = AddLayer<LayerImpl>(); + LayerImpl* grand_child_of_top = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); - root->SetDrawsContent(true); + top->SetDrawsContent(true); render_surface1->SetDrawsContent(true); child_of_rs1->SetDrawsContent(true); grand_child_of_rs1->SetDrawsContent(true); render_surface2->SetDrawsContent(true); child_of_rs2->SetDrawsContent(true); grand_child_of_rs2->SetDrawsContent(true); - child_of_root->SetDrawsContent(true); - grand_child_of_root->SetDrawsContent(true); + child_of_top->SetDrawsContent(true); + grand_child_of_top->SetDrawsContent(true); gfx::Transform layer_transform; layer_transform.Translate(1.0, 1.0); - root->test_properties()->transform = layer_transform; root->SetBounds(gfx::Size(10, 10)); - root->test_properties()->transform_origin = gfx::Point3F(0.25f, 0.f, 0.f); - render_surface1->test_properties()->transform = layer_transform; - render_surface1->test_properties()->position = gfx::PointF(2.5f, 0.f); + top->SetBounds(gfx::Size(10, 10)); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - render_surface1->test_properties()->force_render_surface = true; - render_surface2->test_properties()->transform = layer_transform; - render_surface2->test_properties()->position = gfx::PointF(2.5f, 0.f); render_surface2->SetBounds(gfx::Size(10, 10)); - render_surface2->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - render_surface2->test_properties()->force_render_surface = true; - child_of_root->test_properties()->transform = layer_transform; - child_of_root->test_properties()->position = gfx::PointF(2.5f, 0.f); - child_of_root->SetBounds(gfx::Size(10, 10)); - child_of_root->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - child_of_rs1->test_properties()->transform = layer_transform; - child_of_rs1->test_properties()->position = gfx::PointF(2.5f, 0.f); + child_of_top->SetBounds(gfx::Size(10, 10)); child_of_rs1->SetBounds(gfx::Size(10, 10)); - child_of_rs1->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - child_of_rs2->test_properties()->transform = layer_transform; - child_of_rs2->test_properties()->position = gfx::PointF(2.5f, 0.f); child_of_rs2->SetBounds(gfx::Size(10, 10)); - child_of_rs2->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - grand_child_of_root->test_properties()->transform = layer_transform; - grand_child_of_root->test_properties()->position = gfx::PointF(2.5f, 0.f); - grand_child_of_root->SetBounds(gfx::Size(10, 10)); - grand_child_of_root->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - grand_child_of_rs1->test_properties()->transform = layer_transform; - grand_child_of_rs1->test_properties()->position = gfx::PointF(2.5f, 0.f); + grand_child_of_top->SetBounds(gfx::Size(10, 10)); grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); - grand_child_of_rs1->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - grand_child_of_rs2->test_properties()->transform = layer_transform; - grand_child_of_rs2->test_properties()->position = gfx::PointF(2.5f, 0.f); grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); - grand_child_of_rs2->test_properties()->transform_origin = - gfx::Point3F(0.25f, 0.f, 0.f); - root->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting(); + SetupRootProperties(root); + CopyProperties(root, top); + CreateTransformNode(top).local = layer_transform; + CopyProperties(top, render_surface1); + auto& render_surface1_transform_node = CreateTransformNode(render_surface1); + render_surface1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + render_surface1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f); + render_surface1_transform_node.local = layer_transform; + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, child_of_rs1); + auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1); + child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + child_of_rs1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f); + child_of_rs1_transform_node.local = layer_transform; + CopyProperties(child_of_rs1, grand_child_of_rs1); + auto& grand_child_of_rs1_transform_node = + CreateTransformNode(grand_child_of_rs1); + grand_child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + grand_child_of_rs1_transform_node.post_translation = + gfx::Vector2dF(2.5f, 0.f); + grand_child_of_rs1_transform_node.local = layer_transform; + CopyProperties(render_surface1, render_surface2); + auto& render_surface2_transform_node = CreateTransformNode(render_surface2); + render_surface2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + render_surface2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f); + render_surface2_transform_node.local = layer_transform; + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface2, child_of_rs2); + auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2); + child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + child_of_rs2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f); + child_of_rs2_transform_node.local = layer_transform; + CopyProperties(child_of_rs2, grand_child_of_rs2); + auto& grand_child_of_rs2_transform_node = + CreateTransformNode(grand_child_of_rs2); + grand_child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + grand_child_of_rs2_transform_node.post_translation = + gfx::Vector2dF(2.5f, 0.f); + grand_child_of_rs2_transform_node.local = layer_transform; + CopyProperties(top, child_of_top); + auto& child_of_top_transform_node = CreateTransformNode(child_of_top); + child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + child_of_top_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f); + child_of_top_transform_node.local = layer_transform; + CopyProperties(child_of_top, grand_child_of_top); + auto& grand_child_of_top_transform_node = + CreateTransformNode(grand_child_of_top); + grand_child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f); + grand_child_of_top_transform_node.post_translation = + gfx::Vector2dF(2.5f, 0.f); + grand_child_of_top_transform_node.local = layer_transform; // Put an animated opacity on the render surface. AddOpacityTransitionToElementWithAnimation( render_surface1->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false); // Also put an animated opacity on a layer without descendants. - AddOpacityTransitionToElementWithAnimation(grand_child_of_root->element_id(), - timeline_impl(), 10.0, 1.f, 0.f, - false); + AddOpacityTransitionToElementWithAnimation( + grand_child_of_top->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false); // Put a transform animation on the render surface. AddAnimatedTransformToElementWithAnimation(render_surface2->element_id(), timeline_impl(), 10.0, 30, 0); - // Also put transform animations on grand_child_of_root, and + // Also put transform animations on grand_child_of_top, and // grand_child_of_rs2 - AddAnimatedTransformToElementWithAnimation(grand_child_of_root->element_id(), + AddAnimatedTransformToElementWithAnimation(grand_child_of_top->element_id(), timeline_impl(), 10.0, 30, 0); AddAnimatedTransformToElementWithAnimation(grand_child_of_rs2->element_id(), timeline_impl(), 10.0, 30, 0); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. ASSERT_TRUE(GetRenderSurface(root)); - ASSERT_EQ(GetRenderSurface(child_of_root), GetRenderSurface(root)); - ASSERT_EQ(GetRenderSurface(grand_child_of_root), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(top), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child_of_top), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(grand_child_of_top), GetRenderSurface(root)); ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root)); ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1)); @@ -2102,8 +2098,9 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { // Verify all render target accessors EXPECT_EQ(GetRenderSurface(root), root->render_target()); - EXPECT_EQ(GetRenderSurface(root), child_of_root->render_target()); - EXPECT_EQ(GetRenderSurface(root), grand_child_of_root->render_target()); + EXPECT_EQ(GetRenderSurface(root), top->render_target()); + EXPECT_EQ(GetRenderSurface(root), child_of_top->render_target()); + EXPECT_EQ(GetRenderSurface(root), grand_child_of_top->render_target()); EXPECT_EQ(GetRenderSurface(render_surface1), render_surface1->render_target()); @@ -2119,8 +2116,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { // Verify screen_space_transform_is_animating values EXPECT_FALSE(root->screen_space_transform_is_animating()); - EXPECT_FALSE(child_of_root->screen_space_transform_is_animating()); - EXPECT_TRUE(grand_child_of_root->screen_space_transform_is_animating()); + EXPECT_FALSE(child_of_top->screen_space_transform_is_animating()); + EXPECT_TRUE(grand_child_of_top->screen_space_transform_is_animating()); EXPECT_FALSE(render_surface1->screen_space_transform_is_animating()); EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating()); EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating()); @@ -2131,11 +2128,10 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { // Sanity check. If these fail there is probably a bug in the test itself. // It is expected that we correctly set up transforms so that the y-component // of the screen-space transform encodes the "depth" of the layer in the tree. - EXPECT_FLOAT_EQ(1.0, root->ScreenSpaceTransform().matrix().get(1, 3)); - EXPECT_FLOAT_EQ(2.0, - child_of_root->ScreenSpaceTransform().matrix().get(1, 3)); + EXPECT_FLOAT_EQ(1.0, top->ScreenSpaceTransform().matrix().get(1, 3)); + EXPECT_FLOAT_EQ(2.0, child_of_top->ScreenSpaceTransform().matrix().get(1, 3)); EXPECT_FLOAT_EQ( - 3.0, grand_child_of_root->ScreenSpaceTransform().matrix().get(1, 3)); + 3.0, grand_child_of_top->ScreenSpaceTransform().matrix().get(1, 3)); EXPECT_FLOAT_EQ(2.0, render_surface1->ScreenSpaceTransform().matrix().get(1, 3)); @@ -2152,18 +2148,23 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { TEST_F(LayerTreeHostCommonTest, LargeTransforms) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform large_transform; large_transform.Scale(SkDoubleToMScalar(1e37), SkDoubleToMScalar(1e37)); root->SetBounds(gfx::Size(10, 10)); - child->test_properties()->transform = large_transform; child->SetBounds(gfx::Size(10, 10)); - grand_child->test_properties()->transform = large_transform; grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child).local = large_transform; + CopyProperties(child, grand_child); + CreateTransformNode(grand_child).local = large_transform; + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); @@ -2184,9 +2185,9 @@ static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) { TEST_F(LayerTreeHostCommonTest, ScreenSpaceTransformIsAnimatingWithDelayedAnimation) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - LayerImpl* great_grand_child = AddChild<LayerImpl>(grand_child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* great_grand_child = AddLayer<LayerImpl>(); root->SetDrawsContent(true); child->SetDrawsContent(true); @@ -2200,6 +2201,12 @@ TEST_F(LayerTreeHostCommonTest, SetElementIdsForTesting(); + SetupRootProperties(root); + CopyProperties(root, child); + CopyProperties(child, grand_child); + CreateTransformNode(grand_child); // for animation. + CopyProperties(grand_child, great_grand_child); + // Add a transform animation with a start delay to |grand_child|. std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create( std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1, @@ -2208,6 +2215,7 @@ TEST_F(LayerTreeHostCommonTest, keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithAnimation( grand_child->element_id(), timeline_impl(), std::move(keyframe_model)); + ExecuteCalculateDrawProperties(root); EXPECT_FALSE(root->screen_space_transform_is_animating()); @@ -2219,10 +2227,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_TRUE(great_grand_child->screen_space_transform_is_animating()); } +// Test visible layer rect and drawable content rect are calculated correctly +// for identity transforms. TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { - // Test visible layer rect and drawable content rect are calculated correctly - // correctly for identity transforms. - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2257,10 +2264,9 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { drawing_layer->drawable_content_rect()); } +// Test visible layer rect and drawable content rect are calculated correctly +// for rotations about z-axis (i.e. 2D rotations). TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { - // Test visible layer rect and drawable content rect are calculated correctly - // for rotations about z-axis (i.e. 2D rotations). - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); gfx::Transform layer_to_surface_transform; @@ -2322,10 +2328,9 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { drawing_layer->drawable_content_rect()); } +// Test visible layer rect and drawable content rect are calculated correctly +// for 3d transforms. TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { - // Test visible layer rect and drawable content rect are calculated correctly - // for 3d transforms. - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2363,10 +2368,9 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { drawing_layer->drawable_content_rect()); } +// Test visible layer rect and drawable content rect are calculated correctly +// when the layer has a perspective projection onto the target surface. TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { - // Test visible layer rect and drawable content rect are calculated correctly - // when the layer has a perspective projection onto the target surface. - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200); gfx::Transform layer_to_surface_transform; @@ -2416,13 +2420,12 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { drawing_layer->drawable_content_rect()); } +// There is currently no explicit concept of an orthographic projection plane +// in our code (nor in the CSS spec to my knowledge). Therefore, layers that +// are technically behind the surface in an orthographic world should not be +// clipped when they are flattened to the surface. TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicIsNotClippedBehindSurface) { - // There is currently no explicit concept of an orthographic projection plane - // in our code (nor in the CSS spec to my knowledge). Therefore, layers that - // are technically behind the surface in an orthographic world should not be - // clipped when they are flattened to the surface. - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2445,17 +2448,16 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, drawing_layer->drawable_content_rect()); } +// Test visible layer rect and drawable content rect are calculated correctly +// when projecting a surface onto a layer, but the layer is partially behind +// the camera (not just behind the projection plane). In this case, the +// cartesian coordinates may seem to be valid, but actually they are not. The +// visible rect needs to be properly clipped by the w = 0 plane in homogeneous +// coordinates before converting to cartesian coordinates. The drawable +// content rect would be entire surface rect because layer is rotated at the +// camera position. TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveWhenClippedByW) { - // Test visible layer rect and drawable content rect are calculated correctly - // when projecting a surface onto a layer, but the layer is partially behind - // the camera (not just behind the projection plane). In this case, the - // cartesian coordinates may seem to be valid, but actually they are not. The - // visible rect needs to be properly clipped by the w = 0 plane in homogeneous - // coordinates before converting to cartesian coordinates. The drawable - // content rect would be entire surface rect because layer is rotated at the - // camera position. - gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2); gfx::Transform layer_to_surface_transform; @@ -2474,8 +2476,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, // transform, otherwise this code is not testing the intended scenario. bool clipped; MathUtil::MapQuad(layer_to_surface_transform, - gfx::QuadF(gfx::RectF(layer_content_rect)), - &clipped); + gfx::QuadF(gfx::RectF(layer_content_rect)), &clipped); ASSERT_TRUE(clipped); gfx::Rect expected_visible_layer_rect = gfx::Rect(0, 1, 10, 1); @@ -2502,13 +2503,12 @@ static bool ProjectionClips(const gfx::Transform& map_transform, return clipped; } +// To determine visible rect in layer space, there needs to be an +// un-projection from surface space to layer space. When the original +// transform was a perspective projection that was clipped, it returns a rect +// that encloses the clipped bounds. Un-projecting this new rect may require +// clipping again. 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 - // transform was a perspective projection that was clipped, it returns a rect - // that encloses the clipped bounds. Un-projecting this new rect may require - // clipping again. - // This sequence of transforms causes one corner of the layer to protrude // across the w = 0 plane, and should be clipped. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150); @@ -2542,19 +2542,25 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child1_layer = AddChildToRoot<LayerImpl>(); - LayerImpl* child2_layer = AddChildToRoot<LayerImpl>(); - LayerImpl* child3_layer = AddChildToRoot<LayerImpl>(); + LayerImpl* child1_layer = AddLayer<LayerImpl>(); + LayerImpl* child2_layer = AddLayer<LayerImpl>(); + LayerImpl* child3_layer = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); child1_layer->SetBounds(gfx::Size(50, 50)); child1_layer->SetDrawsContent(true); - child2_layer->test_properties()->position = gfx::PointF(75.f, 75.f); child2_layer->SetBounds(gfx::Size(50, 50)); child2_layer->SetDrawsContent(true); - child3_layer->test_properties()->position = gfx::PointF(125.f, 125.f); child3_layer->SetBounds(gfx::Size(50, 50)); child3_layer->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child1_layer); + CopyProperties(root, child2_layer); + child2_layer->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(root, child3_layer); + child3_layer->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(100.f, 100.f), @@ -2577,23 +2583,31 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForLayersClippedByLayer) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child1 = AddChild<LayerImpl>(child); - LayerImpl* grand_child2 = AddChild<LayerImpl>(child); - LayerImpl* grand_child3 = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + LayerImpl* grand_child2 = AddLayer<LayerImpl>(); + LayerImpl* grand_child3 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); - grand_child1->test_properties()->position = gfx::PointF(5.f, 5.f); grand_child1->SetBounds(gfx::Size(50, 50)); grand_child1->SetDrawsContent(true); - grand_child2->test_properties()->position = gfx::PointF(75.f, 75.f); grand_child2->SetBounds(gfx::Size(50, 50)); grand_child2->SetDrawsContent(true); - grand_child3->test_properties()->position = gfx::PointF(125.f, 125.f); grand_child3->SetBounds(gfx::Size(50, 50)); grand_child3->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateClipNode(child); + CopyProperties(child, grand_child1); + grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(child, grand_child2); + grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(child, grand_child3); + grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(100.f, 100.f), @@ -2616,8 +2630,8 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform child_scale_matrix; child_scale_matrix.Scale(0.25f, 0.25f); @@ -2625,47 +2639,62 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { grand_child_scale_matrix.Scale(0.246f, 0.246f); root->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = child_scale_matrix; child->SetBounds(gfx::Size(10, 10)); child->SetMasksToBounds(true); - grand_child->test_properties()->transform = grand_child_scale_matrix; grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child).local = child_scale_matrix; + CreateClipNode(child); + CopyProperties(child, grand_child); + CreateTransformNode(grand_child).local = grand_child_scale_matrix; + ExecuteCalculateDrawProperties(root); // The visible rect is expanded to integer coordinates. EXPECT_EQ(gfx::Rect(41, 41), grand_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip = AddChild<LayerImpl>(root); - LayerImpl* filter = AddChild<LayerImpl>(clip); - LayerImpl* filter_child = AddChild<LayerImpl>(filter); +// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip +// node for pixel-moving filter). +TEST_F(LayerTreeHostCommonTestWithLayerTree, + VisibleRectWithClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto clip = Layer::Create(); + root->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); root->SetBounds(gfx::Size(100, 100)); clip->SetBounds(gfx::Size(10, 10)); - filter->test_properties()->force_render_surface = true; + filter->SetForceRenderSurfaceForTesting(true); filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->test_properties()->position = gfx::PointF(-50, -50); - filter_child->SetDrawsContent(true); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); clip->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), filter_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurface(filter)->content_rect()); + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect()); FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->test_properties()->filters = blur_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + filter->SetFilters(blur_filter); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), filter_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), - GetRenderSurface(filter)->content_rect()); + GetRenderSurfaceImpl(filter)->content_rect()); gfx::Transform vertical_flip; vertical_flip.Scale(1, -1); @@ -2675,50 +2704,60 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) { reflection_filter.Append( FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->test_properties()->filters = reflection_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + filter->SetFilters(reflection_filter); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), filter_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-1, -11, 12, 21), - GetRenderSurface(filter)->content_rect()); + GetRenderSurfaceImpl(filter)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* scale = AddChild<LayerImpl>(root); - LayerImpl* clip = AddChild<LayerImpl>(scale); - LayerImpl* filter = AddChild<LayerImpl>(clip); - LayerImpl* filter_child = AddChild<LayerImpl>(filter); +// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip +// node for pixel-moving filter). +TEST_F(LayerTreeHostCommonTestWithLayerTree, + VisibleRectWithScalingClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto scale = Layer::Create(); + root->AddChild(scale); + auto clip = Layer::Create(); + scale->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); root->SetBounds(gfx::Size(100, 100)); clip->SetBounds(gfx::Size(10, 10)); - filter->test_properties()->force_render_surface = true; + filter->SetForceRenderSurfaceForTesting(true); filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->test_properties()->position = gfx::PointF(-50, -50); - filter_child->SetDrawsContent(true); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); clip->SetMasksToBounds(true); gfx::Transform scale_transform; scale_transform.Scale(3, 3); - scale->test_properties()->transform = scale_transform; + scale->SetTransform(scale_transform); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), filter_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurface(filter)->content_rect()); + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect()); FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->test_properties()->filters = blur_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + filter->SetFilters(blur_filter); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), filter_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), - GetRenderSurface(filter)->content_rect()); + GetRenderSurfaceImpl(filter)->content_rect()); gfx::Transform vertical_flip; vertical_flip.Scale(1, -1); @@ -2728,82 +2767,73 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { reflection_filter.Append( FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->test_properties()->filters = reflection_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + filter->SetFilters(reflection_filter); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), filter_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-1, -31, 32, 61), - GetRenderSurface(filter)->content_rect()); + GetRenderSurfaceImpl(filter)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParentAndFilters) { +TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip = AddChild<LayerImpl>(root); - LayerImpl* filter = AddChild<LayerImpl>(clip); - LayerImpl* filter_child_1 = AddChild<LayerImpl>(filter); - LayerImpl* filter_child_2 = AddChild<LayerImpl>(filter); + LayerImpl* clip = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - clip->SetBounds(gfx::Size(10, 10)); - filter->test_properties()->force_render_surface = true; - - filter_child_1->SetBounds(gfx::Size(20, 20)); - filter_child_1->SetDrawsContent(true); - filter_child_2->SetBounds(gfx::Size(20, 20)); - filter_child_2->SetDrawsContent(true); - - root->SetMasksToBounds(true); - clip->SetMasksToBounds(true); + SetupRootProperties(root); + CreateClipNode(root); - root->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - root->test_properties()->clip_children->insert(filter_child_1); - filter_child_1->test_properties()->clip_parent = root; + clip->SetBounds(gfx::Size(10, 10)); + CopyProperties(root, clip); + CreateClipNode(clip); - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(filter_child_1->is_clipped()); - EXPECT_TRUE(filter_child_2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), filter_child_1->clip_rect()); - EXPECT_EQ(gfx::Rect(10, 10), filter_child_2->clip_rect()); + child1->SetBounds(gfx::Size(20, 20)); + child1->SetDrawsContent(true); + CopyProperties(clip, child1); + child1->SetClipTreeIndex(root->clip_tree_index()); - FilterOperations blur_filter; - blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->test_properties()->filters = blur_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + child2->SetBounds(gfx::Size(20, 20)); + child2->SetDrawsContent(true); + CopyProperties(clip, child2); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(filter_child_1->is_clipped()); - EXPECT_TRUE(filter_child_2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), filter_child_1->clip_rect()); - EXPECT_EQ(gfx::Rect(10, 10), filter_child_2->clip_rect()); + EXPECT_TRUE(child1->is_clipped()); + EXPECT_TRUE(child2->is_clipped()); + EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect()); + EXPECT_EQ(gfx::Rect(10, 10), child2->clip_rect()); } TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* filter = AddChild<LayerImpl>(root); - LayerImpl* clip = AddChild<LayerImpl>(filter); - LayerImpl* filter_grand_child = AddChild<LayerImpl>(clip); + LayerImpl* filter = AddLayer<LayerImpl>(); + LayerImpl* clip = AddLayer<LayerImpl>(); + LayerImpl* filter_grand_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - filter->test_properties()->force_render_surface = true; - clip->SetBounds(gfx::Size(10, 10)); clip->SetMasksToBounds(true); - filter_grand_child->SetBounds(gfx::Size(20, 20)); filter_grand_child->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, filter); + CreateEffectNode(filter).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(filter, clip); + CreateClipNode(clip); + CopyProperties(clip, filter_grand_child); + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(filter_grand_child->is_clipped()); EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect()); FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->test_properties()->filters = blur_filter; - host_impl()->active_tree()->property_trees()->needs_rebuild = true; + SetFilter(filter, blur_filter); ExecuteCalculateDrawProperties(root); @@ -2814,23 +2844,31 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface); - LayerImpl* child2 = AddChild<LayerImpl>(render_surface); - LayerImpl* child3 = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* child3 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); render_surface->SetBounds(gfx::Size(3, 4)); - render_surface->test_properties()->force_render_surface = true; - child1->test_properties()->position = gfx::PointF(5.f, 5.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child2->test_properties()->position = gfx::PointF(75.f, 75.f); child2->SetBounds(gfx::Size(50, 50)); child2->SetDrawsContent(true); - child3->test_properties()->position = gfx::PointF(125.f, 125.f); child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(render_surface, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(render_surface, child3); + child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -2861,25 +2899,30 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child1 = AddChild<LayerImpl>(root); - LayerImpl* child2 = AddChild<LayerImpl>(root); - LayerImpl* child3 = AddChild<LayerImpl>(root); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* child3 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - child1->test_properties()->position = gfx::PointF(5.f, 5.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child2->test_properties()->position = gfx::PointF(75.f, 75.f); child2->SetBounds(gfx::Size(50, 50)); child2->SetDrawsContent(true); - child3->test_properties()->position = gfx::PointF(125.f, 125.f); child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(root, child3); + child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + RenderSurfaceList render_surface_list_impl; // Now set the root render surface an empty clip. LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(), &render_surface_list_impl); + root, gfx::Rect(), &render_surface_list_impl); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(GetRenderSurface(root)); @@ -2900,10 +2943,9 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - child->test_properties()->position = gfx::PointF(5.f, 5.f); child->SetBounds(gfx::Size(50, 50)); child->SetDrawsContent(true); @@ -2911,7 +2953,10 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); ASSERT_FALSE(uninvertible_matrix.IsInvertible()); - child->test_properties()->transform = uninvertible_matrix; + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child).local = uninvertible_matrix; + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); @@ -2923,7 +2968,7 @@ TEST_F(LayerTreeHostCommonTest, uninvertible_matrix.matrix().set(2, 2, 0.0); ASSERT_FALSE(uninvertible_matrix.IsInvertible()); - child->test_properties()->transform = uninvertible_matrix; + SetTransform(child, uninvertible_matrix); ExecuteCalculateDrawProperties(root); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); @@ -2935,7 +2980,7 @@ TEST_F(LayerTreeHostCommonTest, uninvertible_matrix.matrix().set(2, 2, 0.0); ASSERT_FALSE(uninvertible_matrix.IsInvertible()); - child->test_properties()->transform = uninvertible_matrix; + SetTransform(child, uninvertible_matrix); ExecuteCalculateDrawProperties(root); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); @@ -2945,8 +2990,8 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, VisibleContentRectForLayerWithUninvertibleDrawTransform) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); gfx::Transform perspective; perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12)); @@ -2955,56 +3000,49 @@ TEST_F(LayerTreeHostCommonTest, rotation.RotateAboutYAxis(45.0); root->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = perspective; - child->test_properties()->position = gfx::PointF(10.f, 10.f); child->SetBounds(gfx::Size(100, 100)); child->SetDrawsContent(true); - child->test_properties()->sorting_context_id = 1; - child->test_properties()->should_flatten_transform = false; - grand_child->test_properties()->transform = rotation; grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - child->test_properties()->sorting_context_id = 1; - grand_child->test_properties()->should_flatten_transform = false; - grand_child->test_properties()->sorting_context_id = 1; + + SetupRootProperties(root); + CopyProperties(root, child); + auto& child_transform_node = CreateTransformNode(child); + child_transform_node.flattens_inherited_transform = false; + child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f); + child_transform_node.sorting_context_id = 1; + child_transform_node.local = perspective; + CopyProperties(child, grand_child); + auto& grand_child_transform_node = CreateTransformNode(grand_child); + grand_child_transform_node.flattens_inherited_transform = false; + grand_child_transform_node.sorting_context_id = 1; + grand_child_transform_node.local = rotation; + ExecuteCalculateDrawProperties(root); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. - EXPECT_FALSE(root->layer_tree_impl() - ->property_trees() - ->transform_tree.Node(grand_child->transform_tree_index()) - ->ancestors_are_invertible); + EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible); // CalcDrawProps skips a subtree when a layer's screen space transform is // uninvertible EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<TextureLayerImpl> surface = - TextureLayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<TextureLayerImpl> surface_child = - TextureLayerImpl::Create(host_impl.active_tree(), 4); - std::unique_ptr<TextureLayerImpl> surface_sibling = - TextureLayerImpl::Create(host_impl.active_tree(), 5); - std::unique_ptr<TextureLayerImpl> surface_child_mask = - TextureLayerImpl::Create(host_impl.active_tree(), 6); - - surface->SetDrawsContent(true); - surface_child->SetDrawsContent(true); - surface_sibling->SetDrawsContent(true); - surface_child_mask->SetDrawsContent(true); +// Needs layer tree mode: mask layer. +TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { + auto root = Layer::Create(); + auto child = Layer::Create(); + FakeContentLayerClient client; + auto surface = PictureLayer::Create(&client); + auto surface_child = PictureLayer::Create(&client); + auto surface_sibling = PictureLayer::Create(&client); + auto surface_child_mask = PictureLayer::Create(&client); + + surface->SetIsDrawable(true); + surface_child->SetIsDrawable(true); + surface_sibling->SetIsDrawable(true); + surface_child_mask->SetIsDrawable(true); surface->SetContentsOpaque(true); surface_child->SetContentsOpaque(true); surface_sibling->SetContentsOpaque(true); @@ -3015,102 +3053,73 @@ TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { root->SetBounds(gfx::Size(1000, 1000)); child->SetBounds(gfx::Size(300, 300)); - surface->test_properties()->transform = translate; + surface->SetTransform(translate); surface->SetBounds(gfx::Size(300, 300)); - surface->test_properties()->force_render_surface = true; + surface->SetForceRenderSurfaceForTesting(true); surface_child->SetBounds(gfx::Size(300, 300)); - surface_child->test_properties()->force_render_surface = true; + surface_child->SetForceRenderSurfaceForTesting(true); surface_sibling->SetBounds(gfx::Size(200, 200)); + surface_child_mask->SetBounds(gfx::Size(300, 300)); - LayerImpl* surface_ptr = surface.get(); - LayerImpl* surface_child_ptr = surface_child.get(); - LayerImpl* surface_child_mask_ptr = surface_child_mask.get(); - - host_impl.active_tree()->SetDeviceViewportSize(root->bounds()); + surface_child->SetMaskLayer(surface_child_mask); + surface->AddChild(surface_child); + child->AddChild(surface); + child->AddChild(surface_sibling); + root->AddChild(child); + host()->SetRootLayer(root); - surface_child->test_properties()->SetMaskLayer(std::move(surface_child_mask)); - surface->test_properties()->AddChild(std::move(surface_child)); - child->test_properties()->AddChild(std::move(surface)); - child->test_properties()->AddChild(std::move(surface_sibling)); - root->test_properties()->AddChild(std::move(child)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); + CommitAndActivate(); + host_impl()->active_tree()->UpdateDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( - GetRenderSurface(surface_ptr)->draw_transform(), translate); + GetRenderSurfaceImpl(surface)->draw_transform(), translate); // surface_sibling draws into the root render surface and occludes // surface_child's contents. Occlusion actual_occlusion = - GetRenderSurface(surface_child_ptr)->occlusion_in_content_space(); + GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space(); Occlusion expected_occlusion(translate, SimpleEnclosedRegion(gfx::Rect()), SimpleEnclosedRegion(gfx::Rect(200, 200))); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); // Mask layer should have the same occlusion. actual_occlusion = - surface_child_mask_ptr->draw_properties().occlusion_in_content_space; + ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space; EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); } -TEST_F(LayerTreeHostCommonTest, TextureLayerSnapping) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<TextureLayerImpl> child = - TextureLayerImpl::Create(host_impl.active_tree(), 2); - - LayerImpl* child_ptr = child.get(); +// Needs layer tree mode: testing PropertyTreeBuilder (snapping transform for +// texture layer). +TEST_F(LayerTreeHostCommonTestWithLayerTree, TextureLayerSnapping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = TextureLayer::CreateForMailbox(nullptr); + root->AddChild(child); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(100, 100)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); gfx::Transform fractional_translate; fractional_translate.Translate(10.5f, 20.3f); - child->test_properties()->transform = fractional_translate; + child->SetTransform(fractional_translate); - host_impl.active_tree()->SetDeviceViewportSize(root->bounds()); + CommitAndActivate(); - root->test_properties()->AddChild(std::move(child)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); - - EXPECT_NE(child_ptr->ScreenSpaceTransform(), fractional_translate); + auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform(); + EXPECT_NE(child_screen_space_transform, fractional_translate); fractional_translate.RoundTranslationComponents(); - EXPECT_TRANSFORMATION_MATRIX_EQ(child_ptr->ScreenSpaceTransform(), + EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, fractional_translate); - gfx::RectF layer_bounds_in_screen_space = - MathUtil::MapClippedRect(child_ptr->ScreenSpaceTransform(), - gfx::RectF(gfx::SizeF(child_ptr->bounds()))); + gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect( + child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds()))); EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); } TEST_F(LayerTreeHostCommonTest, OcclusionForLayerWithUninvertibleDrawTransform) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<LayerImpl> occluding_child = - LayerImpl::Create(host_impl.active_tree(), 4); + LayerImpl* root = root_layer_for_testing(); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* occluding_child = AddLayer<LayerImpl>(); gfx::Transform perspective; perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12)); @@ -3119,48 +3128,35 @@ TEST_F(LayerTreeHostCommonTest, rotation.RotateAboutYAxis(45.0); root->SetBounds(gfx::Size(1000, 1000)); - child->test_properties()->transform = perspective; - child->test_properties()->position = gfx::PointF(10.f, 10.f); child->SetBounds(gfx::Size(300, 300)); - child->test_properties()->should_flatten_transform = false; - child->test_properties()->sorting_context_id = 1; - grand_child->test_properties()->transform = rotation; grand_child->SetBounds(gfx::Size(200, 200)); - grand_child->test_properties()->should_flatten_transform = false; - grand_child->test_properties()->sorting_context_id = 1; occluding_child->SetBounds(gfx::Size(200, 200)); - occluding_child->test_properties()->should_flatten_transform = false; child->SetDrawsContent(true); grand_child->SetDrawsContent(true); occluding_child->SetDrawsContent(true); occluding_child->SetContentsOpaque(true); - host_impl.active_tree()->SetDeviceViewportSize(root->bounds()); - - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - root->test_properties()->AddChild(std::move(occluding_child)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); + SetupRootProperties(root); + CopyProperties(root, child); + auto& child_transform_node = CreateTransformNode(child); + child_transform_node.flattens_inherited_transform = false; + child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f); + child_transform_node.sorting_context_id = 1; + child_transform_node.local = perspective; + CopyProperties(child, grand_child); + auto& grand_child_transform_node = CreateTransformNode(grand_child); + grand_child_transform_node.flattens_inherited_transform = false; + grand_child_transform_node.sorting_context_id = 1; + grand_child_transform_node.local = rotation; + CopyProperties(root, occluding_child); + CreateTransformNode(occluding_child).flattens_inherited_transform = false; - LayerImpl* grand_child_ptr = host_impl.active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->test_properties() - ->children[0]; + ExecuteCalculateDrawProperties(root); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. - EXPECT_FALSE( - host_impl.active_tree() - ->property_trees() - ->transform_tree.Node(grand_child_ptr->transform_tree_index()) - ->ancestors_are_invertible); + EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible); // Since |grand_child| has an uninvertible screen space transform, it is // skipped so @@ -3168,31 +3164,40 @@ TEST_F(LayerTreeHostCommonTest, gfx::Rect layer_bounds = gfx::Rect(); EXPECT_EQ( layer_bounds, - grand_child_ptr->draw_properties() + grand_child->draw_properties() .occlusion_in_content_space.GetUnoccludedContentRect(layer_bounds)); } TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface); - LayerImpl* child2 = AddChild<LayerImpl>(render_surface); - LayerImpl* child3 = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* child3 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); root->SetMasksToBounds(true); render_surface->SetBounds(gfx::Size(3, 4)); - render_surface->test_properties()->force_render_surface = true; - child1->test_properties()->position = gfx::PointF(5.f, 5.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child2->test_properties()->position = gfx::PointF(75.f, 75.f); child2->SetBounds(gfx::Size(50, 50)); child2->SetDrawsContent(true); - child3->test_properties()->position = gfx::PointF(125.f, 125.f); child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(render_surface, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(render_surface, child3); + child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3221,31 +3226,42 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); } +// Check that clipping does not propagate down surfaces. TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSurfaceHierarchy) { - // Check that clipping does not propagate down surfaces. LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface2 = AddChild<LayerImpl>(render_surface1); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface2); - LayerImpl* child2 = AddChild<LayerImpl>(render_surface2); - LayerImpl* child3 = AddChild<LayerImpl>(render_surface2); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* child3 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); root->SetMasksToBounds(true); render_surface1->SetBounds(gfx::Size(3, 4)); - render_surface1->test_properties()->force_render_surface = true; render_surface2->SetBounds(gfx::Size(7, 13)); - render_surface2->test_properties()->force_render_surface = true; - child1->test_properties()->position = gfx::PointF(5.f, 5.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child2->test_properties()->position = gfx::PointF(75.f, 75.f); child2->SetBounds(gfx::Size(50, 50)); child2->SetDrawsContent(true); - child3->test_properties()->position = gfx::PointF(125.f, 125.f); child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, render_surface1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface2, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(render_surface2, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(render_surface2, child3); + child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(render_surface1)); @@ -3285,24 +3301,35 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, VisibleRectsForClippedDescendantsOfUnclippedSurfaces) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface1); - LayerImpl* child2 = AddChild<LayerImpl>(child1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(child2); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + LayerImpl* child2 = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); render_surface1->SetBounds(gfx::Size(100, 100)); - render_surface1->test_properties()->force_render_surface = true; child1->SetBounds(gfx::Size(500, 500)); child1->SetDrawsContent(true); child2->SetBounds(gfx::Size(700, 700)); child2->SetDrawsContent(true); render_surface2->SetBounds(gfx::Size(1000, 1000)); - render_surface2->test_properties()->force_render_surface = true; render_surface2->SetDrawsContent(true); child1->SetMasksToBounds(true); child2->SetMasksToBounds(true); + + SetupRootProperties(root); + CopyProperties(root, render_surface1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, child1); + CreateClipNode(child1); + CopyProperties(child1, child2); + CreateClipNode(child2); + CopyProperties(child2, render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(100, 100), child1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect()); @@ -3311,31 +3338,35 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(clip_child); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); clip_parent->SetBounds(gfx::Size(50, 50)); - clip_parent->SetMasksToBounds(true); - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); render_surface1->SetBounds(gfx::Size(20, 20)); - render_surface1->SetMasksToBounds(true); render_surface1->SetDrawsContent(true); - render_surface1->test_properties()->force_render_surface = true; + CopyProperties(clip_parent, render_surface1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface1); clip_child->SetBounds(gfx::Size(60, 60)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; + CopyProperties(render_surface1, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); render_surface2->SetBounds(gfx::Size(60, 60)); render_surface2->SetDrawsContent(true); - render_surface2->test_properties()->force_render_surface = true; + CopyProperties(clip_child, render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(20, 20), render_surface1->visible_layer_rect()); @@ -3345,59 +3376,71 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - 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); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - clip_parent->test_properties()->position = gfx::PointF(2.f, 2.f); clip_parent->SetBounds(gfx::Size(50, 50)); - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(2, 2)); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); clip_layer->SetBounds(gfx::Size(50, 50)); + clip_layer->SetOffsetToTransformParent(gfx::Vector2dF(2, 2)); + CopyProperties(clip_parent, clip_layer); + CreateClipNode(clip_layer); render_surface1->SetBounds(gfx::Size(20, 20)); render_surface1->SetDrawsContent(true); - render_surface1->test_properties()->force_render_surface = true; + CopyProperties(clip_layer, render_surface1); + CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(2, 2); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface1); clip_child->SetBounds(gfx::Size(60, 60)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; + CopyProperties(render_surface1, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); render_surface2->SetBounds(gfx::Size(60, 60)); render_surface2->SetDrawsContent(true); - render_surface2->test_properties()->force_render_surface = true; - - clip_parent->SetMasksToBounds(true); - clip_layer->SetMasksToBounds(true); - render_surface1->SetMasksToBounds(true); + CopyProperties(clip_child, render_surface2); + CreateTransformNode(render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; float device_scale_factor = 1.f; ExecuteCalculateDrawProperties(root, device_scale_factor); EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect()); + device_scale_factor = 2.f; ExecuteCalculateDrawProperties(root, device_scale_factor); EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(render_surface2)->clip_rect()); } +// Test that only drawn layers contribute to render surface content rect. TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { - // Test that only drawn layers contribute to render surface content rect. LayerImpl* root = root_layer_for_testing(); - LayerImpl* surface = AddChildToRoot<LayerImpl>(); - LayerImpl* test_layer = AddChild<LayerImpl>(surface); + LayerImpl* surface = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(200, 200)); surface->SetBounds(gfx::Size(100, 100)); surface->SetDrawsContent(true); - surface->test_properties()->force_render_surface = true; test_layer->SetBounds(gfx::Size(150, 150)); + SetupRootProperties(root); + CopyProperties(root, surface); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(surface, test_layer); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect()); @@ -3406,41 +3449,42 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect()); } +// Tests visible rects computation when we have unclipped_surface-> +// surface_with_unclipped_descendants->clipped_surface, checks that the bounds +// of surface_with_unclipped_descendants doesn't propagate to the +// clipped_surface below it. TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { - // Tests visible rects computation when we have unclipped_surface-> - // surface_with_unclipped_descendants->clipped_surface, checks that the bounds - // of surface_with_unclipped_descendants doesn't propagate to the - // clipped_surface below it. 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_child = AddChild<LayerImpl>(unclipped_desc_surface); - LayerImpl* clipped_surface = AddChild<LayerImpl>(clip_child); + LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* clipped_surface = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - unclipped_surface->SetBounds(gfx::Size(30, 30)); unclipped_surface->SetDrawsContent(true); - unclipped_surface->test_properties()->force_render_surface = true; - clip_parent->SetBounds(gfx::Size(50, 50)); - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); - unclipped_desc_surface->SetBounds(gfx::Size(20, 20)); unclipped_desc_surface->SetDrawsContent(true); - unclipped_desc_surface->test_properties()->force_render_surface = true; - clip_child->SetBounds(gfx::Size(60, 60)); - clip_child->test_properties()->clip_parent = clip_parent; - + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); clipped_surface->SetBounds(gfx::Size(60, 60)); clipped_surface->SetDrawsContent(true); - clipped_surface->test_properties()->force_render_surface = true; - clip_parent->SetMasksToBounds(true); + SetupRootProperties(root); + CopyProperties(root, unclipped_surface); + CreateEffectNode(unclipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_surface, clip_parent); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, unclipped_desc_surface); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface, clip_child); + CopyProperties(clip_child, clipped_surface); + CreateEffectNode(clipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 30), unclipped_surface->visible_layer_rect()); @@ -3448,41 +3492,43 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { EXPECT_EQ(gfx::Rect(50, 50), clipped_surface->visible_layer_rect()); } +// Tests visible rects computation when we have unclipped_surface-> +// surface_with_unclipped_descendants->clipped_surface, checks that the bounds +// of root propagate to the clipped_surface. TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { - // Tests visible rects computation when we have unclipped_surface-> - // surface_with_unclipped_descendants->clipped_surface, checks that the bounds - // of root propagate to the clipped_surface. 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_child = AddChild<LayerImpl>(unclipped_desc_surface); - LayerImpl* clipped_surface = AddChild<LayerImpl>(clip_child); + LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* clipped_surface = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(10, 10)); - unclipped_surface->SetBounds(gfx::Size(50, 50)); unclipped_surface->SetDrawsContent(true); - unclipped_surface->test_properties()->force_render_surface = true; - clip_parent->SetBounds(gfx::Size(50, 50)); - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); - unclipped_desc_surface->SetBounds(gfx::Size(100, 100)); unclipped_desc_surface->SetDrawsContent(true); - unclipped_desc_surface->test_properties()->force_render_surface = true; - clip_child->SetBounds(gfx::Size(100, 100)); - clip_child->test_properties()->clip_parent = clip_parent; - clipped_surface->SetBounds(gfx::Size(50, 50)); clipped_surface->SetDrawsContent(true); clipped_surface->test_properties()->force_render_surface = true; - clip_parent->SetMasksToBounds(true); - unclipped_desc_surface->SetMasksToBounds(true); + SetupRootProperties(root); + CopyProperties(root, unclipped_surface); + CreateEffectNode(unclipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_surface, clip_parent); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, unclipped_desc_surface); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(unclipped_desc_surface); + CopyProperties(unclipped_desc_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + CopyProperties(clip_child, clipped_surface); + CreateEffectNode(clipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(10, 10), unclipped_surface->visible_layer_rect()); @@ -3490,25 +3536,32 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { EXPECT_EQ(gfx::Rect(10, 10), clipped_surface->visible_layer_rect()); } +// Layers that have non-axis aligned bounds (due to transforms) have an +// expanded, axis-aligned DrawableContentRect and visible content rect. TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) { - // Layers that have non-axis aligned bounds (due to transforms) have an - // expanded, axis-aligned DrawableContentRect and visible content rect. LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); gfx::Transform child_rotation; child_rotation.Rotate(45.0); root->SetBounds(gfx::Size(100, 100)); render_surface->SetBounds(gfx::Size(3, 4)); - render_surface->test_properties()->force_render_surface = true; - child1->test_properties()->transform = child_rotation; - child1->test_properties()->position = gfx::PointF(25.f, 25.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child1->test_properties()->transform_origin = gfx::Point3F(25.f, 25.f, 0.f); + + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, child1); + auto& child1_transform_node = CreateTransformNode(child1); + child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f); + child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); + child1_transform_node.local = child_rotation; + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3536,13 +3589,13 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(expected_surface_drawable_content, child1->drawable_content_rect()); } +// Layers that have non-axis aligned bounds (due to transforms) have an +// expanded, axis-aligned DrawableContentRect and visible content rect. TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsWithTransformOnClippedSurface) { - // Layers that have non-axis aligned bounds (due to transforms) have an - // expanded, axis-aligned DrawableContentRect and visible content rect. LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* child1 = AddLayer<LayerImpl>(); gfx::Transform child_rotation; child_rotation.Rotate(45.0); @@ -3550,12 +3603,20 @@ TEST_F(LayerTreeHostCommonTest, root->SetBounds(gfx::Size(50, 50)); root->SetMasksToBounds(true); render_surface->SetBounds(gfx::Size(3, 4)); - render_surface->test_properties()->force_render_surface = true; - child1->test_properties()->position = gfx::PointF(25.f, 25.f); child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - child1->test_properties()->transform = child_rotation; - child1->test_properties()->transform_origin = gfx::Point3F(25.f, 25.f, 0.f); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, child1); + auto& child1_transform_node = CreateTransformNode(child1); + child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f); + child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); + child1_transform_node.local = child_rotation; + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3583,36 +3644,44 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { LayerImpl* root = root_layer_for_testing(); - FakePictureLayerImpl* render_surface1 = - AddChildToRoot<FakePictureLayerImpl>(); - FakePictureLayerImpl* render_surface2 = - AddChild<FakePictureLayerImpl>(render_surface1); - FakePictureLayerImpl* child1 = - AddChild<FakePictureLayerImpl>(render_surface2); - FakePictureLayerImpl* child2 = - AddChild<FakePictureLayerImpl>(render_surface2); - FakePictureLayerImpl* child3 = - AddChild<FakePictureLayerImpl>(render_surface2); + FakePictureLayerImpl* render_surface1 = AddLayer<FakePictureLayerImpl>(); + FakePictureLayerImpl* render_surface2 = AddLayer<FakePictureLayerImpl>(); + FakePictureLayerImpl* child1 = AddLayer<FakePictureLayerImpl>(); + FakePictureLayerImpl* child2 = AddLayer<FakePictureLayerImpl>(); + FakePictureLayerImpl* child3 = AddLayer<FakePictureLayerImpl>(); root->SetBounds(gfx::Size(100, 100)); root->SetMasksToBounds(true); render_surface1->SetBounds(gfx::Size(3, 4)); - render_surface1->test_properties()->position = gfx::PointF(5.f, 5.f); render_surface1->SetDrawsContent(true); - render_surface1->test_properties()->force_render_surface = true; render_surface2->SetBounds(gfx::Size(7, 13)); - render_surface2->test_properties()->position = gfx::PointF(5.f, 5.f); render_surface2->SetDrawsContent(true); - render_surface2->test_properties()->force_render_surface = true; child1->SetBounds(gfx::Size(50, 50)); - child1->test_properties()->position = gfx::PointF(5.f, 5.f); child1->SetDrawsContent(true); child2->SetBounds(gfx::Size(50, 50)); - child2->test_properties()->position = gfx::PointF(75.f, 75.f); child2->SetDrawsContent(true); child3->SetBounds(gfx::Size(50, 50)); - child3->test_properties()->position = gfx::PointF(125.f, 125.f); child3->SetDrawsContent(true); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, render_surface1); + CreateTransformNode(render_surface1).post_translation = + gfx::Vector2dF(5.f, 5.f); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, render_surface2); + CreateTransformNode(render_surface2).post_translation = + gfx::Vector2dF(5.f, 5.f); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface2, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); + CopyProperties(render_surface2, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); + CopyProperties(render_surface2, child3); + child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); + float device_scale_factor = 2.f; ExecuteCalculateDrawProperties(root, device_scale_factor); @@ -3647,48 +3716,50 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { - // Verify the behavior of back-face culling when there are no preserve-3d - // layers. Note that 3d transforms still apply in this case, but they are - // "flattened" to each parent layer according to current W3C spec. - - LayerImpl* root = root_layer_for_testing(); - LayerImpl* front_facing_child = AddChildToRoot<LayerImpl>(); - LayerImpl* back_facing_child = AddChildToRoot<LayerImpl>(); - LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* front_facing_child_of_front_facing_surface = - AddChild<LayerImpl>(front_facing_surface); - LayerImpl* back_facing_child_of_front_facing_surface = - AddChild<LayerImpl>(front_facing_surface); - LayerImpl* front_facing_child_of_back_facing_surface = - AddChild<LayerImpl>(back_facing_surface); - LayerImpl* back_facing_child_of_back_facing_surface = - AddChild<LayerImpl>(back_facing_surface); +// Verify the behavior of back-face culling when there are no preserve-3d +// layers. Note that 3d transforms still apply in this case, but they are +// "flattened" to each parent layer according to current W3C spec. +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + BackFaceCullingWithoutPreserves3d) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto front_facing_child = Layer::Create(); + root->AddChild(front_facing_child); + auto back_facing_child = Layer::Create(); + root->AddChild(back_facing_child); + auto front_facing_surface = Layer::Create(); + root->AddChild(front_facing_surface); + auto back_facing_surface = Layer::Create(); + root->AddChild(back_facing_surface); + auto front_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); + auto back_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); + auto front_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); + auto back_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); // Nothing is double-sided - front_facing_child->test_properties()->double_sided = false; - back_facing_child->test_properties()->double_sided = false; - front_facing_surface->test_properties()->double_sided = false; - back_facing_surface->test_properties()->double_sided = false; - front_facing_child_of_front_facing_surface->test_properties()->double_sided = - false; - back_facing_child_of_front_facing_surface->test_properties()->double_sided = - false; - front_facing_child_of_back_facing_surface->test_properties()->double_sided = - false; - back_facing_child_of_back_facing_surface->test_properties()->double_sided = - false; + front_facing_child->SetDoubleSided(false); + back_facing_child->SetDoubleSided(false); + front_facing_surface->SetDoubleSided(false); + back_facing_surface->SetDoubleSided(false); + front_facing_child_of_front_facing_surface->SetDoubleSided(false); + back_facing_child_of_front_facing_surface->SetDoubleSided(false); + front_facing_child_of_back_facing_surface->SetDoubleSided(false); + back_facing_child_of_back_facing_surface->SetDoubleSided(false); // Everything draws content. - front_facing_child->SetDrawsContent(true); - back_facing_child->SetDrawsContent(true); - front_facing_surface->SetDrawsContent(true); - back_facing_surface->SetDrawsContent(true); - front_facing_child_of_front_facing_surface->SetDrawsContent(true); - back_facing_child_of_front_facing_surface->SetDrawsContent(true); - front_facing_child_of_back_facing_surface->SetDrawsContent(true); - back_facing_child_of_back_facing_surface->SetDrawsContent(true); + front_facing_child->SetIsDrawable(true); + back_facing_child->SetIsDrawable(true); + front_facing_surface->SetIsDrawable(true); + back_facing_surface->SetIsDrawable(true); + front_facing_child_of_front_facing_surface->SetIsDrawable(true); + back_facing_child_of_front_facing_surface->SetIsDrawable(true); + front_facing_child_of_back_facing_surface->SetIsDrawable(true); + back_facing_child_of_back_facing_surface->SetIsDrawable(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); @@ -3705,92 +3776,98 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_surface->test_properties()->force_render_surface = true; - back_facing_surface->test_properties()->force_render_surface = true; + front_facing_surface->SetForceRenderSurfaceForTesting(true); + back_facing_surface->SetForceRenderSurfaceForTesting(true); - back_facing_child->test_properties()->transform = backface_matrix; - back_facing_surface->test_properties()->transform = backface_matrix; - back_facing_child_of_front_facing_surface->test_properties()->transform = - backface_matrix; - back_facing_child_of_back_facing_surface->test_properties()->transform = - backface_matrix; + back_facing_child->SetTransform(backface_matrix); + back_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms // spec, these layers should blindly use their own local transforms to // determine back-face culling. - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + CommitAndActivate(); // Verify which render surfaces were created. - EXPECT_EQ(GetRenderSurface(front_facing_child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(back_facing_child), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(front_facing_surface), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(back_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(front_facing_child_of_front_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(back_facing_child_of_front_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(front_facing_child_of_back_facing_surface), - GetRenderSurface(back_facing_surface)); - EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), - GetRenderSurface(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list()->size()); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + + EXPECT_EQ(3u, update_layer_impl_list().size()); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); EXPECT_TRUE(UpdateLayerImplListContains( front_facing_child_of_front_facing_surface->id())); } -TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { - // Verify the behavior of back-face culling when preserves-3d transform style - // is used. - - LayerImpl* root = root_layer_for_testing(); - LayerImpl* front_facing_child = AddChildToRoot<LayerImpl>(); - LayerImpl* back_facing_child = AddChildToRoot<LayerImpl>(); - LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* front_facing_child_of_front_facing_surface = - AddChild<LayerImpl>(front_facing_surface); - LayerImpl* back_facing_child_of_front_facing_surface = - AddChild<LayerImpl>(front_facing_surface); - LayerImpl* front_facing_child_of_back_facing_surface = - AddChild<LayerImpl>(back_facing_surface); - LayerImpl* back_facing_child_of_back_facing_surface = - AddChild<LayerImpl>(back_facing_surface); +// Verify the behavior of back-face culling when preserves-3d transform style +// is used. +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, BackFaceCullingWithPreserves3d) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto front_facing_child = Layer::Create(); + root->AddChild(front_facing_child); + auto back_facing_child = Layer::Create(); + root->AddChild(back_facing_child); + auto front_facing_surface = Layer::Create(); + root->AddChild(front_facing_surface); + auto back_facing_surface = Layer::Create(); + root->AddChild(back_facing_surface); + auto front_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); + auto back_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); + auto front_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); + auto back_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); // Opacity will not force creation of render surfaces in this case because of // the preserve-3d transform style. Instead, an example of when a surface // would be created with preserve-3d is when there is a mask layer. - LayerImpl* dummy_mask_layer1 = AddMaskLayer<LayerImpl>(front_facing_surface); - LayerImpl* dummy_mask_layer2 = AddMaskLayer<LayerImpl>(back_facing_surface); + FakeContentLayerClient client; + auto dummy_mask_layer1 = PictureLayer::Create(&client); + front_facing_surface->SetMaskLayer(dummy_mask_layer1); + auto dummy_mask_layer2 = PictureLayer::Create(&client); + back_facing_surface->SetMaskLayer(dummy_mask_layer2); // Nothing is double-sided - front_facing_child->test_properties()->double_sided = false; - back_facing_child->test_properties()->double_sided = false; - front_facing_surface->test_properties()->double_sided = false; - back_facing_surface->test_properties()->double_sided = false; - front_facing_child_of_front_facing_surface->test_properties()->double_sided = - false; - back_facing_child_of_front_facing_surface->test_properties()->double_sided = - false; - front_facing_child_of_back_facing_surface->test_properties()->double_sided = - false; - back_facing_child_of_back_facing_surface->test_properties()->double_sided = - false; + front_facing_child->SetDoubleSided(false); + back_facing_child->SetDoubleSided(false); + front_facing_surface->SetDoubleSided(false); + back_facing_surface->SetDoubleSided(false); + front_facing_child_of_front_facing_surface->SetDoubleSided(false); + back_facing_child_of_front_facing_surface->SetDoubleSided(false); + front_facing_child_of_back_facing_surface->SetDoubleSided(false); + back_facing_child_of_back_facing_surface->SetDoubleSided(false); // Everything draws content. - front_facing_child->SetDrawsContent(true); - back_facing_child->SetDrawsContent(true); - front_facing_surface->SetDrawsContent(true); - back_facing_surface->SetDrawsContent(true); - front_facing_child_of_front_facing_surface->SetDrawsContent(true); - back_facing_child_of_front_facing_surface->SetDrawsContent(true); - front_facing_child_of_back_facing_surface->SetDrawsContent(true); - back_facing_child_of_back_facing_surface->SetDrawsContent(true); - dummy_mask_layer1->SetDrawsContent(true); - dummy_mask_layer2->SetDrawsContent(true); + front_facing_child->SetIsDrawable(true); + back_facing_child->SetIsDrawable(true); + front_facing_surface->SetIsDrawable(true); + back_facing_surface->SetIsDrawable(true); + front_facing_child_of_front_facing_surface->SetIsDrawable(true); + back_facing_child_of_front_facing_surface->SetIsDrawable(true); + front_facing_child_of_back_facing_surface->SetIsDrawable(true); + back_facing_child_of_back_facing_surface->SetIsDrawable(true); + dummy_mask_layer1->SetIsDrawable(true); + dummy_mask_layer2->SetIsDrawable(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); @@ -3806,52 +3883,52 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); + dummy_mask_layer1->SetBounds(gfx::Size(100, 100)); + dummy_mask_layer2->SetBounds(gfx::Size(100, 100)); - back_facing_child->test_properties()->transform = backface_matrix; - back_facing_surface->test_properties()->transform = backface_matrix; - back_facing_child_of_front_facing_surface->test_properties()->transform = - backface_matrix; - back_facing_child_of_back_facing_surface->test_properties()->transform = - backface_matrix; + back_facing_child->SetTransform(backface_matrix); + back_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); // Each surface creates its own new 3d rendering context (as defined by W3C // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d // rendering context should use the transform with respect to that context. // This 3d rendering context occurs when (a) parent's transform style is flat // and (b) the layer's transform style is preserve-3d. - front_facing_surface->test_properties()->should_flatten_transform = false; - front_facing_surface->test_properties()->sorting_context_id = 1; - back_facing_surface->test_properties()->should_flatten_transform = false; - back_facing_surface->test_properties()->sorting_context_id = 1; - front_facing_child_of_front_facing_surface->test_properties() - ->sorting_context_id = 1; - back_facing_child_of_front_facing_surface->test_properties() - ->sorting_context_id = 1; - front_facing_child_of_back_facing_surface->test_properties() - ->sorting_context_id = 1; - back_facing_child_of_back_facing_surface->test_properties() - ->sorting_context_id = 1; - - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + front_facing_surface->SetShouldFlattenTransform(false); + front_facing_surface->Set3dSortingContextId(1); + back_facing_surface->SetShouldFlattenTransform(false); + back_facing_surface->Set3dSortingContextId(1); + front_facing_child_of_front_facing_surface->Set3dSortingContextId(1); + back_facing_child_of_front_facing_surface->Set3dSortingContextId(1); + front_facing_child_of_back_facing_surface->Set3dSortingContextId(1); + back_facing_child_of_back_facing_surface->Set3dSortingContextId(1); + + CommitAndActivate(); // Verify which render surfaces were created and used. - EXPECT_EQ(GetRenderSurface(front_facing_child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(back_facing_child), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(front_facing_surface), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), + GetRenderSurfaceImpl(root)); // We expect that a render surface was created but not used. - EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(back_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(front_facing_child_of_front_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(back_facing_child_of_front_facing_surface), - GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(front_facing_child_of_back_facing_surface), - GetRenderSurface(back_facing_surface)); - EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), - GetRenderSurface(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list()->size()); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + + EXPECT_EQ(3u, update_layer_impl_list().size()); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); @@ -3859,102 +3936,114 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { front_facing_child_of_front_facing_surface->id())); } -TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { - // Verify that layers are appropriately culled when their back face is showing - // and they are not double sided, while animations are going on. - // - // Even layers that are animating get culled if their back face is showing and - // they are not double sided. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - LayerImpl* animating_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child_of_animating_surface = - AddChild<LayerImpl>(animating_surface); - LayerImpl* animating_child = AddChildToRoot<LayerImpl>(); - LayerImpl* child2 = AddChildToRoot<LayerImpl>(); +// Verify that layers are appropriately culled when their back face is showing +// and they are not double sided, while animations are going on. +// Even layers that are animating get culled if their back face is showing and +// they are not double sided. +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + BackFaceCullingWithAnimatingTransforms) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto animating_surface = Layer::Create(); + root->AddChild(animating_surface); + auto child_of_animating_surface = Layer::Create(); + animating_surface->AddChild(child_of_animating_surface); + auto animating_child = Layer::Create(); + root->AddChild(animating_child); + auto child2 = Layer::Create(); + root->AddChild(child2); // Nothing is double-sided - child->test_properties()->double_sided = false; - child2->test_properties()->double_sided = false; - animating_surface->test_properties()->double_sided = false; - child_of_animating_surface->test_properties()->double_sided = false; - animating_child->test_properties()->double_sided = false; + child->SetDoubleSided(false); + child2->SetDoubleSided(false); + animating_surface->SetDoubleSided(false); + child_of_animating_surface->SetDoubleSided(false); + animating_child->SetDoubleSided(false); // Everything draws content. - child->SetDrawsContent(true); - child2->SetDrawsContent(true); - animating_surface->SetDrawsContent(true); - child_of_animating_surface->SetDrawsContent(true); - animating_child->SetDrawsContent(true); + child->SetIsDrawable(true); + child2->SetIsDrawable(true); + animating_surface->SetIsDrawable(true); + child_of_animating_surface->SetIsDrawable(true); + animating_child->SetIsDrawable(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); backface_matrix.RotateAboutYAxis(180.0); backface_matrix.Translate(-50.0, -50.0); - SetElementIdsForTesting(); + host()->SetElementIdsForTesting(); // Animate the transform on the render surface. AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(), - timeline_impl(), 10.0, 30, 0); + timeline(), 10.0, 30, 0); // This is just an animating layer, not a surface. AddAnimatedTransformToElementWithAnimation(animating_child->element_id(), - timeline_impl(), 10.0, 30, 0); + timeline(), 10.0, 30, 0); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = backface_matrix; + child->SetTransform(backface_matrix); animating_surface->SetBounds(gfx::Size(100, 100)); - animating_surface->test_properties()->transform = backface_matrix; - animating_surface->test_properties()->force_render_surface = true; + animating_surface->SetTransform(backface_matrix); + animating_surface->SetForceRenderSurfaceForTesting(true); child_of_animating_surface->SetBounds(gfx::Size(100, 100)); - child_of_animating_surface->test_properties()->transform = backface_matrix; + child_of_animating_surface->SetTransform(backface_matrix); animating_child->SetBounds(gfx::Size(100, 100)); - animating_child->test_properties()->transform = backface_matrix; + animating_child->SetTransform(backface_matrix); child2->SetBounds(gfx::Size(100, 100)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + CommitAndActivate(); - EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); - EXPECT_TRUE(GetRenderSurface(animating_surface)); - EXPECT_EQ(GetRenderSurface(child_of_animating_surface), - GetRenderSurface(animating_surface)); - EXPECT_EQ(GetRenderSurface(animating_child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface), + GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); - EXPECT_EQ(1u, update_layer_impl_list()->size()); + EXPECT_EQ(1u, update_layer_impl_list().size()); // The back facing layers are culled from the layer list, and have an empty // visible rect. EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); - EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(animating_surface->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(child_of_animating_surface->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(animating_child->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE( + ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty()); - EXPECT_EQ(gfx::Rect(100, 100), child2->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, - BackFaceCullingWithPreserves3dForFlatteningSurface) { - // Verify the behavior of back-face culling for a render surface that is - // created when it flattens its subtree, and its parent has preserves-3d. - - LayerImpl* root = root_layer_for_testing(); - LayerImpl* front_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* back_facing_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* child1 = AddChild<LayerImpl>(front_facing_surface); - LayerImpl* child2 = AddChild<LayerImpl>(back_facing_surface); +// Verify the behavior of back-face culling for a render surface that is +// created when it flattens its subtree, and its parent has preserves-3d. +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + BackFaceCullingWithPreserves3dForFlatteningSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto front_facing_surface = Layer::Create(); + root->AddChild(front_facing_surface); + auto back_facing_surface = Layer::Create(); + root->AddChild(back_facing_surface); + auto child1 = Layer::Create(); + front_facing_surface->AddChild(child1); + auto child2 = Layer::Create(); + back_facing_surface->AddChild(child2); // RenderSurfaces are not double-sided - front_facing_surface->test_properties()->double_sided = false; - back_facing_surface->test_properties()->double_sided = false; + front_facing_surface->SetDoubleSided(false); + back_facing_surface->SetDoubleSided(false); // Everything draws content. - front_facing_surface->SetDrawsContent(true); - back_facing_surface->SetDrawsContent(true); - child1->SetDrawsContent(true); - child2->SetDrawsContent(true); + front_facing_surface->SetIsDrawable(true); + back_facing_surface->SetIsDrawable(true); + child1->SetIsDrawable(true); + child2->SetIsDrawable(true); gfx::Transform backface_matrix; backface_matrix.Translate(50.0, 50.0); @@ -3963,48 +4052,58 @@ TEST_F(LayerTreeHostCommonTest, root->SetBounds(gfx::Size(100, 100)); front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_surface->test_properties()->force_render_surface = true; + front_facing_surface->SetForceRenderSurfaceForTesting(true); back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->test_properties()->transform = backface_matrix; - back_facing_surface->test_properties()->force_render_surface = true; + back_facing_surface->SetTransform(backface_matrix); + back_facing_surface->SetForceRenderSurfaceForTesting(true); child1->SetBounds(gfx::Size(100, 100)); child2->SetBounds(gfx::Size(100, 100)); - front_facing_surface->test_properties()->sorting_context_id = 1; - back_facing_surface->test_properties()->sorting_context_id = 1; + front_facing_surface->Set3dSortingContextId(1); + back_facing_surface->Set3dSortingContextId(1); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + CommitAndActivate(); // Verify which render surfaces were created and used. - EXPECT_TRUE(GetRenderSurface(front_facing_surface)); + EXPECT_TRUE(GetRenderSurfaceImpl(front_facing_surface)); // We expect the render surface to have been created, but remain unused. - EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child1), GetRenderSurface(front_facing_surface)); - EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(back_facing_surface)); - - EXPECT_EQ(2u, update_layer_impl_list()->size()); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child1), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(child2), + GetRenderSurfaceImpl(back_facing_surface)); + + EXPECT_EQ(2u, update_layer_impl_list().size()); EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); EXPECT_TRUE(UpdateLayerImplListContains(child1->id())); } +using LayerTreeHostCommonScalingTest = LayerTreeHostCommonTest; + +// Verify draw and screen space transforms of layers not in a surface. TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { - // Verify draw and screen space transforms of layers not in a surface. LayerImpl* root = root_layer_for_testing(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - LayerImpl* child = AddChildToRoot<LayerImpl>(); - child->test_properties()->position = gfx::PointF(2.f, 2.f); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - LayerImpl* child2 = AddChildToRoot<LayerImpl>(); - child2->test_properties()->position = gfx::PointF(2.f, 2.f); + LayerImpl* child2 = AddLayer<LayerImpl>(); child2->SetBounds(gfx::Size(5, 5)); child2->SetDrawsContent(true); float device_scale_factor = 2.5f; + + SetupRootProperties(root); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); + ExecuteCalculateDrawProperties(root, device_scale_factor); EXPECT_FLOAT_EQ(device_scale_factor, root->GetIdealContentsScale()); @@ -4037,8 +4136,7 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { // Verify child and child2 transforms. They should match. gfx::Transform expected_child_transform; expected_child_transform.Scale(device_scale_factor, device_scale_factor); - expected_child_transform.Translate(child->test_properties()->position.x(), - child->test_properties()->position.y()); + expected_child_transform.Translate(child->offset_to_transform_parent()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, @@ -4062,8 +4160,9 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { gfx::RectF child2_screen_space_rect = MathUtil::MapClippedRect(child2->ScreenSpaceTransform(), child_bounds); - gfx::RectF expected_child_draw_rect(child->test_properties()->position, - gfx::SizeF(child->bounds())); + gfx::RectF expected_child_draw_rect( + gfx::PointAtOffsetFromOrigin(child->offset_to_transform_parent()), + gfx::SizeF(child->bounds())); expected_child_draw_rect.Scale(device_scale_factor); EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect); EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect); @@ -4071,10 +4170,11 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child2_screen_space_rect); } +// Verify draw and screen space transforms of layers in a surface. TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { - // Verify draw and screen space transforms of layers in a surface. gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.0); + gfx::Vector2dF perspective_surface_offset(2.f, 2.f); gfx::Transform scale_small_matrix; scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f); @@ -4082,37 +4182,51 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { LayerImpl* root = root_layer_for_testing(); root->SetBounds(gfx::Size(100, 100)); - LayerImpl* page_scale = AddChildToRoot<LayerImpl>(); + LayerImpl* page_scale = AddLayer<LayerImpl>(); page_scale->SetBounds(gfx::Size(100, 100)); - LayerImpl* parent = AddChild<LayerImpl>(page_scale); + LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); parent->SetDrawsContent(true); - LayerImpl* perspective_surface = AddChild<LayerImpl>(parent); - perspective_surface->test_properties()->position = gfx::PointF(2.f, 2.f); + LayerImpl* perspective_surface = AddLayer<LayerImpl>(); perspective_surface->SetBounds(gfx::Size(10, 10)); - perspective_surface->test_properties()->transform = - perspective_matrix * scale_small_matrix; perspective_surface->SetDrawsContent(true); - perspective_surface->test_properties()->force_render_surface = true; - LayerImpl* scale_surface = AddChild<LayerImpl>(parent); - scale_surface->test_properties()->position = gfx::PointF(2.f, 2.f); + LayerImpl* scale_surface = AddLayer<LayerImpl>(); scale_surface->SetBounds(gfx::Size(10, 10)); - scale_surface->test_properties()->transform = scale_small_matrix; scale_surface->SetDrawsContent(true); - scale_surface->test_properties()->force_render_surface = true; + + SetupRootProperties(root); + CopyProperties(root, page_scale); + auto& page_scale_transform_node = CreateTransformNode(page_scale); + page_scale_transform_node.in_subtree_of_page_scale_layer = true; + CopyProperties(page_scale, parent); + CopyProperties(parent, perspective_surface); + auto& perspective_surface_transform = + CreateTransformNode(perspective_surface); + perspective_surface_transform.local = perspective_matrix * scale_small_matrix; + perspective_surface_transform.post_translation = perspective_surface_offset; + CreateEffectNode(perspective_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(parent, scale_surface); + auto& scale_surface_transform = CreateTransformNode(scale_surface); + scale_surface_transform.local = scale_small_matrix; + scale_surface_transform.post_translation = gfx::Vector2dF(2.f, 2.f); + CreateEffectNode(scale_surface).render_surface_reason = + RenderSurfaceReason::kTest; float device_scale_factor = 2.5f; float page_scale_factor = 3.f; + const gfx::Transform kDeviceTransform; + LayerTreeImpl::ViewportLayerIds viewport_ids; viewport_ids.page_scale = page_scale->id(); root->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); - root->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting(); root->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale_factor); - ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - root, nullptr, nullptr); + + ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, + page_scale_factor, page_scale); EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, parent->GetIdealContentsScale()); @@ -4150,10 +4264,8 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { // with the screen, and then scaled during drawing. gfx::Transform expected_perspective_surface_draw_transform; expected_perspective_surface_draw_transform.Translate( - device_scale_factor * page_scale_factor * - perspective_surface->test_properties()->position.x(), - device_scale_factor * page_scale_factor * - perspective_surface->test_properties()->position.y()); + device_scale_factor * page_scale_factor * perspective_surface_offset.x(), + device_scale_factor * page_scale_factor * perspective_surface_offset.y()); expected_perspective_surface_draw_transform.PreconcatTransform( perspective_matrix); expected_perspective_surface_draw_transform.PreconcatTransform( @@ -4182,35 +4294,42 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { LayerImpl* root = root_layer_for_testing(); root->SetBounds(gfx::Size(100, 100)); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); + LayerImpl* page_scale = AddLayer<LayerImpl>(); + page_scale->SetBounds(gfx::Size(100, 100)); + + LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); - parent->test_properties()->transform = parent_scale_matrix; parent->SetDrawsContent(true); - LayerImpl* child_scale = AddChild<LayerImpl>(parent); - child_scale->test_properties()->position = gfx::PointF(2.f, 2.f); + LayerImpl* child_scale = AddLayer<LayerImpl>(); child_scale->SetBounds(gfx::Size(10, 10)); - child_scale->test_properties()->transform = child_scale_matrix; child_scale->SetDrawsContent(true); float device_scale_factor = 2.5f; float page_scale_factor = 0.01f; + const gfx::Transform kDeviceTransform; - { - ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - root, nullptr, nullptr); - - // The ideal scale is able to go below 1. - float expected_ideal_scale = - device_scale_factor * page_scale_factor * initial_parent_scale; - EXPECT_LT(expected_ideal_scale, 1.f); - EXPECT_FLOAT_EQ(expected_ideal_scale, parent->GetIdealContentsScale()); - - expected_ideal_scale = device_scale_factor * page_scale_factor * - initial_parent_scale * initial_child_scale; - EXPECT_LT(expected_ideal_scale, 1.f); - EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale()); - } + SetupRootProperties(root); + CopyProperties(root, page_scale); + CreateTransformNode(page_scale).in_subtree_of_page_scale_layer = true; + CopyProperties(page_scale, parent); + CreateTransformNode(parent).local = parent_scale_matrix; + CopyProperties(parent, child_scale); + CreateTransformNode(child_scale).local = child_scale_matrix; + + ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, + page_scale_factor, page_scale); + + // The ideal scale is able to go below 1. + float expected_ideal_scale = + device_scale_factor * page_scale_factor * initial_parent_scale; + EXPECT_LT(expected_ideal_scale, 1.f); + EXPECT_FLOAT_EQ(expected_ideal_scale, parent->GetIdealContentsScale()); + + expected_ideal_scale = device_scale_factor * page_scale_factor * + initial_parent_scale * initial_child_scale; + EXPECT_LT(expected_ideal_scale, 1.f); + EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale()); } TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { @@ -4225,17 +4344,20 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { LayerImpl* root = root_layer_for_testing(); root->SetBounds(gfx::Size(100, 100)); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); + LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); - parent->test_properties()->transform = parent_scale_matrix; parent->SetDrawsContent(true); - LayerImpl* child_scale = AddChild<LayerImpl>(parent); + LayerImpl* child_scale = AddLayer<LayerImpl>(); child_scale->SetBounds(gfx::Size(10, 10)); - child_scale->test_properties()->position = gfx::PointF(2.f, 2.f); - child_scale->test_properties()->transform = child_scale_matrix; child_scale->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, parent); + CreateTransformNode(parent).local = parent_scale_matrix; + CopyProperties(parent, child_scale); + CreateTransformNode(child_scale).local = child_scale_matrix; + ExecuteCalculateDrawProperties(root); EXPECT_FLOAT_EQ(initial_parent_scale, parent->GetIdealContentsScale()); @@ -4249,22 +4371,28 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { LayerImpl* parent = root_layer_for_testing(); parent->SetBounds(gfx::Size(30, 30)); parent->SetDrawsContent(true); - parent->test_properties()->should_flatten_transform = false; - parent->test_properties()->sorting_context_id = 1; - LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetBounds(gfx::Size(10, 10)); - child->test_properties()->position = gfx::PointF(2.f, 2.f); child->SetDrawsContent(true); - child->test_properties()->force_render_surface = true; // This layer should end up in the same surface as child, with the same draw // and screen space transforms. - LayerImpl* duplicate_child_non_owner = AddChild<LayerImpl>(child); + LayerImpl* duplicate_child_non_owner = AddLayer<LayerImpl>(); duplicate_child_non_owner->SetBounds(gfx::Size(10, 10)); duplicate_child_non_owner->SetDrawsContent(true); float device_scale_factor = 1.5f; + gfx::Vector2dF child_offset(2.f, 2.f); + + SetupRootProperties(parent); + CopyProperties(parent, child); + CreateTransformNode(child).post_translation = child_offset; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, duplicate_child_non_owner); + duplicate_child_non_owner->SetOffsetToTransformParent( + child->offset_to_transform_parent()); + ExecuteCalculateDrawProperties(parent, device_scale_factor); // We should have two render surfaces. The root's render surface and child's @@ -4286,9 +4414,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { gfx::Transform expected_screen_space_transform; expected_screen_space_transform.Scale(device_scale_factor, device_scale_factor); - expected_screen_space_transform.Translate( - child->test_properties()->position.x(), - child->test_properties()->position.y()); + expected_screen_space_transform.Translate(child_offset); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform, child->ScreenSpaceTransform()); @@ -4305,8 +4431,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { gfx::Transform expected_render_surface_draw_transform; expected_render_surface_draw_transform.Translate( - device_scale_factor * child->test_properties()->position.x(), - device_scale_factor * child->test_properties()->position.y()); + device_scale_factor * child_offset.x(), + device_scale_factor * child_offset.y()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform, GetRenderSurface(child)->draw_transform()); @@ -4325,17 +4451,21 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { } TEST_F(LayerTreeHostCommonTest, - RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) { + RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) { LayerImpl* parent = root_layer_for_testing(); parent->SetBounds(gfx::Size(33, 31)); parent->SetDrawsContent(true); - LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetBounds(gfx::Size(13, 11)); child->SetDrawsContent(true); - child->test_properties()->force_render_surface = true; float device_scale_factor = 1.7f; + + SetupRootProperties(parent); + CopyProperties(parent, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + ExecuteCalculateDrawProperties(parent, device_scale_factor); // We should have two render surfaces. The root's render surface and child's @@ -4350,7 +4480,8 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform(), GetRenderSurface(child)->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, LayerSearch) { +// Needs layer tree mode: mask layer. Not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerSearch) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child = Layer::Create(); scoped_refptr<Layer> grand_child = Layer::Create(); @@ -4358,7 +4489,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSearch) { scoped_refptr<PictureLayer> mask_layer = PictureLayer::Create(&client); child->AddChild(grand_child.get()); - child->SetMaskLayer(mask_layer.get()); + child->SetMaskLayer(mask_layer); root->AddChild(child.get()); host()->SetRootLayer(root); @@ -4373,126 +4504,92 @@ TEST_F(LayerTreeHostCommonTest, LayerSearch) { TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(10, 10)); - child->test_properties()->opacity = 0.5f; grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateEffectNode(child).opacity = 0.5f; + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); } TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(host()->GetSettings(), &task_runner_provider, - &task_graph_runner); - host_impl.CreatePendingTree(); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); + host_impl()->CreatePendingTree(); + LayerImpl* root = EnsureRootLayerInPendingTree(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.pending_tree(), 2); + auto* child = AddLayerInPendingTree<LayerImpl>(); child->SetBounds(gfx::Size(50, 50)); child->SetDrawsContent(true); - child->test_properties()->opacity = 0.0f; - const int child_id = child->id(); - root->test_properties()->AddChild(std::move(child)); - LayerImpl* root_layer = root.get(); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl()->pending_tree()->SetElementIdsForTesting(); + SetupRootProperties(root); + CopyProperties(root, child); + CreateEffectNode(child).opacity = 0.0f; // Add opacity animation. - scoped_refptr<AnimationTimeline> timeline = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - - ElementId child_element_id = - host_impl.pending_tree()->LayerById(child_id)->element_id(); - - AddOpacityTransitionToElementWithAnimation(child_element_id, timeline, 10.0, - 0.0f, 1.0f, false); + AddOpacityTransitionToElementWithAnimation( + child->element_id(), timeline_impl(), 10.0, 0.0f, 1.0f, false); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root); // We should have one render surface and two layers. The child // layer should be included even though it is transparent. - ASSERT_EQ(1u, render_surface_list.size()); - ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); + ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); // If the root itself is hidden, the child should not be drawn even if it has // an animating opacity. - root_layer->test_properties()->opacity = 0.0f; - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - RenderSurfaceList render_surface_list2; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2( - root_layer, root_layer->bounds(), &render_surface_list2); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs2); - - LayerImpl* child_ptr = root_layer->layer_tree_impl()->LayerById(2); - EffectTree& tree = - root_layer->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = tree.Node(child_ptr->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); + SetOpacity(root, 0.0f); + ExecuteCalculateDrawProperties(root); + + EXPECT_FALSE(GetEffectNode(child)->is_drawn); // A layer should be drawn and it should contribute to drawn surface when // it has animating opacity even if it has opacity 0. - root_layer->test_properties()->opacity = 1.0f; - child_ptr->test_properties()->opacity = 0.0f; - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - RenderSurfaceList render_surface_list3; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3( - root_layer, root_layer->bounds(), &render_surface_list3); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs3); - - child_ptr = root_layer->layer_tree_impl()->LayerById(2); - tree = root_layer->layer_tree_impl()->property_trees()->effect_tree; - node = tree.Node(child_ptr->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); - EXPECT_TRUE(tree.ContributesToDrawnSurface(child_ptr->effect_tree_index())); + SetOpacity(root, 1.0f); + SetOpacity(child, 0.0f); + ExecuteCalculateDrawProperties(root); + + EXPECT_TRUE(GetEffectNode(child)->is_drawn); + EXPECT_TRUE(GetPropertyTrees(root)->effect_tree.ContributesToDrawnSurface( + child->effect_tree_index())); // But if the opacity of the layer remains 0 after activation, it should not // be drawn. - host_impl.ActivateSyncTree(); - LayerImpl* active_root = host_impl.active_tree()->LayerById(root_layer->id()); - LayerImpl* active_child = host_impl.active_tree()->LayerById(child_ptr->id()); + host_impl()->ActivateSyncTree(); + LayerTreeImpl* active_tree = host_impl()->active_tree(); + LayerImpl* active_root = active_tree->LayerById(root->id()); + LayerImpl* active_child = active_tree->LayerById(child->id()); - EffectTree& active_effect_tree = - host_impl.active_tree()->property_trees()->effect_tree; + EffectTree& active_effect_tree = active_tree->property_trees()->effect_tree; EXPECT_TRUE(active_effect_tree.needs_update()); ExecuteCalculateDrawProperties(active_root); - node = active_effect_tree.Node(active_child->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); + EXPECT_FALSE(GetEffectNode(active_child)->is_drawn); EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface( active_child->effect_tree_index())); } -using LCDTextTestParam = std::tuple<bool, bool, bool>; +using LCDTextTestParam = std::tuple<bool, bool>; class LCDTextTest : public LayerTreeHostCommonTestBase, public testing::TestWithParam<LCDTextTestParam> { public: - LCDTextTest() - : LayerTreeHostCommonTestBase(LCDTextTestLayerTreeSettings()), - host_impl_(LCDTextTestLayerTreeSettings(), - &task_runner_provider_, - &task_graph_runner_) {} - - scoped_refptr<AnimationTimeline> timeline() { return timeline_; } + LCDTextTest() : LayerTreeHostCommonTestBase(LCDTextTestLayerTreeSettings()) {} protected: LayerTreeSettings LCDTextTestLayerTreeSettings() { - LayerTreeSettings settings = VerifyTreeCalcsLayerTreeSettings(); + LayerListSettings settings; can_use_lcd_text_ = std::get<0>(GetParam()); layers_always_allowed_lcd_text_ = std::get<1>(GetParam()); @@ -4502,27 +4599,10 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, } void SetUp() override { - timeline_ = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl_.animation_host()->AddAnimationTimeline(timeline_); - - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_.active_tree(), 1); - std::unique_ptr<LayerImpl> child_ptr = - LayerImpl::Create(host_impl_.active_tree(), 2); - std::unique_ptr<LayerImpl> grand_child_ptr = - LayerImpl::Create(host_impl_.active_tree(), 3); - - // Stash raw pointers to look at later. - root_ = root_ptr.get(); - child_ = child_ptr.get(); - grand_child_ = grand_child_ptr.get(); - - child_->test_properties()->AddChild(std::move(grand_child_ptr)); - root_->test_properties()->AddChild(std::move(child_ptr)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - - host_impl_.active_tree()->SetElementIdsForTesting(); + root_ = root_layer_for_testing(); + child_ = AddLayer<LayerImpl>(); + grand_child_ = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); root_->SetContentsOpaque(true); child_->SetContentsOpaque(true); @@ -4536,17 +4616,16 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, child_->SetBounds(gfx::Size(1, 1)); grand_child_->SetBounds(gfx::Size(1, 1)); - child_->test_properties()->force_render_surface = std::get<2>(GetParam()); + SetupRootProperties(root_); + CopyProperties(root_, child_); + CreateTransformNode(child_); + CreateEffectNode(child_).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child_, grand_child_); } bool can_use_lcd_text_; bool layers_always_allowed_lcd_text_; - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; - scoped_refptr<AnimationTimeline> timeline_; - LayerImpl* root_ = nullptr; LayerImpl* child_ = nullptr; LayerImpl* grand_child_ = nullptr; @@ -4557,7 +4636,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Case 1: Identity transform. - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4565,9 +4644,9 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 2: Integral translation. gfx::Transform integral_translation; integral_translation.Translate(1.0, 2.0); - child_->test_properties()->transform = integral_translation; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, integral_translation); + + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4575,9 +4654,8 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 3: Non-integral translation. gfx::Transform non_integral_translation; non_integral_translation.Translate(1.5, 2.5); - child_->test_properties()->transform = non_integral_translation; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, non_integral_translation); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4585,9 +4663,8 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 4: Rotation. gfx::Transform rotation; rotation.Rotate(10.0); - child_->test_properties()->transform = rotation; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, rotation); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4595,9 +4672,8 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 5: Scale. gfx::Transform scale; scale.Scale(2.0, 2.0); - child_->test_properties()->transform = scale; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, scale); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4605,48 +4681,45 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 6: Skew. gfx::Transform skew; skew.Skew(10.0, 0.0); - child_->test_properties()->transform = skew; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, skew); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); // Case 7: Translucent. - child_->test_properties()->transform = gfx::Transform(); - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - child_->test_properties()->opacity = 0.5f; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, gfx::Transform()); + SetOpacity(child_, 0.5f); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); // Case 8: Sanity check: restore transform and opacity. - child_->test_properties()->transform = gfx::Transform(); - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - child_->test_properties()->opacity = 1.f; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + SetTransform(child_, gfx::Transform()); + SetOpacity(child_, 1.f); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 9: Non-opaque content. child_->SetContentsOpaque(false); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 10: Sanity check: restore content opaqueness. child_->SetContentsOpaque(true); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 11: will-change: transform child_->SetHasWillChangeTransformHint(true); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4657,20 +4730,16 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Add opacity animation. - child_->test_properties()->opacity = 0.9f; - child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - - SetElementIdsForTesting(); - + SetOpacity(child_, 0.9f); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); // Text LCD should be adjusted while animation is active. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); @@ -4682,17 +4751,16 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); - SetElementIdsForTesting(); // Mark contents non-opaque within the first animation frame. child_->SetContentsOpaque(false); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); + ExecuteCalculateDrawProperties(root_); // LCD text should be disabled for non-opaque layers even during animations. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); @@ -4701,459 +4769,403 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { INSTANTIATE_TEST_SUITE_P(LayerTreeHostCommonTest, LCDTextTest, - testing::Combine(testing::Bool(), - testing::Bool(), - testing::Bool())); - -TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); + testing::Combine(testing::Bool(), testing::Bool())); + +// Needs layer tree mode: hide_layer_and_subtree. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { + auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); - LayerImpl* root_layer = root.get(); + root->SetIsDrawable(true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.pending_tree(), 2); + auto child = Layer::Create(); + root->AddChild(child); child->SetBounds(gfx::Size(40, 40)); - child->SetDrawsContent(true); - LayerImpl* child_layer = child.get(); + child->SetIsDrawable(true); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl.pending_tree(), 3); + auto grand_child = Layer::Create(); + child->AddChild(grand_child); grand_child->SetBounds(gfx::Size(30, 30)); - grand_child->SetDrawsContent(true); - grand_child->test_properties()->hide_layer_and_subtree = true; - LayerImpl* grand_child_layer = grand_child.get(); + grand_child->SetIsDrawable(true); + grand_child->SetHideLayerAndSubtree(true); - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); + child->AddChild(grand_child); + root->AddChild(child); + host()->SetRootLayer(root); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); // We should have one render surface and two layers. The grand child has // hidden itself. - ASSERT_EQ(1u, render_surface_list.size()); - ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); - EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); +// Needs layer tree mode: hide_layer_and_subtree. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { + auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); - LayerImpl* root_layer = root.get(); + root->SetIsDrawable(true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.pending_tree(), 2); + auto child = Layer::Create(); child->SetBounds(gfx::Size(40, 40)); - child->SetDrawsContent(true); - child->test_properties()->hide_layer_and_subtree = true; - LayerImpl* child_layer = child.get(); + child->SetIsDrawable(true); + child->SetHideLayerAndSubtree(true); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl.pending_tree(), 3); + auto grand_child = Layer::Create(); grand_child->SetBounds(gfx::Size(30, 30)); - grand_child->SetDrawsContent(true); - LayerImpl* grand_child_layer = grand_child.get(); + grand_child->SetIsDrawable(true); - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); + child->AddChild(grand_child); + root->AddChild(child); + host()->SetRootLayer(root); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); // We should have one render surface and one layer. The child has // hidden itself and the grand child. - ASSERT_EQ(1u, render_surface_list.size()); - ASSERT_EQ(1, GetRenderSurface(root_layer)->num_contributors()); - EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); +// Needs layer tree mode: mask layer, hide_layer_and_subtree and copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { + auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); - LayerImpl* root_layer = root.get(); + root->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_grand_parent = - LayerImpl::Create(host_impl.pending_tree(), 2); + auto copy_grand_parent = Layer::Create(); copy_grand_parent->SetBounds(gfx::Size(40, 40)); - copy_grand_parent->SetDrawsContent(true); - LayerImpl* copy_grand_parent_layer = copy_grand_parent.get(); + copy_grand_parent->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_parent = - LayerImpl::Create(host_impl.pending_tree(), 3); + auto copy_parent = Layer::Create(); copy_parent->SetBounds(gfx::Size(30, 30)); - copy_parent->SetDrawsContent(true); - copy_parent->test_properties()->force_render_surface = true; - LayerImpl* copy_parent_layer = copy_parent.get(); - - std::unique_ptr<LayerImpl> copy_request = - LayerImpl::Create(host_impl.pending_tree(), 4); - copy_request->SetBounds(gfx::Size(20, 20)); - copy_request->SetDrawsContent(true); - copy_request->test_properties()->force_render_surface = true; - LayerImpl* copy_layer = copy_request.get(); - - std::unique_ptr<LayerImpl> copy_child = - LayerImpl::Create(host_impl.pending_tree(), 5); + copy_parent->SetIsDrawable(true); + copy_parent->SetForceRenderSurfaceForTesting(true); + + auto copy_layer = Layer::Create(); + copy_layer->SetBounds(gfx::Size(20, 20)); + copy_layer->SetIsDrawable(true); + copy_layer->SetForceRenderSurfaceForTesting(true); + + auto copy_child = Layer::Create(); copy_child->SetBounds(gfx::Size(20, 20)); - copy_child->SetDrawsContent(true); - LayerImpl* copy_child_layer = copy_child.get(); + copy_child->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_grand_child = - LayerImpl::Create(host_impl.pending_tree(), 6); + auto copy_grand_child = Layer::Create(); copy_grand_child->SetBounds(gfx::Size(20, 20)); - copy_grand_child->SetDrawsContent(true); - LayerImpl* copy_grand_child_layer = copy_grand_child.get(); + copy_grand_child->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_grand_parent_sibling_before = - LayerImpl::Create(host_impl.pending_tree(), 7); + auto copy_grand_parent_sibling_before = Layer::Create(); copy_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40)); - copy_grand_parent_sibling_before->SetDrawsContent(true); - LayerImpl* copy_grand_parent_sibling_before_layer = - copy_grand_parent_sibling_before.get(); + copy_grand_parent_sibling_before->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_grand_parent_sibling_after = - LayerImpl::Create(host_impl.pending_tree(), 8); + auto copy_grand_parent_sibling_after = Layer::Create(); copy_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40)); - copy_grand_parent_sibling_after->SetDrawsContent(true); - LayerImpl* copy_grand_parent_sibling_after_layer = - copy_grand_parent_sibling_after.get(); - - copy_child->test_properties()->AddChild(std::move(copy_grand_child)); - copy_request->test_properties()->AddChild(std::move(copy_child)); - copy_parent->test_properties()->AddChild(std::move(copy_request)); - copy_grand_parent->test_properties()->AddChild(std::move(copy_parent)); - root->test_properties()->AddChild( - std::move(copy_grand_parent_sibling_before)); - root->test_properties()->AddChild(std::move(copy_grand_parent)); - root->test_properties()->AddChild(std::move(copy_grand_parent_sibling_after)); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); + copy_grand_parent_sibling_after->SetIsDrawable(true); + + copy_child->AddChild(copy_grand_child); + copy_layer->AddChild(copy_child); + copy_parent->AddChild(copy_layer); + copy_grand_parent->AddChild(copy_parent); + root->AddChild(copy_grand_parent_sibling_before); + root->AddChild(copy_grand_parent); + root->AddChild(copy_grand_parent_sibling_after); + host()->SetRootLayer(root); // Hide the copy_grand_parent and its subtree. But make a copy request in that // hidden subtree on copy_layer. Also hide the copy grand child and its // subtree. - copy_grand_parent_layer->test_properties()->hide_layer_and_subtree = true; - copy_grand_parent_sibling_before_layer->test_properties() - ->hide_layer_and_subtree = true; - copy_grand_parent_sibling_after_layer->test_properties() - ->hide_layer_and_subtree = true; - copy_grand_child_layer->test_properties()->hide_layer_and_subtree = true; - - copy_layer->test_properties()->copy_requests.push_back( + copy_grand_parent->SetHideLayerAndSubtree(true); + copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true); + copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true); + copy_grand_child->SetHideLayerAndSubtree(true); + + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); - auto& effect_tree = - root_layer->layer_tree_impl()->property_trees()->effect_tree; - EXPECT_TRUE(effect_tree.Node(root_layer->effect_tree_index()) - ->subtree_has_copy_request); - EXPECT_TRUE(effect_tree.Node(copy_grand_parent_layer->effect_tree_index()) - ->subtree_has_copy_request); - EXPECT_TRUE(effect_tree.Node(copy_parent_layer->effect_tree_index()) - ->subtree_has_copy_request); - EXPECT_TRUE(effect_tree.Node(copy_layer->effect_tree_index()) - ->subtree_has_copy_request); + EXPECT_TRUE(GetEffectNode(ImplOf(root))->subtree_has_copy_request); + EXPECT_TRUE( + GetEffectNode(ImplOf(copy_grand_parent))->subtree_has_copy_request); + EXPECT_TRUE(GetEffectNode(ImplOf(copy_parent))->subtree_has_copy_request); + EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->subtree_has_copy_request); // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the copy_layer. - ASSERT_EQ(4u, render_surface_list.size()); - EXPECT_EQ(static_cast<uint64_t>(root_layer->id()), - render_surface_list.at(0)->id()); - EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent_layer->id()), - render_surface_list.at(1)->id()); - EXPECT_EQ(static_cast<uint64_t>(copy_parent_layer->id()), - render_surface_list.at(2)->id()); + ASSERT_EQ(4u, render_surface_list_impl()->size()); + EXPECT_EQ(static_cast<uint64_t>(root->id()), + render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent->id()), + render_surface_list_impl()->at(1)->id()); + EXPECT_EQ(static_cast<uint64_t>(copy_parent->id()), + render_surface_list_impl()->at(2)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()), - render_surface_list.at(3)->id()); + render_surface_list_impl()->at(3)->id()); // The root render surface should have 2 contributing layers. - EXPECT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); - EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(copy_grand_parent_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(copy_grand_parent_sibling_before_layer + EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); + EXPECT_FALSE( + ImplOf(copy_grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_before) ->contributes_to_drawn_render_surface()); - EXPECT_FALSE(copy_grand_parent_sibling_after_layer + EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_after) ->contributes_to_drawn_render_surface()); // Nothing actually draws into the copy parent, so only the copy_layer will // appear in its list, since it needs to be drawn for the copy request. - ASSERT_EQ(1, GetRenderSurface(copy_parent_layer)->num_contributors()); - EXPECT_FALSE(copy_parent_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(1, GetRenderSurfaceImpl(copy_parent)->num_contributors()); + EXPECT_FALSE(ImplOf(copy_parent)->contributes_to_drawn_render_surface()); // The copy layer's render surface should have 2 contributing layers. - ASSERT_EQ(2, GetRenderSurface(copy_layer)->num_contributors()); - EXPECT_TRUE(copy_layer->contributes_to_drawn_render_surface()); - EXPECT_TRUE(copy_child_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(copy_grand_child_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(2, GetRenderSurfaceImpl(copy_layer)->num_contributors()); + EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface()); // copy_grand_parent, copy_parent shouldn't be drawn because they are hidden, // but the copy_layer and copy_child should be drawn for the copy request. // copy grand child should not be drawn as its hidden even in the copy // request. - EffectTree& tree = - root_layer->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = tree.Node(copy_grand_parent_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - node = tree.Node(copy_parent_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - node = tree.Node(copy_layer->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); - node = tree.Node(copy_child_layer->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); - node = tree.Node(copy_grand_child_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); + EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_parent))->is_drawn); + EXPECT_FALSE(GetEffectNode(ImplOf(copy_parent))->is_drawn); + EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->is_drawn); + EXPECT_TRUE(GetEffectNode(ImplOf(copy_child))->is_drawn); + EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_child))->is_drawn); // Though copy_layer is drawn, it shouldn't contribute to drawn surface as its // actually hidden. - EXPECT_FALSE(GetRenderSurface(copy_layer)->contributes_to_drawn_surface()); + EXPECT_FALSE( + GetRenderSurfaceImpl(copy_layer)->contributes_to_drawn_surface()); } -TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); +// Needs layer tree mode: copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { + auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); + root->SetIsDrawable(true); - std::unique_ptr<LayerImpl> copy_parent = - LayerImpl::Create(host_impl.pending_tree(), 2); - copy_parent->SetDrawsContent(true); + auto copy_parent = Layer::Create(); + copy_parent->SetIsDrawable(true); copy_parent->SetMasksToBounds(true); - std::unique_ptr<LayerImpl> copy_layer = - LayerImpl::Create(host_impl.pending_tree(), 3); + auto copy_layer = Layer::Create(); copy_layer->SetBounds(gfx::Size(30, 30)); - copy_layer->SetDrawsContent(true); - copy_layer->test_properties()->force_render_surface = true; + copy_layer->SetIsDrawable(true); + copy_layer->SetForceRenderSurfaceForTesting(true); - std::unique_ptr<LayerImpl> copy_child = - LayerImpl::Create(host_impl.pending_tree(), 4); + auto copy_child = Layer::Create(); copy_child->SetBounds(gfx::Size(20, 20)); - copy_child->SetDrawsContent(true); + copy_child->SetIsDrawable(true); - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - copy_layer->test_properties()->AddChild(std::move(copy_child)); - copy_parent->test_properties()->AddChild(std::move(copy_layer)); - root->test_properties()->AddChild(std::move(copy_parent)); + copy_layer->AddChild(copy_child); + copy_parent->AddChild(copy_layer); + root->AddChild(copy_parent); - RenderSurfaceList render_surface_list; - LayerImpl* root_layer = root.get(); - root_layer->layer_tree_impl()->SetRootLayerForTesting(std::move(root)); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + host()->SetRootLayer(root); + + CommitAndActivate(); // We should have two render surface, as the others are clipped out. - ASSERT_EQ(2u, render_surface_list.size()); - EXPECT_EQ(static_cast<uint64_t>(root_layer->id()), - render_surface_list.at(0)->id()); + ASSERT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(static_cast<uint64_t>(root->id()), + render_surface_list_impl()->at(0)->id()); // The root render surface should have only 2 contributing layer, since the // other layers are clipped away. - ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); - EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, SingularTransformAndCopyRequests) { - LayerImpl* root = root_layer_for_testing(); +// Needs layer tree mode: copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SingularTransformAndCopyRequests) { + auto root = Layer::Create(); + host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); + root->SetIsDrawable(true); - LayerImpl* singular_transform_layer = AddChild<LayerImpl>(root); + auto singular_transform_layer = Layer::Create(); + root->AddChild(singular_transform_layer); singular_transform_layer->SetBounds(gfx::Size(100, 100)); - singular_transform_layer->SetDrawsContent(true); + singular_transform_layer->SetIsDrawable(true); gfx::Transform singular; singular.Scale3d(6.f, 6.f, 0.f); - singular_transform_layer->test_properties()->transform = singular; + singular_transform_layer->SetTransform(singular); - LayerImpl* copy_layer = AddChild<LayerImpl>(singular_transform_layer); + auto copy_layer = Layer::Create(); + singular_transform_layer->AddChild(copy_layer); copy_layer->SetBounds(gfx::Size(100, 100)); - copy_layer->SetDrawsContent(true); - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->SetIsDrawable(true); + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); + auto copy_child = Layer::Create(); + copy_layer->AddChild(copy_child); copy_child->SetBounds(gfx::Size(100, 100)); - copy_child->SetDrawsContent(true); + copy_child->SetIsDrawable(true); - LayerImpl* copy_grand_child = AddChild<LayerImpl>(copy_child); + auto copy_grand_child = Layer::Create(); + copy_child->AddChild(copy_grand_child); copy_grand_child->SetBounds(gfx::Size(100, 100)); - copy_grand_child->SetDrawsContent(true); - copy_grand_child->test_properties()->transform = singular; + copy_grand_child->SetIsDrawable(true); + copy_grand_child->SetTransform(singular); - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(); + ASSERT_FALSE(copy_layer->HasCopyRequest()); // A layer with singular transform should not contribute to drawn render // surface. - EXPECT_FALSE(singular_transform_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE( + ImplOf(singular_transform_layer)->contributes_to_drawn_render_surface()); // Even though copy_layer and copy_child have singular screen space transform, // they still contribute to drawn render surface as their transform to the // closest ancestor with copy request is not singular. - EXPECT_TRUE(copy_layer->contributes_to_drawn_render_surface()); - EXPECT_TRUE(copy_child->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface()); // copy_grand_child's transform to its closest ancestor with copy request is // also singular. So, it doesn't contribute to drawn render surface. - EXPECT_FALSE(copy_grand_child->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) { - LayerImpl* root = root_layer_for_testing(); +// Needs layer tree mode: copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { + auto root = Layer::Create(); + host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); + root->SetIsDrawable(true); root->SetMasksToBounds(true); - LayerImpl* copy_layer = AddChild<LayerImpl>(root); + auto copy_layer = Layer::Create(); + root->AddChild(copy_layer); copy_layer->SetBounds(gfx::Size(100, 100)); - copy_layer->SetDrawsContent(true); - copy_layer->test_properties()->force_render_surface = true; + copy_layer->SetIsDrawable(true); + copy_layer->SetForceRenderSurfaceForTesting(true); - LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); - copy_child->test_properties()->position = gfx::PointF(40.f, 40.f); + auto copy_child = Layer::Create(); + copy_layer->AddChild(copy_child); + copy_child->SetPosition(gfx::PointF(40.f, 40.f)); copy_child->SetBounds(gfx::Size(20, 20)); - copy_child->SetDrawsContent(true); + copy_child->SetIsDrawable(true); - LayerImpl* copy_clip = AddChild<LayerImpl>(copy_layer); + auto copy_clip = Layer::Create(); + copy_layer->AddChild(copy_clip); copy_clip->SetBounds(gfx::Size(55, 55)); copy_clip->SetMasksToBounds(true); - LayerImpl* copy_clipped_child = AddChild<LayerImpl>(copy_clip); - copy_clipped_child->test_properties()->position = gfx::PointF(40.f, 40.f); + auto copy_clipped_child = Layer::Create(); + copy_clip->AddChild(copy_clipped_child); + copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f)); copy_clipped_child->SetBounds(gfx::Size(20, 20)); - copy_clipped_child->SetDrawsContent(true); + copy_clipped_child->SetIsDrawable(true); - LayerImpl* copy_surface = AddChild<LayerImpl>(copy_clip); - copy_surface->test_properties()->position = gfx::PointF(45.f, 45.f); + auto copy_surface = Layer::Create(); + copy_clip->AddChild(copy_surface); + copy_surface->SetPosition(gfx::PointF(45.f, 45.f)); copy_surface->SetBounds(gfx::Size(20, 20)); - copy_surface->SetDrawsContent(true); - copy_surface->test_properties()->force_render_surface = true; + copy_surface->SetIsDrawable(true); + copy_surface->SetForceRenderSurfaceForTesting(true); - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(); + ASSERT_FALSE(copy_layer->HasCopyRequest()); - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); - - EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_surface->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_surface)->visible_layer_rect()); // Case 2: When the non root copy request layer is clipped. copy_layer->SetBounds(gfx::Size(50, 50)); copy_layer->SetMasksToBounds(true); - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(); + ASSERT_FALSE(copy_layer->HasCopyRequest()); - EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(5, 5), copy_surface->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); // Case 3: When there is device scale factor. float device_scale_factor = 2.f; - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root, device_scale_factor); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(device_scale_factor); + ASSERT_FALSE(copy_layer->HasCopyRequest()); - EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(5, 5), copy_surface->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { // Ensure that a transform between the layer and its render surface is not a // problem. Constructs the following layer tree. // + // Virtual layer tree: // root (a render surface) // + render_surface // + clip_parent (scaled) // + intervening_clipping_layer - // + clip_child + // + clip_child (clipped_by_clip_parent) // // The render surface should be resized correctly and the clip child should // inherit the right clip rect. LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* clip_parent = AddChild<LayerImpl>(render_surface); - clip_parent->SetDrawsContent(true); - LayerImpl* intervening = AddChild<LayerImpl>(clip_parent); - intervening->SetDrawsContent(true); - LayerImpl* clip_child = AddChild<LayerImpl>(intervening); - clip_child->SetDrawsContent(true); - 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 = std::move(clip_children); - - intervening->SetMasksToBounds(true); - clip_parent->SetMasksToBounds(true); - - gfx::Transform scale_transform; - scale_transform.Scale(2, 2); - root->SetBounds(gfx::Size(50, 50)); + + LayerImpl* render_surface = AddLayer<LayerImpl>(); render_surface->SetBounds(gfx::Size(10, 10)); - render_surface->test_properties()->force_render_surface = true; - clip_parent->test_properties()->transform = scale_transform; - clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f); + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + clip_parent->SetDrawsContent(true); clip_parent->SetBounds(gfx::Size(10, 10)); - intervening->test_properties()->position = gfx::PointF(1.f, 1.f); + CopyProperties(render_surface, clip_parent); + auto& clip_parent_transform = CreateTransformNode(clip_parent); + clip_parent_transform.local.Scale(2, 2); + clip_parent_transform.post_translation = gfx::Vector2dF(1, 1); + CreateClipNode(clip_parent); + + LayerImpl* intervening = AddLayer<LayerImpl>(); + intervening->SetDrawsContent(true); intervening->SetBounds(gfx::Size(5, 5)); - clip_child->test_properties()->position = gfx::PointF(1.f, 1.f); + intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1)); + CopyProperties(clip_parent, intervening); + CreateClipNode(intervening); + + LayerImpl* clip_child = AddLayer<LayerImpl>(); + clip_child->SetDrawsContent(true); clip_child->SetBounds(gfx::Size(10, 10)); + clip_child->SetOffsetToTransformParent(gfx::Vector2dF(2, 2)); + CopyProperties(intervening, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + ExecuteCalculateDrawProperties(root); ASSERT_TRUE(GetRenderSurface(root)); @@ -5183,42 +5195,54 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { // case. In the following tree, both render surfaces should be resized to // accomodate for the clip child, despite an intervening clip. // + // Virtual layer tree: // root (a render surface) - // + clip_parent (masks to bounds) + // + clip_parent (clips) // + render_surface1 (sets opacity) - // + intervening (masks to bounds) + // + intervening (clips) // + render_surface2 (also sets opacity) - // + clip_child + // + clip_child (clipped by clip_parent) // LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_parent); - LayerImpl* intervening = AddChild<LayerImpl>(render_surface1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(intervening); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface2); - render_surface1->SetDrawsContent(true); - render_surface2->SetDrawsContent(true); - clip_child->SetDrawsContent(true); - - clip_child->test_properties()->clip_parent = clip_parent; - - intervening->SetMasksToBounds(true); - clip_parent->SetMasksToBounds(true); - - gfx::Transform translation_transform; - translation_transform.Translate(2, 2); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* intervening = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); - clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f); + clip_parent->SetBounds(gfx::Size(40, 40)); + clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(1, 1)); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); + + render_surface1->SetDrawsContent(true); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - intervening->test_properties()->position = gfx::PointF(1.f, 1.f); + CopyProperties(clip_parent, render_surface1); + CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(1, 1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + intervening->SetBounds(gfx::Size(5, 5)); + intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1)); + CopyProperties(render_surface1, intervening); + CreateClipNode(intervening); + + render_surface2->SetDrawsContent(true); render_surface2->SetBounds(gfx::Size(10, 10)); - render_surface2->test_properties()->force_render_surface = true; - clip_child->test_properties()->position = gfx::PointF(-10.f, -10.f); + CopyProperties(intervening, render_surface2); + CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(1, 1); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + clip_child->SetBounds(gfx::Size(60, 60)); + clip_child->SetDrawsContent(true); + clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10)); + CopyProperties(render_surface2, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(GetRenderSurface(root)); @@ -5266,47 +5290,59 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { // is a scroll involved. Note, we do _not_ have to consider any other sort // of transform. // + // Virtual layer tree: // root (a render surface) - // + clip_parent (masks to bounds) - // + render_surface1 (sets opacity) - // + intervening (masks to bounds AND scrolls) - // + render_surface2 (also sets opacity) - // + clip_child + // + clip_parent (clips and transforms) + // + render_surface1 (has render surface) + // + intervening (clips AND scrolls) + // + render_surface2 (also has render surface) + // + clip_child (clipped by clip_parent) // LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(clip_parent); - LayerImpl* intervening = AddChild<LayerImpl>(render_surface1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(intervening); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface2); - render_surface1->SetDrawsContent(true); - render_surface2->SetDrawsContent(true); - clip_child->SetDrawsContent(true); - - clip_child->test_properties()->clip_parent = clip_parent; - - intervening->SetMasksToBounds(true); - clip_parent->SetMasksToBounds(true); - intervening->SetScrollable(gfx::Size(1, 1)); - intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id())); - - gfx::Transform translation_transform; - translation_transform.Translate(2, 2); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* intervening = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); - clip_parent->test_properties()->transform = translation_transform; - clip_parent->test_properties()->position = gfx::PointF(1.f, 1.f); + clip_parent->SetBounds(gfx::Size(40, 40)); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + auto& clip_parent_transform = CreateTransformNode(clip_parent); + clip_parent_transform.local.Translate(2, 2); + clip_parent_transform.post_translation = gfx::Vector2dF(1, 1); + CreateClipNode(clip_parent); + + render_surface1->SetDrawsContent(true); render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->force_render_surface = true; - intervening->test_properties()->position = gfx::PointF(1.f, 1.f); + CopyProperties(clip_parent, render_surface1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + intervening->SetBounds(gfx::Size(5, 5)); + intervening->SetScrollable(gfx::Size(1, 1)); + intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id())); + CopyProperties(render_surface1, intervening); + CreateTransformNode(intervening).post_translation = gfx::Vector2dF(1, 1); + CreateScrollNode(intervening); + CreateClipNode(intervening); + + render_surface2->SetDrawsContent(true); render_surface2->SetBounds(gfx::Size(10, 10)); - render_surface2->test_properties()->force_render_surface = true; - clip_child->test_properties()->position = gfx::PointF(-10.f, -10.f); + CopyProperties(intervening, render_surface2); + CreateTransformNode(render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + clip_child->SetBounds(gfx::Size(60, 60)); - BuildPropertyTreesForTesting(); - intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3)); + clip_child->SetDrawsContent(true); + clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10)); + CopyProperties(render_surface2, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + + SetScrollOffset(intervening, gfx::ScrollOffset(3, 3)); ExecuteCalculateDrawProperties(root); EXPECT_TRUE(GetRenderSurface(root)); @@ -5351,32 +5387,38 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { // Ensures that descendants of the clip child inherit the correct clip. // + // Virtual layer tree: // root (a render surface) - // + clip_parent (masks to bounds) - // + intervening (masks to bounds) - // + clip_child + // + clip_parent (clips) + // + intervening (clips) + // + clip_child (clipped by clip_parent, skipping intervening) // + child // LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChild<LayerImpl>(root); - LayerImpl* intervening = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(intervening); - LayerImpl* child = AddChild<LayerImpl>(clip_child); - clip_child->SetDrawsContent(true); - child->SetDrawsContent(true); - - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* intervening = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); + clip_parent->SetBounds(gfx::Size(40, 40)); - clip_parent->SetMasksToBounds(true); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); + intervening->SetBounds(gfx::Size(5, 5)); - intervening->SetMasksToBounds(true); + CopyProperties(clip_parent, intervening); + CreateClipNode(intervening); + + clip_child->SetDrawsContent(true); clip_child->SetBounds(gfx::Size(60, 60)); + CopyProperties(intervening, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + + child->SetDrawsContent(true); child->SetBounds(gfx::Size(60, 60)); + CopyProperties(clip_child, child); ExecuteCalculateDrawProperties(root); @@ -5396,47 +5438,52 @@ TEST_F(LayerTreeHostCommonTest, // render surfaces. // // root (a render surface) - // + clip_parent (masks to bounds) - // + clip_layer (masks to bounds) + // + clip_parent (clips) + // + clip_layer (clips) // + render_surface1 - // + clip_child + // + clip_child (clipped by clip_parent) // + render_surface2 - // + non_clip_child + // + non_clip_child (in normal clip hierarchy) // // In this example render_surface2 should be unaffected by clip_child. LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - 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_layer); - LayerImpl* non_clip_child = AddChild<LayerImpl>(render_surface2); - - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); - - clip_parent->SetMasksToBounds(true); - clip_layer->SetMasksToBounds(true); - - render_surface1->SetDrawsContent(true); - clip_child->SetDrawsContent(true); - render_surface2->SetDrawsContent(true); - non_clip_child->SetDrawsContent(true); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* non_clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(15, 15)); clip_parent->SetBounds(gfx::Size(10, 10)); clip_layer->SetBounds(gfx::Size(10, 10)); - render_surface1->test_properties()->position = gfx::PointF(5, 5); + render_surface1->SetDrawsContent(true); render_surface1->SetBounds(gfx::Size(5, 5)); - render_surface1->test_properties()->force_render_surface = true; + render_surface2->SetDrawsContent(true); render_surface2->SetBounds(gfx::Size(5, 5)); - render_surface2->test_properties()->force_render_surface = true; - clip_child->test_properties()->position = gfx::PointF(-1, 1); + clip_child->SetDrawsContent(true); + clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-1, 1)); clip_child->SetBounds(gfx::Size(10, 10)); + non_clip_child->SetDrawsContent(true); non_clip_child->SetBounds(gfx::Size(5, 5)); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, render_surface1); + CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(5, 5); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(clip_layer, render_surface2); + CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(5, 5); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + CopyProperties(render_surface2, non_clip_child); + ExecuteCalculateDrawProperties(root); EXPECT_TRUE(GetRenderSurface(root)); @@ -5468,70 +5515,85 @@ TEST_F(LayerTreeHostCommonTest, GetRenderSurface(render_surface2)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, CreateRenderSurfaceWhenFlattenInsideRenderingContext) { // Verifies that Render Surfaces are created at the edge of rendering context. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child1 = AddChildToRoot<LayerImpl>(); - LayerImpl* child2 = AddChild<LayerImpl>(child1); - LayerImpl* child3 = AddChild<LayerImpl>(child2); - root->SetDrawsContent(true); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child1 = Layer::Create(); + root->AddChild(child1); + auto child2 = Layer::Create(); + child1->AddChild(child2); + auto child3 = Layer::Create(); + child2->AddChild(child3); + root->SetIsDrawable(true); gfx::Size bounds(100, 100); root->SetBounds(bounds); child1->SetBounds(bounds); - child1->SetDrawsContent(true); - child1->test_properties()->should_flatten_transform = false; - child1->test_properties()->sorting_context_id = 1; + child1->SetIsDrawable(true); + child1->SetShouldFlattenTransform(false); + child1->Set3dSortingContextId(1); child2->SetBounds(bounds); - child2->SetDrawsContent(true); - child2->test_properties()->sorting_context_id = 1; + child2->SetIsDrawable(true); + child2->Set3dSortingContextId(1); child3->SetBounds(bounds); - child3->SetDrawsContent(true); - child3->test_properties()->sorting_context_id = 1; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + child3->SetIsDrawable(true); + child3->Set3dSortingContextId(1); + + CommitAndActivate(); // Verify which render surfaces were created. - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child1), GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(child2), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child3), GetRenderSurface(child2)); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child1), GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child3), GetRenderSurfaceImpl(child2)); } -TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* back_facing = AddChild<LayerImpl>(root); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + DoNotIncludeBackfaceInvisibleSurfaces) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto back_facing = Layer::Create(); + root->AddChild(back_facing); - LayerImpl* render_surface1 = AddChild<LayerImpl>(back_facing); - LayerImpl* child1 = AddChild<LayerImpl>(render_surface1); + auto render_surface1 = Layer::Create(); + back_facing->AddChild(render_surface1); + auto child1 = Layer::Create(); + render_surface1->AddChild(child1); - LayerImpl* flattener = AddChild<LayerImpl>(back_facing); - LayerImpl* render_surface2 = AddChild<LayerImpl>(flattener); - LayerImpl* child2 = AddChild<LayerImpl>(render_surface2); + auto flattener = Layer::Create(); + back_facing->AddChild(flattener); + auto render_surface2 = Layer::Create(); + flattener->AddChild(render_surface2); + auto child2 = Layer::Create(); + render_surface2->AddChild(child2); - child1->SetDrawsContent(true); - child2->SetDrawsContent(true); + child1->SetIsDrawable(true); + child2->SetIsDrawable(true); root->SetBounds(gfx::Size(50, 50)); back_facing->SetBounds(gfx::Size(50, 50)); - back_facing->test_properties()->should_flatten_transform = false; + back_facing->SetShouldFlattenTransform(false); render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->test_properties()->should_flatten_transform = false; - render_surface1->test_properties()->force_render_surface = true; - render_surface1->test_properties()->double_sided = false; + render_surface1->SetShouldFlattenTransform(false); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetDoubleSided(false); child1->SetBounds(gfx::Size(20, 20)); flattener->SetBounds(gfx::Size(30, 30)); render_surface2->SetBounds(gfx::Size(30, 30)); - render_surface2->test_properties()->should_flatten_transform = false; - render_surface2->test_properties()->force_render_surface = true; - render_surface2->test_properties()->double_sided = false; + render_surface2->SetShouldFlattenTransform(false); + render_surface2->SetForceRenderSurfaceForTesting(true); + render_surface2->SetDoubleSided(false); child2->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); EXPECT_EQ(3u, render_surface_list_impl()->size()); EXPECT_EQ(2, render_surface_list_impl()->at(0)->num_contributors()); @@ -5539,11 +5601,9 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { gfx::Transform rotation_transform; rotation_transform.RotateAboutXAxis(180.0); + back_facing->SetTransform(rotation_transform); - back_facing->test_properties()->transform = rotation_transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); // render_surface1 is in the same 3d rendering context as back_facing and is // not double sided, so it should not be in RSLL. render_surface2 is also not @@ -5553,188 +5613,166 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { EXPECT_EQ(1, render_surface_list_impl()->at(0)->num_contributors()); } -TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + DoNotIncludeBackfaceInvisibleLayers) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grand_child = Layer::Create(); + child->AddChild(grand_child); root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->should_flatten_transform = false; + root->SetShouldFlattenTransform(false); child->SetBounds(gfx::Size(30, 30)); - child->test_properties()->double_sided = false; - child->test_properties()->should_flatten_transform = false; + child->SetDoubleSided(false); + child->SetShouldFlattenTransform(false); grand_child->SetBounds(gfx::Size(20, 20)); - grand_child->SetDrawsContent(true); + grand_child->SetIsDrawable(true); grand_child->SetUseParentBackfaceVisibility(true); - grand_child->test_properties()->should_flatten_transform = false; - ExecuteCalculateDrawProperties(root); + grand_child->SetShouldFlattenTransform(false); + + CommitAndActivate(); EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_TRUE(grand_child->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child)->contributes_to_drawn_render_surface()); // A ll layers with invisible backfgaces should be checked. - EXPECT_FALSE(root->should_check_backface_visibility()); - EXPECT_TRUE(child->should_check_backface_visibility()); - EXPECT_TRUE(grand_child->should_check_backface_visibility()); + EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); gfx::Transform rotation_transform; rotation_transform.RotateAboutXAxis(180.0); - child->test_properties()->transform = rotation_transform; - child->test_properties()->sorting_context_id = 1; - grand_child->test_properties()->sorting_context_id = 1; - child->layer_tree_impl()->property_trees()->needs_rebuild = true; + child->SetTransform(rotation_transform); + child->Set3dSortingContextId(1); + grand_child->Set3dSortingContextId(1); + + CommitAndActivate(); - ExecuteCalculateDrawProperties(root); EXPECT_EQ(1u, render_surface_list_impl()->size()); EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); // We should check for backface visibilty of child as it has a rotation // transform. We should also check for grand_child as it uses the backface // visibility of its parent. - EXPECT_FALSE(root->should_check_backface_visibility()); - EXPECT_TRUE(child->should_check_backface_visibility()); - EXPECT_TRUE(grand_child->should_check_backface_visibility()); + EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); grand_child->SetUseParentBackfaceVisibility(false); - grand_child->test_properties()->double_sided = false; - grand_child->layer_tree_impl()->property_trees()->needs_rebuild = true; + grand_child->SetDoubleSided(false); + + CommitAndActivate(); - ExecuteCalculateDrawProperties(root); EXPECT_EQ(1u, render_surface_list_impl()->size()); EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); // We should check the backface visibility of child as it has a rotation // transform and for grand_child as it is in a 3d rendering context and not // the root of it. - EXPECT_FALSE(root->should_check_backface_visibility()); - EXPECT_TRUE(child->should_check_backface_visibility()); - EXPECT_TRUE(grand_child->should_check_backface_visibility()); + EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); + EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); } TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* back_facing = AddChild<LayerImpl>(root); - LayerImpl* render_surface1 = AddChild<LayerImpl>(back_facing); - LayerImpl* render_surface2 = AddChild<LayerImpl>(back_facing); + LayerImpl* back_facing = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); gfx::Transform rotate_about_y; rotate_about_y.RotateAboutYAxis(180.0); root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->should_flatten_transform = false; - root->test_properties()->sorting_context_id = 1; - back_facing->test_properties()->transform = rotate_about_y; back_facing->SetBounds(gfx::Size(50, 50)); - back_facing->test_properties()->should_flatten_transform = false; - back_facing->test_properties()->sorting_context_id = 1; render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->test_properties()->should_flatten_transform = false; - render_surface1->test_properties()->double_sided = false; - render_surface1->test_properties()->force_render_surface = true; - render_surface1->test_properties()->sorting_context_id = 1; render_surface2->SetBounds(gfx::Size(30, 30)); - render_surface2->test_properties()->should_flatten_transform = false; - 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 = - root->layer_tree_impl()->property_trees()->effect_tree; - EXPECT_TRUE(tree.Node(render_surface1->effect_tree_index()) - ->hidden_by_backface_visibility); - EXPECT_TRUE(tree.Node(render_surface2->effect_tree_index()) - ->hidden_by_backface_visibility); + SetupRootProperties(root); + CopyProperties(root, back_facing); + auto& back_facing_transform_node = CreateTransformNode(back_facing); + back_facing_transform_node.flattens_inherited_transform = false; + back_facing_transform_node.sorting_context_id = 1; + back_facing_transform_node.local = rotate_about_y; + CopyProperties(back_facing, render_surface1); + auto& render_surface1_transform_node = CreateTransformNode(render_surface1); + render_surface1_transform_node.flattens_inherited_transform = false; + render_surface1_transform_node.sorting_context_id = 1; + auto& render_surface1_effect_node = CreateEffectNode(render_surface1); + render_surface1_effect_node.render_surface_reason = + RenderSurfaceReason::kTest; + render_surface1_effect_node.double_sided = false; + CopyProperties(back_facing, render_surface2); + auto& render_surface2_transform_node = CreateTransformNode(render_surface2); + render_surface2_transform_node.flattens_inherited_transform = false; + render_surface2_transform_node.sorting_context_id = 1; + auto& render_surface2_effect_node = CreateEffectNode(render_surface2); + render_surface2_effect_node.render_surface_reason = + RenderSurfaceReason::kTest; + render_surface2_effect_node.double_sided = false; + + ExecuteCalculateDrawProperties(root); + + EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); + EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); 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); + EXPECT_FALSE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); + EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); 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); - EXPECT_TRUE(tree.Node(render_surface2->effect_tree_index()) - ->hidden_by_backface_visibility); -} - -TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) { - // Checks that the simple case (being clipped by a scroll parent that would - // have been processed before you anyhow) results in the right clips. - // - // + root - // + scroll_parent_border - // | + scroll_parent_clip - // | + scroll_parent - // + scroll_child - // - LayerImpl* root = root_layer_for_testing(); - LayerImpl* scroll_parent_border = AddChildToRoot<LayerImpl>(); - LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip); - LayerImpl* scroll_child = AddChild<LayerImpl>(root); - - scroll_parent->SetDrawsContent(true); - scroll_child->SetDrawsContent(true); - scroll_parent_clip->SetMasksToBounds(true); - - scroll_child->test_properties()->scroll_parent = scroll_parent; - - root->SetBounds(gfx::Size(50, 50)); - scroll_parent_border->SetBounds(gfx::Size(40, 40)); - scroll_parent_clip->SetBounds(gfx::Size(30, 30)); - scroll_parent->SetBounds(gfx::Size(50, 50)); - scroll_child->SetBounds(gfx::Size(50, 50)); - ExecuteCalculateDrawProperties(root); - - EXPECT_TRUE(GetRenderSurface(root)); - - EXPECT_EQ(gfx::Rect(0, 0, 30, 30), scroll_child->clip_rect()); - EXPECT_TRUE(scroll_child->is_clipped()); + EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); + EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); } TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { // Tests the computation of draw transform for the scroll child when its - // target is different from its scroll parent's target. + // render surface is different from its scroll parent's render surface. LayerImpl* root = root_layer_for_testing(); - LayerImpl* scroll_child_target = AddChildToRoot<LayerImpl>(); - LayerImpl* scroll_child = AddChild<LayerImpl>(scroll_child_target); - LayerImpl* scroll_parent_target = AddChild<LayerImpl>(scroll_child_target); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_target); - - scroll_parent->SetDrawsContent(true); - scroll_child->SetDrawsContent(true); - - scroll_child->test_properties()->scroll_parent = scroll_parent; + LayerImpl* scroll_child_target = AddLayer<LayerImpl>(); + LayerImpl* scroll_child = AddLayer<LayerImpl>(); + LayerImpl* scroll_parent_target = AddLayer<LayerImpl>(); + LayerImpl* scroll_parent = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); scroll_child_target->SetBounds(gfx::Size(50, 50)); - scroll_child_target->test_properties()->force_render_surface = true; - scroll_child->SetBounds(gfx::Size(50, 50)); - scroll_parent_target->test_properties()->position = gfx::PointF(10, 10); 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)); + scroll_parent->SetDrawsContent(true); + scroll_child->SetBounds(gfx::Size(50, 50)); + scroll_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, scroll_child_target); + auto& child_target_effect_node = CreateEffectNode(scroll_child_target); + child_target_effect_node.render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(scroll_child_target, scroll_parent_target); + CreateTransformNode(scroll_parent_target).post_translation = + gfx::Vector2dF(10, 10); + CreateScrollNode(scroll_parent_target); + CreateEffectNode(scroll_parent_target).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(scroll_parent_target); + CopyProperties(scroll_parent_target, scroll_parent); + // Let |scroll_child| inherit |scroll_parent|'s transform/clip/scroll states, + CopyProperties(scroll_parent, scroll_child); + // and |scroll_child_target|'s effect state. + scroll_child->SetEffectTreeIndex(scroll_child_target->effect_tree_index()); + scroll_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10)); float device_scale_factor = 1.5f; - RenderSurfaceList render_surface_list_impl; - gfx::Size device_viewport_size = - gfx::Size(root->bounds().width() * device_scale_factor, - root->bounds().height() * device_scale_factor); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, gfx::Transform(), &render_surface_list_impl); - inputs.device_scale_factor = device_scale_factor; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root, device_scale_factor); EXPECT_EQ(scroll_child->effect_tree_index(), scroll_child_target->effect_tree_index()); @@ -5747,20 +5785,24 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(parent); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); root->SetDrawsContent(true); - root->test_properties()->sorting_context_id = 1; parent->SetBounds(gfx::Size(30, 30)); parent->SetDrawsContent(true); - parent->test_properties()->force_render_surface = true; - parent->test_properties()->sorting_context_id = 1; child->SetBounds(gfx::Size(20, 20)); child->SetDrawsContent(true); - child->test_properties()->force_render_surface = true; - child->test_properties()->sorting_context_id = 1; + + SetupRootProperties(root); + CopyProperties(root, parent); + CreateTransformNode(parent).sorting_context_id = 1; + CreateEffectNode(parent).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(parent, child); + CreateTransformNode(child).sorting_context_id = 1; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + ExecuteCalculateDrawProperties(root); EXPECT_EQ(3u, render_surface_list_impl()->size()); @@ -5769,381 +5811,71 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { singular_transform.Scale3d( SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); - child->test_properties()->transform = singular_transform; - - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetTransform(child, singular_transform); ExecuteCalculateDrawProperties(root); EXPECT_EQ(2u, render_surface_list_impl()->size()); // Ensure that the entire subtree under a layer with singular transform does // not get rendered. - parent->test_properties()->transform = singular_transform; - child->test_properties()->transform = gfx::Transform(); - - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetTransform(parent, singular_transform); + SetTransform(child, gfx::Transform()); ExecuteCalculateDrawProperties(root); EXPECT_EQ(1u, render_surface_list_impl()->size()); } -TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { - // Checks that clipping by a scroll parent that follows you in paint order - // still results in correct clipping. - // - // + root - // + scroll_parent_border - // + scroll_parent_clip - // + scroll_parent - // + scroll_child - // - LayerImpl* root = root_layer_for_testing(); - LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root); - LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip); - LayerImpl* scroll_child = AddChild<LayerImpl>(root); - - scroll_parent->SetDrawsContent(true); - scroll_child->SetDrawsContent(true); - - root->SetBounds(gfx::Size(50, 50)); - scroll_parent_border->SetBounds(gfx::Size(40, 40)); - scroll_parent_clip->SetBounds(gfx::Size(30, 30)); - scroll_parent_clip->SetMasksToBounds(true); - scroll_parent->SetBounds(gfx::Size(50, 50)); - scroll_child->SetBounds(gfx::Size(50, 50)); - - scroll_child->test_properties()->scroll_parent = scroll_parent; - - ExecuteCalculateDrawProperties(root); - - EXPECT_TRUE(GetRenderSurface(root)); - - EXPECT_EQ(gfx::Rect(0, 0, 30, 30), scroll_child->clip_rect()); - EXPECT_TRUE(scroll_child->is_clipped()); -} - -TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { - // Checks that clipping by a scroll parent and scroll grandparent that follow - // you in paint order still results in correct clipping. - // - // + root - // + scroll_child - // + scroll_parent_border - // | + scroll_parent_clip - // | + scroll_parent - // + scroll_grandparent_border - // + scroll_grandparent_clip - // + scroll_grandparent - // - LayerImpl* root = root_layer_for_testing(); - LayerImpl* scroll_child = AddChild<LayerImpl>(root); - LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root); - LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip); - LayerImpl* scroll_grandparent_border = AddChild<LayerImpl>(root); - LayerImpl* scroll_grandparent_clip = - AddChild<LayerImpl>(scroll_grandparent_border); - LayerImpl* scroll_grandparent = AddChild<LayerImpl>(scroll_grandparent_clip); - - scroll_parent->SetDrawsContent(true); - scroll_grandparent->SetDrawsContent(true); - scroll_child->SetDrawsContent(true); - - scroll_parent_clip->SetMasksToBounds(true); - scroll_grandparent_clip->SetMasksToBounds(true); - - scroll_child->test_properties()->scroll_parent = scroll_parent; - - scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; - - root->SetBounds(gfx::Size(50, 50)); - scroll_grandparent_border->SetBounds(gfx::Size(40, 40)); - scroll_grandparent_clip->SetBounds(gfx::Size(20, 20)); - scroll_grandparent->SetBounds(gfx::Size(50, 50)); - scroll_parent_border->SetBounds(gfx::Size(40, 40)); - scroll_parent_clip->SetBounds(gfx::Size(30, 30)); - scroll_parent->SetBounds(gfx::Size(50, 50)); - scroll_child->SetBounds(gfx::Size(50, 50)); - - ExecuteCalculateDrawProperties(root); - - EXPECT_TRUE(GetRenderSurface(root)); - - EXPECT_EQ(gfx::Rect(0, 0, 20, 20), scroll_child->clip_rect()); - EXPECT_TRUE(scroll_child->is_clipped()); - - // Despite the fact that we visited the above layers out of order to get the - // correct clip, the layer lists should be unaffected. - EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); - EXPECT_TRUE(scroll_child->contributes_to_drawn_render_surface()); - EXPECT_TRUE(scroll_parent->contributes_to_drawn_render_surface()); - EXPECT_TRUE(scroll_grandparent->contributes_to_drawn_render_surface()); -} - -TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { - // Ensures that even if we visit layers out of order, we still produce a - // correctly ordered render surface layer list. - // + root - // + scroll_child - // + scroll_parent_border - // + scroll_parent_clip - // + scroll_parent - // + render_surface2 - // + scroll_grandparent_border - // + scroll_grandparent_clip - // + scroll_grandparent - // + render_surface1 - // - LayerImpl* root = root_layer_for_testing(); - root->SetDrawsContent(true); - - LayerImpl* scroll_child = AddChild<LayerImpl>(root); - scroll_child->SetDrawsContent(true); - - LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root); - LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip); - LayerImpl* render_surface2 = AddChild<LayerImpl>(scroll_parent); - LayerImpl* scroll_grandparent_border = AddChild<LayerImpl>(root); - LayerImpl* scroll_grandparent_clip = - AddChild<LayerImpl>(scroll_grandparent_border); - LayerImpl* scroll_grandparent = AddChild<LayerImpl>(scroll_grandparent_clip); - LayerImpl* render_surface1 = AddChild<LayerImpl>(scroll_grandparent); - - scroll_parent->SetDrawsContent(true); - render_surface1->SetDrawsContent(true); - scroll_grandparent->SetDrawsContent(true); - render_surface2->SetDrawsContent(true); - - scroll_parent_clip->SetMasksToBounds(true); - scroll_grandparent_clip->SetMasksToBounds(true); - - scroll_child->test_properties()->scroll_parent = scroll_parent; - - scroll_parent_border->test_properties()->scroll_parent = scroll_grandparent; - - root->SetBounds(gfx::Size(50, 50)); - scroll_grandparent_border->SetBounds(gfx::Size(40, 40)); - scroll_grandparent_clip->SetBounds(gfx::Size(20, 20)); - scroll_grandparent->SetBounds(gfx::Size(50, 50)); - render_surface1->SetBounds(gfx::Size(50, 50)); - render_surface1->test_properties()->force_render_surface = true; - scroll_parent_border->SetBounds(gfx::Size(40, 40)); - scroll_parent_clip->SetBounds(gfx::Size(30, 30)); - scroll_parent->SetBounds(gfx::Size(50, 50)); - render_surface2->SetBounds(gfx::Size(50, 50)); - render_surface2->test_properties()->force_render_surface = true; - scroll_child->SetBounds(gfx::Size(50, 50)); - - ExecuteCalculateDrawProperties(root); - - EXPECT_TRUE(GetRenderSurface(root)); - - EXPECT_EQ(gfx::Rect(0, 0, 20, 20), scroll_child->clip_rect()); - EXPECT_TRUE(scroll_child->is_clipped()); - - // Despite the fact that we had to process the layers out of order to get the - // right clip, our render_surface_list's order should be unaffected. - EXPECT_EQ(3u, render_surface_list_impl()->size()); - EXPECT_EQ(GetRenderSurface(root), render_surface_list_impl()->at(0)); - EXPECT_EQ(GetRenderSurface(render_surface2), - render_surface_list_impl()->at(1)); - EXPECT_EQ(GetRenderSurface(render_surface1), - render_surface_list_impl()->at(2)); -} - -TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) { - // Ensures that when we have a render surface between a fixed position layer - // and its container, we compute the fixed position layer's draw transform - // with respect to that intervening render surface, not with respect to its - // container's render target. +TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { + // This test verifies that a scrolling layer gets scroll offset snapped to + // integer coordinates. // + // Virtual layer hierarchy: // + root - // + render_surface - // + fixed - // + child + // + container + // + scroller // LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChild<LayerImpl>(root); - LayerImpl* fixed = AddChild<LayerImpl>(render_surface); - LayerImpl* child = AddChild<LayerImpl>(fixed); - - render_surface->test_properties()->force_render_surface = true; - root->test_properties()->is_container_for_fixed_position_layers = true; - - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - fixed->test_properties()->position_constraint = constraint; + LayerImpl* container = AddLayer<LayerImpl>(); + LayerImpl* scroller = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); - render_surface->test_properties()->position = gfx::PointF(7.f, 9.f); - render_surface->SetBounds(gfx::Size(50, 50)); - render_surface->SetDrawsContent(true); - fixed->test_properties()->position = gfx::PointF(10.f, 15.f); - fixed->SetBounds(gfx::Size(50, 50)); - fixed->SetDrawsContent(true); - child->test_properties()->position = gfx::PointF(1.f, 2.f); - child->SetBounds(gfx::Size(50, 50)); - child->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); - - TransformTree& transform_tree = - host_impl()->active_tree()->property_trees()->transform_tree; - EffectTree& effect_tree = - host_impl()->active_tree()->property_trees()->effect_tree; - gfx::Transform expected_fixed_draw_transform; - expected_fixed_draw_transform.Translate(10.f, 15.f); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_fixed_draw_transform, - draw_property_utils::DrawTransform(fixed, transform_tree, effect_tree)); - - gfx::Transform expected_fixed_screen_space_transform; - expected_fixed_screen_space_transform.Translate(17.f, 24.f); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_fixed_screen_space_transform, - draw_property_utils::ScreenSpaceTransform(fixed, transform_tree)); - - gfx::Transform expected_child_draw_transform; - expected_child_draw_transform.Translate(11.f, 17.f); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_draw_transform, - draw_property_utils::DrawTransform(child, transform_tree, effect_tree)); - - gfx::Transform expected_child_screen_space_transform; - expected_child_screen_space_transform.Translate(18.f, 26.f); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_screen_space_transform, - draw_property_utils::ScreenSpaceTransform(child, transform_tree)); -} + container->SetBounds(gfx::Size(40, 40)); + container->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, container); -TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { - // This test verifies that a scrolling layer that gets snapped to - // integer coordinates doesn't move a fixed position child. - // - // + root - // + container - // + scroller - // + fixed - // - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl.active_tree(), 1); - LayerImpl* root = root_ptr.get(); - std::unique_ptr<LayerImpl> container = - LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* container_layer = container.get(); - std::unique_ptr<LayerImpl> scroller = - LayerImpl::Create(host_impl.active_tree(), 3); - LayerImpl* scroll_layer = scroller.get(); - std::unique_ptr<LayerImpl> fixed = - LayerImpl::Create(host_impl.active_tree(), 4); - LayerImpl* fixed_layer = fixed.get(); - - container->test_properties()->is_container_for_fixed_position_layers = true; - - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - fixed->test_properties()->position_constraint = constraint; + gfx::Vector2dF container_offset(10, 20); scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - - gfx::Transform container_transform; - container_transform.Translate3d(10.0, 20.0, 0.0); - gfx::Vector2dF container_offset = container_transform.To2dTranslation(); - - root->SetBounds(gfx::Size(50, 50)); - container->test_properties()->transform = container_transform; - container->SetBounds(gfx::Size(40, 40)); - container->SetDrawsContent(true); scroller->SetBounds(gfx::Size(30, 30)); scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); - fixed->SetBounds(gfx::Size(50, 50)); - fixed->SetDrawsContent(true); - - scroller->test_properties()->AddChild(std::move(fixed)); - container->test_properties()->AddChild(std::move(scroller)); - root->test_properties()->AddChild(std::move(container)); - root->layer_tree_impl()->SetRootLayerForTesting(std::move(root_ptr)); - root->layer_tree_impl()->BuildPropertyTreesForTesting(); + CopyProperties(container, scroller); + CreateTransformNode(scroller).post_translation = container_offset; + CreateScrollNode(scroller); // Rounded to integers already. { gfx::Vector2dF scroll_delta(3.0, 5.0); - SetScrollOffsetDelta(scroll_layer, scroll_delta); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - root->layer_tree_impl() - ->property_trees() - ->transform_tree.set_source_to_parent_updates_allowed(false); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + SetScrollOffsetDelta(scroller, scroll_delta); + ExecuteCalculateDrawProperties(root); - EXPECT_TRANSFORMATION_MATRIX_EQ( - container_layer->draw_properties().screen_space_transform, - fixed_layer->draw_properties().screen_space_transform); EXPECT_VECTOR_EQ( - fixed_layer->draw_properties().screen_space_transform.To2dTranslation(), - container_offset); - EXPECT_VECTOR_EQ(scroll_layer->draw_properties() - .screen_space_transform.To2dTranslation(), - container_offset - scroll_delta); + scroller->draw_properties().screen_space_transform.To2dTranslation(), + container_offset - scroll_delta); } // Scroll delta requiring rounding. { gfx::Vector2dF scroll_delta(4.1f, 8.1f); - SetScrollOffsetDelta(scroll_layer, scroll_delta); + SetScrollOffsetDelta(scroller, scroll_delta); + ExecuteCalculateDrawProperties(root); gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - - EXPECT_TRANSFORMATION_MATRIX_EQ( - container_layer->draw_properties().screen_space_transform, - fixed_layer->draw_properties().screen_space_transform); EXPECT_VECTOR_EQ( - fixed_layer->draw_properties().screen_space_transform.To2dTranslation(), - container_offset); - EXPECT_VECTOR_EQ(scroll_layer->draw_properties() - .screen_space_transform.To2dTranslation(), - container_offset - rounded_scroll_delta); - } - - // Scale is applied earlier in the tree. - { - SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF()); - gfx::Transform scaled_container_transform = container_transform; - scaled_container_transform.Scale3d(2.0, 2.0, 1.0); - container_layer->test_properties()->transform = scaled_container_transform; - - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - - gfx::Vector2dF scroll_delta(4.5f, 8.5f); - SetScrollOffsetDelta(scroll_layer, scroll_delta); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - - EXPECT_TRANSFORMATION_MATRIX_EQ( - container_layer->draw_properties().screen_space_transform, - fixed_layer->draw_properties().screen_space_transform); - EXPECT_VECTOR_EQ( - fixed_layer->draw_properties().screen_space_transform.To2dTranslation(), - container_offset); - - container_layer->test_properties()->transform = container_transform; + scroller->draw_properties().screen_space_transform.To2dTranslation(), + container_offset - rounded_scroll_delta); } } @@ -6152,6 +5884,7 @@ TEST_F(LayerTreeHostCommonTest, // This test verifies that a scrolling layer whose screen space transform is // animating doesn't get snapped to integer coordinates. // + // Virtual layer hierarchy: // + root // + animated layer // + surface @@ -6159,24 +5892,35 @@ TEST_F(LayerTreeHostCommonTest, // + scroller // LayerImpl* root = root_layer_for_testing(); - LayerImpl* animated_layer = AddChildToRoot<FakePictureLayerImpl>(); - LayerImpl* surface = AddChild<LayerImpl>(animated_layer); - LayerImpl* container = AddChild<LayerImpl>(surface); - LayerImpl* scroller = AddChild<LayerImpl>(container); + LayerImpl* animated_layer = AddLayer<FakePictureLayerImpl>(); + LayerImpl* surface = AddLayer<LayerImpl>(); + LayerImpl* container = AddLayer<LayerImpl>(); + LayerImpl* scroller = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); + + root->SetBounds(gfx::Size(50, 50)); gfx::Transform start_scale; start_scale.Scale(1.5f, 1.5f); - root->SetBounds(gfx::Size(50, 50)); - animated_layer->test_properties()->transform = start_scale; animated_layer->SetBounds(gfx::Size(50, 50)); + SetupRootProperties(root); + CopyProperties(root, animated_layer); + CreateTransformNode(animated_layer).local = start_scale; + surface->SetBounds(gfx::Size(50, 50)); - surface->test_properties()->force_render_surface = true; + CopyProperties(animated_layer, surface); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + container->SetBounds(gfx::Size(50, 50)); + CopyProperties(surface, container); + scroller->SetBounds(gfx::Size(100, 100)); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); + CopyProperties(container, scroller); + CreateTransformNode(scroller); + CreateScrollNode(scroller); gfx::Transform end_scale; end_scale.Scale(2.f, 2.f); @@ -6184,12 +5928,11 @@ TEST_F(LayerTreeHostCommonTest, start_operations.AppendMatrix(start_scale); TransformOperations end_operations; end_operations.AppendMatrix(end_scale); - SetElementIdsForTesting(); AddAnimatedTransformToElementWithAnimation(animated_layer->element_id(), timeline_impl(), 1.0, start_operations, end_operations); - BuildPropertyTreesForTesting(); + gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); @@ -6204,221 +5947,177 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { // This test verifies that a scrolling child of a scrolling layer doesn't get // snapped to integer coordinates. // + // Virtual layer hierarchy: // + root // + container - // + scroller - // + scroll_child + // + scroller + // + scroll_child (transform parent is scroller) // - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> scroll_child = Layer::Create(); - root->AddChild(container); - root->AddChild(scroll_child); - container->AddChild(scroller); - host()->SetRootLayer(root); - - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroll_child->SetScrollParent(scroller.get()); + LayerImpl* root = root_layer_for_testing(); + LayerImpl* container = AddLayer<LayerImpl>(); + LayerImpl* scroller = AddLayer<LayerImpl>(); + LayerImpl* scroll_child = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); - gfx::Transform rotate; - rotate.RotateAboutYAxis(30); root->SetBounds(gfx::Size(50, 50)); + container->SetBounds(gfx::Size(50, 50)); + SetupRootProperties(root); + CopyProperties(root, container); + gfx::Vector2dF container_offset(10.3f, 10.3f); + scroller->SetBounds(gfx::Size(100, 100)); scroller->SetScrollable(container->bounds()); - scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); - scroll_child->SetBounds(gfx::Size(10, 10)); - scroll_child->SetTransform(rotate); + CopyProperties(container, scroller); + CreateTransformNode(scroller).post_translation = container_offset; + CreateScrollNode(scroller); - ExecuteCalculateDrawProperties(root.get()); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + scroll_child->SetBounds(gfx::Size(10, 10)); + CopyProperties(root, scroll_child); + auto& scroll_child_transform = + CreateTransformNode(scroll_child, scroller->transform_tree_index()); + scroll_child_transform.local.RotateAboutYAxis(30); + scroll_child_transform.post_translation = -container_offset; - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); - LayerImpl* scroll_child_impl = layer_tree_impl->LayerById(scroll_child->id()); gfx::Vector2dF scroll_delta(5.f, 9.f); - SetScrollOffsetDelta(scroller_impl, scroll_delta); - - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller, scroll_delta); + ExecuteCalculateDrawProperties(root); gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f); EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation, - scroller_impl->ScreenSpaceTransform().To2dTranslation()); + scroller->ScreenSpaceTransform().To2dTranslation()); gfx::Transform expected_scroll_child_screen_space_transform; expected_scroll_child_screen_space_transform.Translate(-5.3f, -9.3f); expected_scroll_child_screen_space_transform.RotateAboutYAxis(30); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_child_screen_space_transform, - scroll_child_impl->ScreenSpaceTransform()); + scroll_child->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; - sticky_position.is_anchored_top = true; - sticky_position.top_offset = 10.0f; - sticky_position.scroll_container_relative_sticky_box_rect = - gfx::Rect(10, 20, 10, 10); - sticky_position.scroll_container_relative_containing_block_rect = - gfx::Rect(0, 0, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(10, 20)); +class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { + protected: + // Setup layers and property trees. + // Virtual layer hierarchy: + // + root + // + container + // + scroller + // + sticky_pos + void CreateTree() { + CreateRootAndScroller(); + sticky_pos_ = CreateSticky(scroller_.get()); + } - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + void CreateRootAndScroller() { + root_ = Layer::Create(); + container_ = Layer::Create(); + scroller_ = Layer::Create(); + scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id())); + + root_->SetBounds(gfx::Size(100, 100)); + host()->SetRootLayer(root_); + SetupRootProperties(root_.get()); + + container_->SetBounds(gfx::Size(100, 100)); + CopyProperties(root_.get(), container_.get()); + root_->AddChild(container_); + + scroller_->SetBounds(gfx::Size(1000, 1000)); + scroller_->SetScrollable(container_->bounds()); + CopyProperties(container_.get(), scroller_.get()); + CreateTransformNode(scroller_.get()); + CreateScrollNode(scroller_.get()); + root_->AddChild(scroller_); + } - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); - LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + scoped_refptr<Layer> CreateSticky(Layer* parent) { + scoped_refptr<Layer> sticky = Layer::Create(); + sticky->SetBounds(gfx::Size(10, 10)); + CopyProperties(parent, sticky.get()); + CreateTransformNode(sticky.get()); + EnsureStickyData(sticky.get()).scroll_ancestor = + parent->scroll_tree_index(); + root_->AddChild(sticky); + return sticky; + } - ExecuteCalculateDrawProperties(root_impl); - EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(10.f, 20.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + void CommitAndUpdateImplPointers() { + ExecuteCalculateDrawProperties(root_.get()); + host()->host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + host()->host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + root_impl_ = layer_tree_impl->LayerById(root_->id()); + scroller_impl_ = layer_tree_impl->LayerById(scroller_->id()); + sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id()); + } - // Scroll less than sticking point, sticky element should move with scroll as - // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); - EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(5.f, 15.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + StickyPositionNodeData& EnsureStickyData(Layer* layer) { + return GetPropertyTrees(layer)->transform_tree.EnsureStickyPositionData( + layer->transform_tree_index()); + } - // Scroll past the sticking point, the Y coordinate should now be clamped. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl); - EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(-5.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); - EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(-5.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + scoped_refptr<Layer> root_; + scoped_refptr<Layer> container_; + scoped_refptr<Layer> scroller_; + scoped_refptr<Layer> sticky_pos_; + LayerImpl* root_impl_; + LayerImpl* scroller_impl_; + LayerImpl* sticky_pos_impl_; +}; - // Scroll past the end of the sticky container (note: this element does not - // have its own layer as it does not need to be composited). - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl); - EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(-5.f, -10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); -} +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { + CreateTree(); -TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - root->AddChild(sticky_pos); - sticky_pos->SetScrollParent(scroller.get()); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->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; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 0, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(200, 200)); - container->SetBounds(gfx::Size(100, 100)); - container->SetPosition(gfx::PointF(50, 50)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(60, 70)); - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + CommitAndUpdateImplPointers(); - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); - LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); - - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(60.f, 70.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + gfx::Vector2dF(10.f, 20.f), + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(55.f, 65.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + gfx::Vector2dF(5.f, 15.f), + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(45.f, 60.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); + gfx::Vector2dF(-5.f, 10.f), + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(45.f, 60.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + gfx::Vector2dF(-5.f, 10.f), + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container (note: this element does not // have its own layer as it does not need to be composited). - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( - gfx::Vector2dF(45.f, 40.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + gfx::Vector2dF(-5.f, -10.f), + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) { + CreateTree(); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 200)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100); @@ -6426,46 +6125,22 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { gfx::Rect(0, 200, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 0, 100, 500); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(100, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 200)); - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + CommitAndUpdateImplPointers(); - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); - LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f)); - ExecuteCalculateDrawProperties(root_impl); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.8f)); - ExecuteCalculateDrawProperties(root_impl); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { + CreateTree(); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 150)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100); @@ -6473,81 +6148,52 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { gfx::Rect(0, 150, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 100, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 150)); - - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + CommitAndUpdateImplPointers(); // Initially the sticky element is moved up to the top of the container. - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 100.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 95.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Once we get past the top of the container it moves to be aligned 10px // up from the the bottom of the scroller. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Once we scroll past its initial location, it sticks there. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 150.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> page_scale = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> outer_clip = Layer::Create(); - scoped_refptr<Layer> outer_viewport = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(page_scale); - page_scale->AddChild(scroller); - scroller->AddChild(outer_clip); - outer_clip->AddChild(outer_viewport); - outer_viewport->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale; - viewport_layers.inner_viewport_container = root; - viewport_layers.outer_viewport_container = outer_clip; - viewport_layers.inner_viewport_scroll = scroller; - viewport_layers.outer_viewport_scroll = outer_viewport; - host()->RegisterViewportLayers(viewport_layers); - - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; +TEST_F(LayerTreeHostCommonStickyPositionTest, + StickyPositionBottomOuterViewportDelta) { + CreateTree(); + + GetScrollNode(scroller_.get())->scrolls_outer_viewport = true; + + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 70)); + GetPropertyTrees(sticky_pos_.get()) + ->transform_tree.AddNodeAffectedByOuterViewportBoundsDelta( + sticky_pos_->transform_tree_index()); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100); @@ -6555,574 +6201,402 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { gfx::Rect(0, 70, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 60, 100, 100); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - scroller->SetScrollable(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(100, 1000)); - outer_clip->SetBounds(gfx::Size(100, 100)); - outer_viewport->SetScrollable(gfx::Size(100, 100)); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 70)); - - ExecuteCalculateDrawProperties(root.get(), 1.f, 1.f, root.get(), - scroller.get(), outer_viewport.get()); - host()->CommitAndCreateLayerImplTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - ASSERT_EQ(outer_viewport->id(), - layer_tree_impl->OuterViewportScrollLayer()->id()); - LayerImpl* inner_scroll = layer_tree_impl->InnerViewportScrollLayer(); - LayerImpl* outer_scroll = layer_tree_impl->OuterViewportScrollLayer(); - LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); - LayerImpl* outer_clip_impl = layer_tree_impl->LayerById(outer_clip->id()); + CommitAndUpdateImplPointers(); // Initially the sticky element is moved to the bottom of the container. EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 70.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // We start to hide the toolbar, but not far enough that the sticky element // should be moved up yet. - outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f)); - ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, - outer_scroll); + GetPropertyTrees(scroller_impl_) + ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 70.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // On hiding more of the toolbar the sticky element starts to stick. - outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f)); - ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, - outer_scroll); + GetPropertyTrees(scroller_impl_) + ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + ExecuteCalculateDrawProperties(root_impl_); // On hiding more the sticky element stops moving as it has reached its // limit. EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 60.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); - outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f)); - ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, - outer_scroll); + GetPropertyTrees(scroller_impl_) + ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 60.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { + CreateTree(); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(145, 0)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_left = true; sticky_position.is_anchored_right = true; - sticky_position.left_offset = 10.f; - sticky_position.right_offset = 10.f; + sticky_position.left_offset = 10.0f; + sticky_position.right_offset = 10.0f; sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(145, 0, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(100, 0, 100, 100); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(145, 0)); - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + CommitAndUpdateImplPointers(); // Initially the sticky element is moved the leftmost side of the container. - ExecuteCalculateDrawProperties(root_impl); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(100.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(95.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Once we get past the left side of the container it moves to be aligned 10px // up from the the right of the scroller. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(25.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(30.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // When we get to the sticky element's original position we stop sticking // to the right. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(95.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(50.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(105.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(40.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // The element starts sticking to the left once we scroll far enough. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(150.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(155.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Finally it stops sticking when it hits the right side of the container. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(190.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(195.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // This test ensures that the compositor sticky position code correctly accounts // for the element having been given a position from the main thread sticky // position code. -TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { + CreateTree(); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 0, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(10, 20)); - - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + CommitAndUpdateImplPointers(); - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 20.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(5.f, 15.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Now the main thread commits the new position of the sticky element. - scroller->SetScrollOffset(gfx::ScrollOffset(15, 15)); + SetScrollOffset(scroller_.get(), gfx::ScrollOffset(15, 15)); // Shift the layer by -offset_for_position_sticky. - sticky_pos->SetPosition(gfx::PointF(10, 25) - gfx::Vector2dF(0, 5)); - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - layer_tree_impl = host()->host_impl()->active_tree(); - root_impl = layer_tree_impl->LayerById(root->id()); - scroller_impl = layer_tree_impl->LayerById(scroller->id()); - sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + SetPostTranslation(sticky_pos_.get(), + gfx::PointF(10, 25) - gfx::PointF(0, 5)); + GetPropertyTrees(scroller_.get())->transform_tree.set_needs_update(true); + + CommitAndUpdateImplPointers(); // The element should still be where it was before. We reset the delta to // (0, 0) because we have synced a scroll offset of (15, 15) from the main // thread. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // This tests the main thread updates with a composited sticky container. In // this case the position received from main is relative to the container but // the constraint rects are relative to the ancestor scroller. -TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_container = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_container); - sticky_container->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); +TEST_F(LayerTreeHostCommonStickyPositionTest, + StickyPositionCompositedContainer) { + CreateRootAndScroller(); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + scoped_refptr<Layer> sticky_container = Layer::Create(); + sticky_container->SetBounds(gfx::Size(30, 30)); + sticky_container->SetOffsetToTransformParent(gfx::Vector2dF(20, 20)); + CopyProperties(scroller_.get(), sticky_container.get()); + root_->AddChild(sticky_container); + + sticky_pos_ = CreateSticky(sticky_container.get()); + SetPostTranslation( + sticky_pos_.get(), + gfx::Vector2dF(0, 10) + sticky_container->offset_to_transform_parent()); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(20, 30, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(20, 20, 30, 30); - sticky_pos->SetStickyPositionConstraint(sticky_position); - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_container->SetPosition(gfx::PointF(20, 20)); - sticky_container->SetBounds(gfx::Size(30, 30)); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 10)); + CommitAndUpdateImplPointers(); - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); - - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 30.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 25.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Now the main thread commits the new position of the sticky element. - scroller->SetScrollOffset(gfx::ScrollOffset(0, 25)); + SetScrollOffset(scroller_.get(), gfx::ScrollOffset(0, 25)); // Shift the layer by -offset_for_position_sticky. - sticky_pos->SetPosition(gfx::PointF(0, 15) - gfx::Vector2dF(0, 5)); - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - layer_tree_impl = host()->host_impl()->active_tree(); - root_impl = layer_tree_impl->LayerById(root->id()); - scroller_impl = layer_tree_impl->LayerById(scroller->id()); - sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + SetPostTranslation(sticky_pos_.get(), + gfx::PointF(0, 15) - gfx::PointF(0, 5) + + sticky_container->offset_to_transform_parent()); + CommitAndUpdateImplPointers(); // The element should still be where it was before. We reset the delta to // (0, 0) because we have synced a scroll offset of (0, 25) from the main // thread. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And hits the bottom of the container. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 5.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // A transform on a sticky element should not affect its sticky position. -TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - gfx::Transform t; - t.Scale(2, 2); - sticky_pos->SetTransform(t); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { + CreateTree(); + + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20)); + gfx::Transform scale; + scale.Scale(2, 2); + SetTransform(sticky_pos_.get(), scale); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 0, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 20)); - - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + CommitAndUpdateImplPointers(); - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 20.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); + + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 5.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the box is positioned at the scroller // edge. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, -10.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // Tests that a transform does not affect the sticking points. The sticky // element will however move relative to the viewport due to its transform. -TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { + CreateRootAndScroller(); + scoped_refptr<Layer> sticky_container = Layer::Create(); - scoped_refptr<Layer> sticky_pos = Layer::Create(); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(sticky_container); - sticky_container->AddChild(sticky_pos); - host()->SetRootLayer(root); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - gfx::Transform t; - t.Scale(2, 2); - sticky_container->SetTransform(t); + sticky_container->SetBounds(gfx::Size(50, 50)); + CopyProperties(scroller_.get(), sticky_container.get()); + CreateTransformNode(sticky_container.get()).local.Scale(2, 2); + root_->AddChild(sticky_container); - LayerStickyPositionConstraint sticky_position; - sticky_position.is_sticky = true; + sticky_pos_ = CreateSticky(sticky_container.get()); + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20)); + auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = gfx::Rect(0, 0, 50, 50); - sticky_pos->SetStickyPositionConstraint(sticky_position); - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetScrollable(container->bounds()); - sticky_container->SetBounds(gfx::Size(50, 50)); - sticky_pos->SetBounds(gfx::Size(10, 10)); - sticky_pos->SetPosition(gfx::PointF(0, 20)); + CommitAndUpdateImplPointers(); - 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* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); - - ExecuteCalculateDrawProperties(root_impl); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 40.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the box is positioned at the scroller // edge but is also scaled by its container so it begins to move down. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); + ExecuteCalculateDrawProperties(root_impl_); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), - sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + 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->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - outer_sticky->SetElementId(LayerIdToElementIdForTesting(outer_sticky->id())); - - root->SetBounds(gfx::Size(100, 100)); - container->SetBounds(gfx::Size(100, 100)); - scroller->SetBounds(gfx::Size(100, 1000)); - scroller->SetScrollable(container->bounds()); - 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)); +TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { + CreateTree(); - LayerStickyPositionConstraint outer_sticky_pos; - outer_sticky_pos.is_sticky = true; + SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 50)); + auto& outer_sticky_pos = EnsureStickyData(sticky_pos_.get()).constraints; outer_sticky_pos.is_anchored_top = true; outer_sticky_pos.top_offset = 10.0f; 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; + scoped_refptr<Layer> inner_sticky = CreateSticky(sticky_pos_.get()); + auto& inner_sticky_pos = EnsureStickyData(inner_sticky.get()).constraints; inner_sticky_pos.is_anchored_top = true; inner_sticky_pos.top_offset = 25.0f; 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_element_shifting_containing_block = - outer_sticky->element_id(); - inner_sticky->SetStickyPositionConstraint(inner_sticky_pos); + EnsureStickyData(inner_sticky.get()).nearest_node_shifting_containing_block = + sticky_pos_->transform_tree_index(); - ExecuteCalculateDrawProperties(root.get()); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); + CommitAndUpdateImplPointers(); 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* outer_sticky_impl = sticky_pos_impl_; 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( @@ -7134,8 +6608,8 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { // 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); + 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()); @@ -7145,8 +6619,8 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { // 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); + 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()); @@ -7155,8 +6629,8 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); // Keep going, both should stick. - SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 100.f)); - ExecuteCalculateDrawProperties(root_impl); + 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()); @@ -7165,100 +6639,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { inner_sticky_impl->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, NonFlatContainerForFixedPosLayer) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> fixed_pos = Layer::Create(); - - scroller->SetIsContainerForFixedPositionLayers(true); - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(fixed_pos); - host()->SetRootLayer(root); - - LayerPositionConstraint fixed_position; - fixed_position.set_is_fixed_position(true); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - fixed_pos->SetPositionConstraint(fixed_position); - - root->SetBounds(gfx::Size(50, 50)); - container->SetBounds(gfx::Size(50, 50)); - scroller->SetBounds(gfx::Size(50, 50)); - scroller->SetScrollable(container->bounds()); - fixed_pos->SetBounds(gfx::Size(50, 50)); - - gfx::Transform rotate; - rotate.RotateAboutXAxis(20); - container->SetTransform(rotate); - - ExecuteCalculateDrawProperties(root.get()); - TransformTree& tree = - root->layer_tree_host()->property_trees()->transform_tree; - gfx::Transform transform; - tree.ComputeTranslation(fixed_pos->transform_tree_index(), - container->transform_tree_index(), &transform); - EXPECT_TRUE(transform.IsIdentity()); -} - -TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithFixedPosChild) { - // This test verifies that a fixed pos child of a scrolling layer doesn't get - // snapped to integer coordinates. - // - // + root - // + container - // + scroller - // + fixed_pos - // - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> container = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> fixed_pos = Layer::Create(); - - scroller->SetIsContainerForFixedPositionLayers(true); - - root->AddChild(container); - container->AddChild(scroller); - scroller->AddChild(fixed_pos); - host()->SetRootLayer(root); - - LayerPositionConstraint fixed_position; - fixed_position.set_is_fixed_position(true); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - fixed_pos->SetPositionConstraint(fixed_position); - - root->SetBounds(gfx::Size(50, 50)); - container->SetBounds(gfx::Size(50, 50)); - scroller->SetBounds(gfx::Size(100, 100)); - scroller->SetScrollable(container->bounds()); - scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); - fixed_pos->SetBounds(gfx::Size(10, 10)); - - 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* fixed_pos_impl = layer_tree_impl->LayerById(fixed_pos->id()); - gfx::Vector2dF scroll_delta(5.f, 9.f); - SetScrollOffsetDelta(scroller_impl, scroll_delta); - - ExecuteCalculateDrawProperties(root_impl); - - gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f); - EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation, - scroller_impl->ScreenSpaceTransform().To2dTranslation()); - - gfx::Vector2dF expected_fixed_pos_screen_space_transform_translation(10.3f, - 10.3f); - EXPECT_VECTOR2DF_EQ(expected_fixed_pos_screen_space_transform_translation, - fixed_pos_impl->ScreenSpaceTransform().To2dTranslation()); -} - class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { public: static std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> Create( @@ -7279,147 +6659,132 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { }; TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - LayerTreeSettings settings = host()->GetSettings(); - FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &task_graph_runner); - std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent = - AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> parent = - AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> child = - AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_child = - AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 4); - - AnimationScaleFactorTrackingLayerImpl* parent_raw = parent.get(); - AnimationScaleFactorTrackingLayerImpl* child_raw = child.get(); - AnimationScaleFactorTrackingLayerImpl* grand_child_raw = grand_child.get(); - AnimationScaleFactorTrackingLayerImpl* grand_parent_raw = grand_parent.get(); + LayerImpl* root = root_layer_for_testing(); + auto* grand_parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); + auto* parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); + auto* child = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); + auto* grand_child = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); + SetElementIdsForTesting(); + root->SetBounds(gfx::Size(1, 2)); grand_parent->SetBounds(gfx::Size(1, 2)); parent->SetBounds(gfx::Size(1, 2)); child->SetBounds(gfx::Size(1, 2)); grand_child->SetBounds(gfx::Size(1, 2)); - child->test_properties()->AddChild(std::move(grand_child)); - parent->test_properties()->AddChild(std::move(child)); - grand_parent->test_properties()->AddChild(std::move(parent)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(grand_parent)); + SetupRootProperties(root); + CopyProperties(root, grand_parent); + CreateTransformNode(grand_parent); + CopyProperties(grand_parent, parent); + CreateTransformNode(parent); + CopyProperties(parent, child); + CreateTransformNode(child); + CopyProperties(child, grand_child); + CreateTransformNode(grand_child); - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // No layers have animations. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); TransformOperations translation; translation.AppendTranslate(1.f, 2.f, 3.f); - scoped_refptr<AnimationTimeline> timeline; - timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - - host_impl.active_tree()->SetElementIdsForTesting(); - scoped_refptr<SingleKeyframeEffectAnimation> grand_parent_animation = SingleKeyframeEffectAnimation::Create( AnimationIdProvider::NextAnimationId()); - timeline->AttachAnimation(grand_parent_animation); - grand_parent_animation->AttachElement(grand_parent_raw->element_id()); + timeline_impl()->AttachAnimation(grand_parent_animation); + grand_parent_animation->AttachElement(grand_parent->element_id()); scoped_refptr<SingleKeyframeEffectAnimation> parent_animation = SingleKeyframeEffectAnimation::Create( AnimationIdProvider::NextAnimationId()); - timeline->AttachAnimation(parent_animation); - parent_animation->AttachElement(parent_raw->element_id()); + timeline_impl()->AttachAnimation(parent_animation); + parent_animation->AttachElement(parent->element_id()); scoped_refptr<SingleKeyframeEffectAnimation> child_animation = SingleKeyframeEffectAnimation::Create( AnimationIdProvider::NextAnimationId()); - timeline->AttachAnimation(child_animation); - child_animation->AttachElement(child_raw->element_id()); + timeline_impl()->AttachAnimation(child_animation); + child_animation->AttachElement(child->element_id()); scoped_refptr<SingleKeyframeEffectAnimation> grand_child_animation = SingleKeyframeEffectAnimation::Create( AnimationIdProvider::NextAnimationId()); - timeline->AttachAnimation(grand_child_animation); - grand_child_animation->AttachElement(grand_child_raw->element_id()); + timeline_impl()->AttachAnimation(grand_child_animation); + grand_child_animation->AttachElement(grand_child->element_id()); AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), translation); // No layers have scale-affecting animations. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); TransformOperations scale; scale.AppendScale(5.f, 4.f, 3.f); AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), scale); - child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // Only |child| has a scale-affecting animation. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(5.f, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(5.f, GetMaximumAnimationScale(child)); + EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(1.f, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(1.f, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(1.f, GetStartingAnimationScale(child)); + EXPECT_EQ(1.f, GetStartingAnimationScale(grand_child)); AddAnimatedTransformToAnimation(grand_parent_animation.get(), 1.0, TransformOperations(), scale); - grand_parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // |grand_parent| and |child| have scale-affecting animations. - EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(5.f, GetMaximumAnimationScale(parent_raw)); + EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(5.f, GetMaximumAnimationScale(parent)); // We don't support combining animated scales from two nodes; 0.f means // that the maximum scale could not be computed. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(1.f, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(1.f, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // |grand_parent|, |parent|, and |child| have scale-affecting animations. - EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); grand_parent_animation->AbortKeyframeModelsWithProperty( TargetProperty::TRANSFORM, false); @@ -7433,96 +6798,91 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), perspective); - child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // |child| has a scale-affecting animation but computing the maximum of this // animation is not supported. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); child_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM, false); gfx::Transform scale_matrix; scale_matrix.Scale(1.f, 2.f); - grand_parent_raw->test_properties()->transform = scale_matrix; - parent_raw->test_properties()->transform = scale_matrix; - grand_parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetTransform(grand_parent, scale_matrix); + SetTransform(parent, scale_matrix); AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // |grand_parent| and |parent| each have scale 2.f. |parent| has a scale // animation with maximum scale 5.f. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(10.f, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(10.f, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(10.f, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(10.f, GetMaximumAnimationScale(parent)); + EXPECT_EQ(10.f, GetMaximumAnimationScale(child)); + EXPECT_EQ(10.f, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(2.f, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(2.f, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(2.f, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(2.f, GetStartingAnimationScale(parent)); + EXPECT_EQ(2.f, GetStartingAnimationScale(child)); + EXPECT_EQ(2.f, GetStartingAnimationScale(grand_child)); gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.f); - child_raw->test_properties()->transform = perspective_matrix; - grand_parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + SetTransform(child, perspective_matrix); + ExecuteCalculateDrawProperties(root); // |child| has a transform that's neither a translation nor a scale. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(10.f, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(10.f, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(2.f, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(2.f, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); - parent_raw->test_properties()->transform = perspective_matrix; - grand_parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(grand_parent_raw); + SetTransform(parent, perspective_matrix); + ExecuteCalculateDrawProperties(root); // |parent| and |child| have transforms that are neither translations nor // scales. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); - parent_raw->test_properties()->transform = gfx::Transform(); - child_raw->test_properties()->transform = gfx::Transform(); - grand_parent_raw->test_properties()->transform = perspective_matrix; - grand_parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetTransform(parent, gfx::Transform()); + SetTransform(child, gfx::Transform()); + SetTransform(grand_parent, perspective_matrix); - ExecuteCalculateDrawProperties(grand_parent_raw); + ExecuteCalculateDrawProperties(root); // |grand_parent| has a transform that's neither a translation nor a scale. - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child_raw)); - EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child_raw)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child)); + EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); } static void GatherDrawnLayers(LayerTreeImpl* tree_impl, @@ -7540,418 +6900,349 @@ static void GatherDrawnLayers(LayerTreeImpl* tree_impl, } } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> grand_parent = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> parent = - LayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.active_tree(), 5); - std::unique_ptr<LayerImpl> grand_child1 = - LayerImpl::Create(host_impl.active_tree(), 7); - std::unique_ptr<LayerImpl> grand_child2 = - LayerImpl::Create(host_impl.active_tree(), 9); - - LayerImpl* grand_parent_raw = grand_parent.get(); - LayerImpl* parent_raw = parent.get(); - LayerImpl* child_raw = child.get(); - LayerImpl* grand_child1_raw = grand_child1.get(); - LayerImpl* grand_child2_raw = grand_child2.get(); +// Needs layer tree mode: mask layer. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { + auto root = Layer::Create(); + auto grand_parent = Layer::Create(); + auto parent = Layer::Create(); + auto child = Layer::Create(); + auto grand_child1 = Layer::Create(); + auto grand_child2 = Layer::Create(); + root->SetBounds(gfx::Size(1, 2)); grand_parent->SetBounds(gfx::Size(1, 2)); parent->SetBounds(gfx::Size(1, 2)); child->SetBounds(gfx::Size(1, 2)); grand_child1->SetBounds(gfx::Size(1, 2)); grand_child2->SetBounds(gfx::Size(1, 2)); - child->test_properties()->AddChild(std::move(grand_child1)); - child->test_properties()->AddChild(std::move(grand_child2)); - parent->test_properties()->AddChild(std::move(child)); - grand_parent->test_properties()->AddChild(std::move(parent)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(grand_parent)); + child->AddChild(grand_child1); + child->AddChild(grand_child2); + parent->AddChild(child); + grand_parent->AddChild(parent); + root->AddChild(grand_parent); + host()->SetRootLayer(root); // Start with nothing being drawn. - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); std::set<LayerImpl*> expected; std::set<LayerImpl*> actual; - GatherDrawnLayers(host_impl.active_tree(), &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, // then this layer should not appear in RSLL. - grand_child1_raw->test_properties()->force_render_surface = true; - grand_child1_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; + grand_child1->SetForceRenderSurfaceForTesting(true); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &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 // RSLL. - grand_child1_raw->SetDrawsContent(true); + grand_child1->SetIsDrawable(true); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(grand_child1_raw); + expected.insert(ImplOf(grand_child1)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &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 // content. - grand_child1_raw->SetDrawsContent(false); - grand_child1_raw->test_properties()->force_render_surface = false; - grand_child1_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - child_raw->test_properties()->force_render_surface = true; - grand_child2_raw->SetDrawsContent(true); + grand_child1->SetIsDrawable(false); + grand_child1->SetForceRenderSurfaceForTesting(false); + child->SetForceRenderSurfaceForTesting(true); + grand_child2->SetIsDrawable(true); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(grand_child2_raw); + expected.insert(ImplOf(grand_child2)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &actual); + GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); // Add a mask layer to child. - child_raw->test_properties()->SetMaskLayer( - LayerImpl::Create(host_impl.active_tree(), 6)); - child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; + FakeContentLayerClient client; + auto mask = PictureLayer::Create(&client); + mask->SetBounds(child->bounds()); + child->SetMaskLayer(mask); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(grand_child2_raw); - expected.insert(child_raw->test_properties()->mask_layer); - - expected.clear(); - expected.insert(grand_child2_raw); - expected.insert(child_raw->test_properties()->mask_layer); + expected.insert(ImplOf(grand_child2)); + expected.insert(ImplOf(mask)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &actual); + GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(grand_child2_raw); - expected.insert(child_raw->test_properties()->mask_layer); + expected.insert(ImplOf(grand_child2)); + expected.insert(ImplOf(mask)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &actual); + GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); - child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; - // With nothing drawing, we should have no layers. - grand_child2_raw->SetDrawsContent(false); + grand_child2->SetIsDrawable(false); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(child_raw->test_properties() - ->mask_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &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 - // list. - child_raw->SetDrawsContent(true); + // When the child is drawable, both the child and the mask should be in the + // render surface list. + child->SetIsDrawable(true); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(child_raw); - expected.insert(child_raw->test_properties()->mask_layer); + expected.insert(ImplOf(child)); + expected.insert(ImplOf(mask)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &actual); + GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); - child_raw->test_properties()->SetMaskLayer(nullptr); - child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true; + child->SetMaskLayer(nullptr); // Now everyone's a member! - grand_parent_raw->SetDrawsContent(true); - parent_raw->SetDrawsContent(true); - child_raw->SetDrawsContent(true); - grand_child1_raw->SetDrawsContent(true); - grand_child2_raw->SetDrawsContent(true); + grand_parent->SetIsDrawable(true); + parent->SetIsDrawable(true); + child->SetIsDrawable(true); + grand_child1->SetIsDrawable(true); + grand_child2->SetIsDrawable(true); - ExecuteCalculateDrawProperties(grand_parent_raw); + CommitAndActivate(); - EXPECT_TRUE(grand_parent_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(parent_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(child_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child1_raw->contributes_to_drawn_render_surface()); - EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(parent)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); - expected.insert(grand_parent_raw); - expected.insert(parent_raw); - expected.insert(child_raw); - expected.insert(grand_child1_raw); - expected.insert(grand_child2_raw); + expected.insert(ImplOf(grand_parent)); + expected.insert(ImplOf(parent)); + expected.insert(ImplOf(child)); + expected.insert(ImplOf(grand_child1)); + expected.insert(ImplOf(grand_child2)); actual.clear(); - GatherDrawnLayers(host_impl.active_tree(), &actual); + GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); } -TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - LayerTreeSettings settings = host()->GetSettings(); - FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - LayerImpl* root_layer = root.get(); - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* child1_layer = child1.get(); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl.active_tree(), 3); - LayerImpl* child2_layer = child2.get(); +// Needs layer tree mode: mask layer. +TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { + auto root = Layer::Create(); + auto page_scale = Layer::Create(); + auto child1 = Layer::Create(); + auto child2 = Layer::Create(); gfx::Transform scale_transform_child1, scale_transform_child2; scale_transform_child1.Scale(2, 3); scale_transform_child2.Scale(4, 5); root->SetBounds(gfx::Size(1, 1)); - root->SetDrawsContent(true); - child1_layer->test_properties()->transform = scale_transform_child1; - child1_layer->SetBounds(gfx::Size(1, 1)); - child1_layer->SetDrawsContent(true); + root->SetIsDrawable(true); + child1->SetTransform(scale_transform_child1); + child1->SetBounds(gfx::Size(1, 1)); + child1->SetIsDrawable(true); - child1_layer->test_properties()->SetMaskLayer( - LayerImpl::Create(host_impl.active_tree(), 4)); + FakeContentLayerClient client; + auto mask = PictureLayer::Create(&client); + mask->SetBounds(child1->bounds()); + child1->SetMaskLayer(mask); - 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(); + page_scale->AddChild(child1); + page_scale->AddChild(child2); + root->AddChild(page_scale); + host()->SetRootLayer(root); + host()->SetElementIdsForTesting(); - ExecuteCalculateDrawProperties(root_layer); + CommitAndActivate(); TransformOperations scale; scale.AppendScale(5.f, 8.f, 3.f); - scoped_refptr<AnimationTimeline> timeline = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - - child2_layer->test_properties()->transform = scale_transform_child2; - child2_layer->SetBounds(gfx::Size(1, 1)); - child2_layer->SetDrawsContent(true); - AddAnimatedTransformToElementWithAnimation( - child2_layer->element_id(), timeline, 1.0, TransformOperations(), scale); + child2->SetTransform(scale_transform_child2); + child2->SetBounds(gfx::Size(1, 1)); + child2->SetIsDrawable(true); + AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(), + 1.0, TransformOperations(), scale); - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_layer); + CommitAndActivate(); - EXPECT_FLOAT_EQ(1.f, root_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(3.f, child1_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ( - 3.f, - child1_layer->test_properties()->mask_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(5.f, child2_layer->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root_layer)); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1_layer)); - EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2_layer)); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2))); // Changing page-scale would affect ideal_contents_scale and // maximum_animation_contents_scale. - float page_scale_factor = 3.f; float device_scale_factor = 1.0f; - RenderSurfaceList render_surface_list; - gfx::Size device_viewport_size = - gfx::Size(root_layer->bounds().width() * device_scale_factor, - root_layer->bounds().height() * device_scale_factor); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, &render_surface_list); - - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_layer = root_layer; - inputs.page_scale_transform_node = inputs.property_trees->transform_tree.Node( - inputs.page_scale_layer->transform_tree_index()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + float page_scale_factor = 3.f; + CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); - EXPECT_FLOAT_EQ(3.f, root_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(9.f, child1_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ( - 9.f, - child1_layer->test_properties()->mask_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(15.f, child2_layer->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(9.f, ImplOf(mask)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root_layer)); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1_layer)); - EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(child2_layer)); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(ImplOf(child2))); // Changing device-scale would affect ideal_contents_scale and // maximum_animation_contents_scale. device_scale_factor = 4.0f; - inputs.device_scale_factor = device_scale_factor; - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); - EXPECT_FLOAT_EQ(12.f, root_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(36.f, child1_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ( - 36.f, - child1_layer->test_properties()->mask_layer->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(60.f, child2_layer->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(36.f, ImplOf(mask)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root_layer)); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1_layer)); - EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(child2_layer)); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(ImplOf(child2))); } TEST_F(LayerTreeHostCommonTest, AnimationScales) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - LayerTreeSettings settings = host()->GetSettings(); - FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - LayerImpl* root_layer = root.get(); - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* child1_layer = child1.get(); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl.active_tree(), 3); - LayerImpl* child2_layer = child2.get(); - - root->test_properties()->AddChild(std::move(child1)); - child1_layer->test_properties()->AddChild(std::move(child2)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); - - host_impl.active_tree()->SetElementIdsForTesting(); + LayerImpl* root = root_layer_for_testing(); + auto* child1 = AddChildToRoot<LayerImpl>(); + auto* child2 = AddChildToRoot<LayerImpl>(); + SetElementIdsForTesting(); gfx::Transform scale_transform_child1, scale_transform_child2; scale_transform_child1.Scale(2, 3); scale_transform_child2.Scale(4, 5); - root_layer->SetBounds(gfx::Size(1, 1)); - child1_layer->test_properties()->transform = scale_transform_child1; - child1_layer->SetBounds(gfx::Size(1, 1)); - child2_layer->test_properties()->transform = scale_transform_child2; - child2_layer->SetBounds(gfx::Size(1, 1)); + root->SetBounds(gfx::Size(1, 1)); + child1->SetBounds(gfx::Size(1, 1)); + child2->SetBounds(gfx::Size(1, 1)); + + SetupRootProperties(root); + CopyProperties(root, child1); + CreateTransformNode(child1).local = scale_transform_child1; + CopyProperties(child1, child2); + CreateTransformNode(child2).local = scale_transform_child2; TransformOperations scale; scale.AppendScale(5.f, 8.f, 3.f); - scoped_refptr<AnimationTimeline> timeline = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - AddAnimatedTransformToElementWithAnimation( - child2_layer->element_id(), timeline, 1.0, TransformOperations(), scale); - - // Correctly computes animation scale when rebuilding property trees. - root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_layer); + child2->element_id(), timeline_impl(), 1.0, TransformOperations(), scale); + ExecuteCalculateDrawProperties(root); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root_layer)); - EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1_layer)); - EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(child2_layer)); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root)); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1)); + EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(child2)); - EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(root_layer)); - EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(child1_layer)); - EXPECT_FLOAT_EQ(3.f, GetStartingAnimationScale(child2_layer)); + EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(root)); + EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(child1)); + EXPECT_FLOAT_EQ(3.f, GetStartingAnimationScale(child2)); // Correctly updates animation scale when layer property changes. - child1_layer->test_properties()->transform = gfx::Transform(); - 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)); - EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2_layer)); + SetTransform(child1, gfx::Transform()); + root->layer_tree_impl()->SetTransformMutated(child1->element_id(), + gfx::Transform()); + ExecuteCalculateDrawProperties(root); + EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2)); + EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2)); // Do not update animation scale if already updated. - host_impl.active_tree()->property_trees()->SetAnimationScalesForTesting( - child2_layer->transform_tree_index(), 100.f, 100.f); - EXPECT_FLOAT_EQ(100.f, GetMaximumAnimationScale(child2_layer)); - EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2_layer)); + host_impl()->active_tree()->property_trees()->SetAnimationScalesForTesting( + child2->transform_tree_index(), 100.f, 100.f); + EXPECT_FLOAT_EQ(100.f, GetMaximumAnimationScale(child2)); + EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2)); } TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip = AddChild<LayerImpl>(root); - LayerImpl* content = AddChild<LayerImpl>(clip); + LayerImpl* clip = AddLayer<LayerImpl>(); + LayerImpl* content = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(768 / 2, 3000)); root->SetDrawsContent(true); @@ -7959,12 +7250,17 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { clip->SetMasksToBounds(true); content->SetBounds(gfx::Size(768 / 2, 10000)); content->SetDrawsContent(true); - content->test_properties()->force_render_surface = true; - gfx::Size device_viewport_size(768, 582); + SetupRootProperties(root); + CopyProperties(root, clip); + CreateClipNode(clip); + CopyProperties(clip, content); + CreateEffectNode(content).render_surface_reason = RenderSurfaceReason::kTest; + + gfx::Rect device_viewport_rect(768, 582); RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, gfx::Transform(), &render_surface_list_impl); + root, device_viewport_rect, gfx::Transform(), &render_surface_list_impl); inputs.device_scale_factor = 2.f; inputs.page_scale_factor = 1.f; inputs.page_scale_layer = nullptr; @@ -7980,10 +7276,6 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { } TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - // Set two layers: the root layer clips it's child, // the child draws its content. @@ -7993,13 +7285,11 @@ TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { gfx::Size sublayer_size = gfx::Size(300, 1000); // Device viewport accomidated the root and the browser controls. - gfx::Size device_viewport_size = gfx::Size(300, 600); + gfx::Rect device_viewport_rect = gfx::Rect(300, 600); - host_impl.active_tree()->SetDeviceViewportSize(device_viewport_size); - host_impl.active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl.active_tree(), 1)); + host_impl()->active_tree()->SetDeviceViewportRect(device_viewport_rect); - LayerImpl* root = host_impl.active_tree()->root_layer_for_testing(); + LayerImpl* root = root_layer_for_testing(); root->SetBounds(root_size); root->SetMasksToBounds(true); @@ -8007,115 +7297,45 @@ TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { // |SetViewportBoundsDelta| will be on a viewport layer. LayerTreeImpl::ViewportLayerIds viewport_ids; viewport_ids.inner_viewport_scroll = root->id(); - host_impl.active_tree()->SetViewportLayersFromIds(viewport_ids); + host_impl()->active_tree()->SetViewportLayersFromIds(viewport_ids); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl.active_tree(), 2)); - - LayerImpl* sublayer = root->test_properties()->children[0]; + LayerImpl* sublayer = AddLayer<LayerImpl>(); sublayer->SetBounds(sublayer_size); sublayer->SetDrawsContent(true); - host_impl.active_tree()->BuildPropertyTreesForTesting(); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, &render_surface_list); + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, sublayer); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); root->SetViewportBoundsDelta(gfx::Vector2dF(0.0, 50.0)); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + ExecuteCalculateDrawProperties(root); gfx::Rect affected_by_delta(0, 0, root_size.width(), root_size.height() + 50); EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, NodesAffectedByViewportBoundsDeltaGetUpdated) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - scoped_refptr<Layer> outer_viewport_container_layer = Layer::Create(); - scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); - - root->AddChild(inner_viewport_container_layer); - inner_viewport_container_layer->AddChild(page_scale_layer); - page_scale_layer->AddChild(inner_viewport_scroll_layer); - inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer); - outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer); - - inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); - outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); - outer_viewport_scroll_layer->SetIsResizedByBrowserControls(true); - - host()->SetRootLayer(root); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = inner_viewport_container_layer; - viewport_layers.outer_viewport_container = outer_viewport_container_layer; - viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer; - viewport_layers.outer_viewport_scroll = outer_viewport_scroll_layer; - host()->RegisterViewportLayers(viewport_layers); - - scoped_refptr<Layer> fixed_to_inner = Layer::Create(); - scoped_refptr<Layer> fixed_to_outer = Layer::Create(); - - inner_viewport_scroll_layer->AddChild(fixed_to_inner); - outer_viewport_scroll_layer->AddChild(fixed_to_outer); - - LayerPositionConstraint fixed_to_right; - fixed_to_right.set_is_fixed_position(true); - fixed_to_right.set_is_fixed_to_right_edge(true); - - fixed_to_inner->SetPositionConstraint(fixed_to_right); - fixed_to_outer->SetPositionConstraint(fixed_to_right); - - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - - TransformTree& transform_tree = host()->property_trees()->transform_tree; - EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta()); - - LayerPositionConstraint fixed_to_left; - fixed_to_left.set_is_fixed_position(true); - fixed_to_inner->SetPositionConstraint(fixed_to_left); - - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta()); - - fixed_to_outer->SetPositionConstraint(fixed_to_left); - - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_FALSE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta()); -} - TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { host_impl()->CreatePendingTree(); - std::unique_ptr<LayerImpl> pending_root = - LayerImpl::Create(host_impl()->pending_tree(), 1); - LayerImpl* root = pending_root.get(); - host_impl()->pending_tree()->SetRootLayerForTesting(std::move(pending_root)); - std::unique_ptr<LayerImpl> animated_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 2); - LayerImpl* animated = animated_ptr.get(); - root->test_properties()->AddChild(std::move(animated_ptr)); + LayerImpl* root = EnsureRootLayerInPendingTree(); + LayerImpl* animated = AddLayerInPendingTree<LayerImpl>(); animated->SetDrawsContent(true); host_impl()->pending_tree()->SetElementIdsForTesting(); root->SetBounds(gfx::Size(100, 100)); - root->SetMasksToBounds(true); - root->test_properties()->force_render_surface = true; - animated->test_properties()->opacity = 0.f; animated->SetBounds(gfx::Size(20, 20)); + SetupRootProperties(root); + CopyProperties(root, animated); + CreateEffectNode(animated).opacity = 0.f; + AddOpacityTransitionToElementWithAnimation( animated->element_id(), timeline_impl(), 10.0, 0.f, 1.f, false); - animated->test_properties()->opacity_can_animate = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + ExecuteCalculateDrawProperties(root); EXPECT_FALSE(animated->visible_layer_rect().IsEmpty()); } @@ -8123,29 +7343,11 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayerWithSingularTransform) { host_impl()->CreatePendingTree(); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 1); - LayerImpl* root = root_ptr.get(); - host_impl()->pending_tree()->SetRootLayerForTesting(std::move(root_ptr)); - std::unique_ptr<LayerImpl> clip_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 2); - LayerImpl* clip = clip_ptr.get(); - root->test_properties()->AddChild(std::move(clip_ptr)); - std::unique_ptr<LayerImpl> animated_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 3); - LayerImpl* animated = animated_ptr.get(); - clip->test_properties()->AddChild(std::move(animated_ptr)); - std::unique_ptr<LayerImpl> surface_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 4); - LayerImpl* surface = surface_ptr.get(); - animated->test_properties()->AddChild(std::move(surface_ptr)); - std::unique_ptr<LayerImpl> descendant_of_keyframe_model_ptr = - LayerImpl::Create(host_impl()->pending_tree(), 5); - LayerImpl* descendant_of_keyframe_model = - descendant_of_keyframe_model_ptr.get(); - surface->test_properties()->AddChild( - std::move(descendant_of_keyframe_model_ptr)); - + LayerImpl* root = EnsureRootLayerInPendingTree(); + LayerImpl* clip = AddLayerInPendingTree<LayerImpl>(); + LayerImpl* animated = AddLayerInPendingTree<LayerImpl>(); + LayerImpl* surface = AddLayerInPendingTree<LayerImpl>(); + LayerImpl* descendant_of_keyframe_model = AddLayerInPendingTree<LayerImpl>(); host_impl()->pending_tree()->SetElementIdsForTesting(); root->SetDrawsContent(true); @@ -8159,12 +7361,20 @@ TEST_F(LayerTreeHostCommonTest, root->SetBounds(gfx::Size(100, 100)); clip->SetBounds(gfx::Size(10, 10)); clip->SetMasksToBounds(true); - animated->test_properties()->transform = uninvertible_matrix; animated->SetBounds(gfx::Size(120, 120)); surface->SetBounds(gfx::Size(100, 100)); - surface->test_properties()->force_render_surface = true; descendant_of_keyframe_model->SetBounds(gfx::Size(200, 200)); + SetupRootProperties(root); + CopyProperties(root, clip); + CreateClipNode(clip); + CopyProperties(clip, animated); + CreateTransformNode(animated).local = uninvertible_matrix; + CopyProperties(animated, surface); + CreateTransformNode(surface); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(surface, descendant_of_keyframe_model); + TransformOperations start_transform_operations; start_transform_operations.AppendMatrix(uninvertible_matrix); TransformOperations end_transform_operations; @@ -8224,26 +7434,31 @@ TEST_F(LayerTreeHostCommonTest, // Verify that having animated opacity but current opacity 1 still creates // a render surface. -TEST_F(LayerTreeHostCommonTest, AnimatedOpacityCreatesRenderSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grandchild = AddChild<LayerImpl>(child); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + AnimatedOpacityCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); root->SetBounds(gfx::Size(50, 50)); child->SetBounds(gfx::Size(50, 50)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); grandchild->SetBounds(gfx::Size(50, 50)); - grandchild->SetDrawsContent(true); + grandchild->SetIsDrawable(true); - SetElementIdsForTesting(); - AddOpacityTransitionToElementWithAnimation( - child->element_id(), timeline_impl(), 10.0, 1.f, 0.2f, false); - ExecuteCalculateDrawProperties(root); + host()->SetElementIdsForTesting(); + AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(), + 10.0, 1.f, 0.2f, false); + CommitAndActivate(); - EXPECT_EQ(1.f, child->Opacity()); - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); + EXPECT_EQ(1.f, ImplOf(child)->Opacity()); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); } static bool FilterIsAnimating(LayerImpl* layer) { @@ -8254,30 +7469,35 @@ static bool FilterIsAnimating(LayerImpl* layer) { // Verify that having an animated filter (but no current filter, as these // are mutually exclusive) correctly creates a render surface. -TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grandchild = AddChild<LayerImpl>(child); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + AnimatedFilterCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); root->SetBounds(gfx::Size(50, 50)); child->SetBounds(gfx::Size(50, 50)); grandchild->SetBounds(gfx::Size(50, 50)); - SetElementIdsForTesting(); - AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline_impl(), - 10.0, 0.1f, 0.2f); - ExecuteCalculateDrawProperties(root); + host()->SetElementIdsForTesting(); + AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0, + 0.1f, 0.2f); + CommitAndActivate(); - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - EXPECT_FALSE(FilterIsAnimating(root)); - EXPECT_TRUE(FilterIsAnimating(child)); - EXPECT_FALSE(FilterIsAnimating(grandchild)); + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_TRUE(FilterIsAnimating(ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); } bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { @@ -8288,16 +7508,21 @@ bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { // Verify that having a filter animation with a delayed start time creates a // render surface. -TEST_F(LayerTreeHostCommonTest, DelayedFilterAnimationCreatesRenderSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grandchild = AddChild<LayerImpl>(child); +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + DelayedFilterAnimationCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); root->SetBounds(gfx::Size(50, 50)); child->SetBounds(gfx::Size(50, 50)); grandchild->SetBounds(gfx::Size(50, 50)); - SetElementIdsForTesting(); + host()->SetElementIdsForTesting(); std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); @@ -8314,144 +7539,29 @@ TEST_F(LayerTreeHostCommonTest, DelayedFilterAnimationCreatesRenderSurface) { keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); - AddKeyframeModelToElementWithAnimation(child->element_id(), timeline_impl(), + AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root); - - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); - - EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty()); - - EXPECT_FALSE(FilterIsAnimating(root)); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*root)); - EXPECT_FALSE(FilterIsAnimating(child)); - EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*child)); - EXPECT_FALSE(FilterIsAnimating(grandchild)); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*grandchild)); -} - -// Ensures that the property tree code accounts for offsets between fixed -// position layers and their respective containers. -TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grandchild = AddChild<LayerImpl>(child); - - root->SetBounds(gfx::Size(50, 50)); - root->SetMasksToBounds(true); - root->test_properties()->is_container_for_fixed_position_layers = true; - child->test_properties()->position = gfx::PointF(1000, 1000); - child->SetBounds(gfx::Size(50, 50)); - grandchild->test_properties()->position = gfx::PointF(-1000, -1000); - grandchild->SetBounds(gfx::Size(50, 50)); - grandchild->SetDrawsContent(true); - - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - grandchild->test_properties()->position_constraint = constraint; - - ExecuteCalculateDrawProperties(root); - - EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grandchild->visible_layer_rect()); -} - -// Ensures that the property tree code accounts for offsets between fixed -// position containers and their transform tree parents, when a fixed position -// layer's container is its layer tree parent, but this parent doesn't have its -// own transform tree node. -TEST_F(LayerTreeHostCommonTest, - PropertyTreesAccountForFixedParentOffsetWhenContainerIsParent) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grandchild = AddChild<LayerImpl>(child); - - root->SetBounds(gfx::Size(50, 50)); - root->SetMasksToBounds(true); - root->test_properties()->is_container_for_fixed_position_layers = true; - child->test_properties()->position = gfx::PointF(1000, 1000); - child->SetBounds(gfx::Size(50, 50)); - child->test_properties()->is_container_for_fixed_position_layers = true; - grandchild->test_properties()->position = gfx::PointF(-1000, -1000); - grandchild->SetBounds(gfx::Size(50, 50)); - grandchild->SetDrawsContent(true); - - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - grandchild->test_properties()->position_constraint = constraint; - - ExecuteCalculateDrawProperties(root); - - EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grandchild->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* frame_clip = AddChild<LayerImpl>(root); - LayerImpl* fixed = AddChild<LayerImpl>(frame_clip); - gfx::Transform translate_z; - translate_z.Translate3d(0, 0, 10); - - root->SetBounds(gfx::Size(800, 800)); - root->test_properties()->is_container_for_fixed_position_layers = true; - - frame_clip->test_properties()->position = gfx::PointF(500, 100); - frame_clip->SetBounds(gfx::Size(100, 100)); - frame_clip->SetMasksToBounds(true); - - fixed->SetBounds(gfx::Size(1000, 1000)); - fixed->SetDrawsContent(true); - - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - fixed->test_properties()->position_constraint = constraint; - - ExecuteCalculateDrawProperties(root); - - gfx::Rect expected(0, 0, 100, 100); - EXPECT_EQ(expected, fixed->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* frame_clip = AddChild<LayerImpl>(root); - LayerImpl* scroller = AddChild<LayerImpl>(frame_clip); - LayerImpl* fixed = AddChild<LayerImpl>(scroller); - - root->SetBounds(gfx::Size(800, 800)); - root->SetDrawsContent(true); - root->test_properties()->is_container_for_fixed_position_layers = true; - frame_clip->test_properties()->position = gfx::PointF(500, 100); - frame_clip->SetBounds(gfx::Size(100, 100)); - frame_clip->SetMasksToBounds(true); - frame_clip->SetDrawsContent(true); - scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); - scroller->SetScrollable(frame_clip->bounds()); - scroller->SetDrawsContent(true); - fixed->test_properties()->position = gfx::PointF(100, 100); - fixed->SetBounds(gfx::Size(50, 50)); - fixed->SetMasksToBounds(true); - fixed->SetDrawsContent(true); - fixed->test_properties()->force_render_surface = true; + CommitAndActivate(); - BuildPropertyTreesForTesting(); - scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100)); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - LayerPositionConstraint constraint; - constraint.set_is_fixed_position(true); - fixed->test_properties()->position_constraint = constraint; + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - ExecuteCalculateDrawProperties(root); - - gfx::Rect expected(0, 0, 50, 50); - EXPECT_EQ(expected, fixed->visible_layer_rect()); + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(child))); + EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild))); } -TEST_F(LayerTreeHostCommonTest, ChangingAxisAlignmentTriggersRebuild) { +// Needs layer tree mode: needs_rebuild flag. Not using impl-side +// PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + ChangingAxisAlignmentTriggersRebuild) { gfx::Transform translate; gfx::Transform rotate; @@ -8460,11 +7570,10 @@ TEST_F(LayerTreeHostCommonTest, ChangingAxisAlignmentTriggersRebuild) { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(800, 800)); - root->SetIsContainerForFixedPositionLayers(true); host()->SetRootLayer(root); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); EXPECT_FALSE(host()->property_trees()->needs_rebuild); root->SetTransform(translate); @@ -8476,61 +7585,66 @@ TEST_F(LayerTreeHostCommonTest, ChangingAxisAlignmentTriggersRebuild) { TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); + LayerImpl* child = AddLayer<LayerImpl>(); gfx::Transform scale_matrix; scale_matrix.Scale(2.f, 2.f); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - child->test_properties()->transform = scale_matrix; child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child).local = scale_matrix; + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); - child->test_properties()->transform_origin = gfx::Point3F(10.f, 10.f, 10.f); + SetTransformOrigin(child, gfx::Point3F(10.f, 10.f, 10.f)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* scroll_parent = AddChild<LayerImpl>(root); - LayerImpl* scroll_child = AddChild<LayerImpl>(scroll_parent); - - gfx::Transform scale; - scale.Scale(2.f, 2.f); + LayerImpl* scroll_parent = AddLayer<LayerImpl>(); + LayerImpl* scroll_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); - scroll_child->test_properties()->transform = scale; - scroll_child->SetBounds(gfx::Size(40, 40)); - scroll_child->SetDrawsContent(true); + scroll_parent->SetBounds(gfx::Size(30, 30)); scroll_parent->SetScrollable(gfx::Size(50, 50)); scroll_parent->SetElementId( LayerIdToElementIdForTesting(scroll_parent->id())); scroll_parent->SetDrawsContent(true); - scroll_child->test_properties()->scroll_parent = scroll_parent; + scroll_child->SetBounds(gfx::Size(40, 40)); + scroll_child->SetDrawsContent(true); + + SetupRootProperties(root); + CopyProperties(root, scroll_parent); + CreateTransformNode(scroll_parent); + CreateScrollNode(scroll_parent); + CopyProperties(scroll_parent, scroll_child); + CreateTransformNode(scroll_child).local.Scale(2.f, 2.f); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect()); - scroll_child->test_properties()->position = gfx::PointF(0, -10.f); - scroll_parent->SetCurrentScrollOffset(gfx::ScrollOffset(0.f, 10.f)); + SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f)); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetPostTranslation(scroll_child, gfx::Vector2dF(0, -10.f)); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, HasCopyRequestsInTargetSubtree) { +// Needs layer tree mode: copy request. Not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2 = Layer::Create(); @@ -8543,11 +7657,12 @@ TEST_F(LayerTreeHostCommonTest, HasCopyRequestsInTargetSubtree) { grandchild->AddChild(greatgrandchild); host()->SetRootLayer(root); + root->SetBounds(gfx::Size(1, 1)); child1->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting()); greatgrandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); child2->SetOpacity(0.f); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get())); EXPECT_TRUE(LayerSubtreeHasCopyRequest(child1.get())); @@ -8556,7 +7671,9 @@ TEST_F(LayerTreeHostCommonTest, HasCopyRequestsInTargetSubtree) { EXPECT_TRUE(LayerSubtreeHasCopyRequest(greatgrandchild.get())); } -TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { +// Needs layer tree mode: hide_layer_and_subtree, etc. +// Not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { FakeContentLayerClient client; scoped_refptr<Layer> root = Layer::Create(); @@ -8580,9 +7697,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { host()->SetElementIdsForTesting(); // Check the non-skipped case. - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - const LayerList* update_list = GetUpdateLayerList(); - EXPECT_TRUE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Now we will reset the visible rect from property trees for the grandchild, // and we will configure |child| in several ways that should force the subtree @@ -8592,15 +7708,13 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { singular.matrix().set(0, 0, 0); child->SetTransform(singular); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_FALSE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetTransform(gfx::Transform()); child->SetHideLayerAndSubtree(true); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_FALSE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetHideLayerAndSubtree(false); gfx::Transform zero_z_scale; @@ -8617,26 +7731,23 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_TRUE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); RemoveKeyframeModelFromElementWithExistingKeyframeEffect( child->element_id(), timeline(), keyframe_model_id); child->SetTransform(gfx::Transform()); child->SetOpacity(0.f); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_FALSE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); // Now, even though child has zero opacity, we will configure |grandchild| and // |greatgrandchild| in several ways that should force the subtree to be // processed anyhow. grandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_TRUE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Add an opacity animation with a start delay. keyframe_model_id = 1; @@ -8647,52 +7758,43 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithExistingKeyframeEffect( child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - update_list = GetUpdateLayerList(); - EXPECT_TRUE(VerifyLayerInList(grandchild, update_list)); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); } -TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<LayerImpl> grandchild = - LayerImpl::Create(host_impl.active_tree(), 3); - - std::unique_ptr<FakePictureLayerImpl> greatgrandchild( - FakePictureLayerImpl::Create(host_impl.active_tree(), 4)); +// Needs layer tree mode: hide_layer_and_subtree, etc. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayerImpl) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child = Layer::Create(); + parent->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + FakeContentLayerClient client; + auto greatgrandchild = PictureLayer::Create(&client); + grandchild->AddChild(greatgrandchild); root->SetBounds(gfx::Size(100, 100)); + parent->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); grandchild->SetBounds(gfx::Size(10, 10)); - grandchild->SetDrawsContent(true); - greatgrandchild->SetDrawsContent(true); - - LayerImpl* root_ptr = root.get(); - LayerImpl* child_ptr = child.get(); - LayerImpl* grandchild_ptr = grandchild.get(); - - child->test_properties()->AddChild(std::move(grandchild)); - root->test_properties()->AddChild(std::move(child)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); + grandchild->SetIsDrawable(true); + greatgrandchild->SetIsDrawable(true); - host_impl.active_tree()->SetElementIdsForTesting(); + host()->SetElementIdsForTesting(); // Check the non-skipped case. - // ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - // EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect()); // Now we will reset the visible rect from property trees for the grandchild, // and we will configure |child| in several ways that should force the subtree // to be skipped. The visible content rect for |grandchild| should, therefore, // remain empty. - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); + ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect()); gfx::Transform singular; singular.matrix().set(0, 0, 0); @@ -8707,62 +7809,56 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { rotate_back_and_translate.RotateAboutYAxis(180); rotate_back_and_translate.Translate(-10, 0); - child_ptr->test_properties()->transform = singular; - 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()->transform = gfx::Transform(); + child->SetTransform(singular); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); + child->SetTransform(gfx::Transform()); - child_ptr->test_properties()->hide_layer_and_subtree = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - child_ptr->test_properties()->hide_layer_and_subtree = false; + child->SetHideLayerAndSubtree(true); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); + child->SetHideLayerAndSubtree(false); - 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; + child->SetOpacity(0.f); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); + child->SetOpacity(1.f); - root_ptr->test_properties()->transform = singular; + parent->SetTransform(singular); // Force transform tree to have a node for child, so that ancestor's // invertible transform can be tested. - child_ptr->test_properties()->transform = rotate; - host_impl.active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - root_ptr->test_properties()->transform = gfx::Transform(); - child_ptr->test_properties()->transform = gfx::Transform(); - - root_ptr->test_properties()->opacity = 0.f; - child_ptr->test_properties()->opacity = 0.7f; - host_impl.active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - root_ptr->test_properties()->opacity = 1.f; - - child_ptr->test_properties()->opacity = 0.f; + child->SetTransform(rotate); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); + parent->SetTransform(gfx::Transform()); + child->SetTransform(gfx::Transform()); + + parent->SetOpacity(0.f); + child->SetOpacity(0.7f); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); + parent->SetOpacity(1.f); + + child->SetOpacity(0.f); // Now, even though child has zero opacity, we will configure |grandchild| and // |greatgrandchild| in several ways that should force the subtree to be // processed anyhow. - grandchild_ptr->test_properties()->copy_requests.push_back( + grandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect()); - host_impl.active_tree()->property_trees()->effect_tree.ClearCopyRequests(); - child_ptr->test_properties()->opacity = 1.f; + GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests(); + child->SetOpacity(1.f); // A double sided render surface with backface visible should not be skipped - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - child_ptr->test_properties()->force_render_surface = true; - child_ptr->test_properties()->double_sided = true; - child_ptr->test_properties()->transform = rotate_back_and_translate; - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); - child_ptr->test_properties()->transform = gfx::Transform(); + ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect()); + child->SetForceRenderSurfaceForTesting(true); + child->SetDoubleSided(true); + child->SetTransform(rotate_back_and_translate); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect()); + child->SetTransform(gfx::Transform()); std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); @@ -8780,19 +7876,15 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); scoped_refptr<SingleKeyframeEffectAnimation> animation( SingleKeyframeEffectAnimation::Create(1)); - scoped_refptr<AnimationTimeline> timeline = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - timeline->AttachAnimation(animation); - animation->AttachElementForKeyframeEffect(root_ptr->element_id(), + timeline()->AttachAnimation(animation); + animation->AttachElementForKeyframeEffect(parent->element_id(), animation->keyframe_effect()->id()); animation->AddKeyframeModel(std::move(transform_animation)); - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - root_ptr->test_properties()->transform = singular; - child_ptr->test_properties()->transform = singular; - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); + ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect()); + parent->SetTransform(singular); + child->SetTransform(singular); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect()); } // This tests for correctness of an optimization. If a node in the tree @@ -8823,8 +7915,8 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { // Set up some layers to have a tree. LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - LayerImpl* grand_child = AddChild<LayerImpl>(child); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); SetElementIdsForTesting(); @@ -8846,21 +7938,26 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { // Check that we set the visible sizes as expected in CalculateDrawProperties grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); + + SetupRootProperties(root); + CopyProperties(root, child); + CreateTransformNode(child); + CopyProperties(child, grand_child); + ExecuteCalculateDrawProperties(root); ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); // See if we optimize out irrelevant pieces of work. - child->test_properties()->transform = singular; + SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(), child->visible_layer_rect()); // Check that undoing the transform is still valid (memoryless enough) - child->test_properties()->transform = gfx::Transform(); + SetTransform(child, gfx::Transform()); grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); root->layer_tree_impl()->property_trees()->needs_rebuild = true; @@ -8873,10 +7970,9 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { // ticked, there is also code along that path. This is not its test. animation->AttachElementForKeyframeEffect(child->element_id(), animation->keyframe_effect()->id()); - child->test_properties()->transform = singular; + SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect(1, 1)); child->set_visible_layer_rect(gfx::Rect(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); @@ -8884,51 +7980,35 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { // This tests that we skip computing the visible areas for the subtree // rooted at nodes with constant zero opacity. -TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - host_impl.CreatePendingTree(); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl.pending_tree(), 2); - std::unique_ptr<LayerImpl> grandchild = - LayerImpl::Create(host_impl.pending_tree(), 3); - - std::unique_ptr<FakePictureLayerImpl> greatgrandchild( - FakePictureLayerImpl::Create(host_impl.pending_tree(), 4)); +TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingPendingLayerImpl) { + auto root = Layer::Create(); + auto child = Layer::Create(); + auto grandchild = Layer::Create(); + FakeContentLayerClient client; + auto greatgrandchild = PictureLayer::Create(&client); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); grandchild->SetBounds(gfx::Size(10, 10)); - grandchild->SetDrawsContent(true); - greatgrandchild->SetDrawsContent(true); - - LayerImpl* root_ptr = root.get(); - LayerImpl* grandchild_ptr = grandchild.get(); - - child->test_properties()->AddChild(std::move(grandchild)); - root->test_properties()->AddChild(std::move(child)); + grandchild->SetIsDrawable(true); + greatgrandchild->SetIsDrawable(true); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); - host_impl.pending_tree()->SetElementIdsForTesting(); + child->AddChild(grandchild); + root->AddChild(child); + host()->SetRootLayer(root); + host()->SetElementIdsForTesting(); // Check the non-skipped case. - root_ptr->test_properties()->opacity = 1.f; - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - ASSERT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); + root->SetOpacity(1.f); + Commit(); + ASSERT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect()); // Check the skipped case. - root_ptr->test_properties()->opacity = 0.f; - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(), grandchild_ptr->visible_layer_rect()); + root->SetOpacity(0.f); + PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect()); + Commit(); + EXPECT_EQ(gfx::Rect(), PendingImplOf(grandchild)->visible_layer_rect()); // Check the animated case is not skipped. std::unique_ptr<KeyframedFloatAnimationCurve> curve( @@ -8944,86 +8024,59 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::OPACITY)); scoped_refptr<SingleKeyframeEffectAnimation> animation( SingleKeyframeEffectAnimation::Create(1)); - scoped_refptr<AnimationTimeline> timeline = - AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl.animation_host()->AddAnimationTimeline(timeline); - timeline->AttachAnimation(animation); + timeline()->AttachAnimation(animation); animation->AddKeyframeModel(std::move(keyframe_model)); - animation->AttachElementForKeyframeEffect(root_ptr->element_id(), + animation->AttachElementForKeyframeEffect(root->element_id(), animation->keyframe_effect()->id()); // Repeat the calculation invocation. - grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); - EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); + PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect()); + Commit(); + EXPECT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, SkippingLayer) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); +// Needs layer tree mode: hide_layer_and_subtree. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayer) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(10, 10)); - child->SetDrawsContent(true); + child->SetIsDrawable(true); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); - child->set_visible_layer_rect(gfx::Rect()); + CommitAndActivate(); - child->test_properties()->hide_layer_and_subtree = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); - child->test_properties()->hide_layer_and_subtree = false; + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(child)->visible_layer_rect()); + ImplOf(child)->set_visible_layer_rect(gfx::Rect()); + + child->SetHideLayerAndSubtree(true); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); + child->SetHideLayerAndSubtree(false); child->SetBounds(gfx::Size()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); child->SetBounds(gfx::Size(10, 10)); gfx::Transform rotate; - child->test_properties()->double_sided = false; + child->SetDoubleSided(false); rotate.RotateAboutXAxis(180.f); - child->test_properties()->transform = rotate; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); - child->test_properties()->double_sided = true; - child->test_properties()->transform = gfx::Transform(); - - child->test_properties()->opacity = 0.f; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) { - // Ensure that the treewalk in LayerTreeHostCommom:: - // PreCalculateMetaInformation happens when its required. - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> parent = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(100, 100)); - child->SetClipParent(root.get()); - - root->AddChild(parent); - parent->AddChild(child); - host()->SetRootLayer(root); - - child->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting()); - - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get())); + child->SetTransform(rotate); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); + child->SetDoubleSided(true); + child->SetTransform(gfx::Transform()); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get())); + child->SetOpacity(0.f); + CommitAndActivate(); + EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ResetPropertyTreeIndices) { +// Needs layer tree mode: testing PropertyTreeBuilder. +// Not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, ResetPropertyTreeIndices) { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(800, 800)); @@ -9038,22 +8091,28 @@ TEST_F(LayerTreeHostCommonTest, ResetPropertyTreeIndices) { host()->SetRootLayer(root); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); EXPECT_NE(-1, child->transform_tree_index()); child->RemoveFromParent(); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); EXPECT_EQ(-1, child->transform_tree_index()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceClipsSubtree) { // Ensure that a Clip Node is added when a render surface applies clip. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* significant_transform = AddChildToRoot<LayerImpl>(); - LayerImpl* layer_clips_subtree = AddChild<LayerImpl>(significant_transform); - LayerImpl* render_surface = AddChild<LayerImpl>(layer_clips_subtree); - LayerImpl* test_layer = AddChild<LayerImpl>(render_surface); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto significant_transform = Layer::Create(); + root->AddChild(significant_transform); + auto layer_clips_subtree = Layer::Create(); + significant_transform->AddChild(layer_clips_subtree); + auto render_surface = Layer::Create(); + layer_clips_subtree->AddChild(render_surface); + auto test_layer = Layer::Create(); + render_surface->AddChild(test_layer); // This transform should be a significant one so that a transform node is // formed for it. @@ -9066,33 +8125,28 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { transform2.Translate3d(10, 10, 10); root->SetBounds(gfx::Size(30, 30)); - significant_transform->test_properties()->transform = transform1; + significant_transform->SetTransform(transform1); significant_transform->SetBounds(gfx::Size(30, 30)); layer_clips_subtree->SetBounds(gfx::Size(30, 30)); layer_clips_subtree->SetMasksToBounds(true); - layer_clips_subtree->test_properties()->force_render_surface = true; - render_surface->test_properties()->transform = transform2; + layer_clips_subtree->SetForceRenderSurfaceForTesting(true); + render_surface->SetTransform(transform2); render_surface->SetBounds(gfx::Size(30, 30)); - render_surface->test_properties()->force_render_surface = true; + render_surface->SetForceRenderSurfaceForTesting(true); test_layer->SetBounds(gfx::Size(30, 30)); - test_layer->SetDrawsContent(true); + test_layer->SetIsDrawable(true); - float device_scale_factor = 1.f; - float page_scale_factor = 1.f; - LayerImpl* page_scale_layer = nullptr; - LayerImpl* inner_viewport_scroll_layer = nullptr; - LayerImpl* outer_viewport_scroll_layer = nullptr; - ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer); + CommitAndActivate(); - EXPECT_TRUE(GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(significant_transform), GetRenderSurface(root)); - EXPECT_TRUE(GetRenderSurface(layer_clips_subtree)); - EXPECT_NE(GetRenderSurface(render_surface), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(test_layer), GetRenderSurface(render_surface)); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(significant_transform), + GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(test_layer), + GetRenderSurfaceImpl(render_surface)); - EXPECT_EQ(gfx::Rect(30, 20), test_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { @@ -9100,23 +8154,30 @@ TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { // clip node's target, clip is 'projected' from parent space to current // target space and visible rects are calculated correctly. LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_layer = AddChild<LayerImpl>(root); - LayerImpl* target_layer = AddChild<LayerImpl>(clip_layer); - LayerImpl* test_layer = AddChild<LayerImpl>(target_layer); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* target_layer = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); gfx::Transform transform; transform.RotateAboutYAxis(45); root->SetBounds(gfx::Size(30, 30)); - clip_layer->test_properties()->transform = transform; clip_layer->SetBounds(gfx::Size(30, 30)); clip_layer->SetMasksToBounds(true); - target_layer->test_properties()->transform = transform; target_layer->SetBounds(gfx::Size(30, 30)); target_layer->SetMasksToBounds(true); test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); + SetupRootProperties(root); + CopyProperties(root, clip_layer); + CreateTransformNode(clip_layer).local = transform; + CreateClipNode(clip_layer); + CopyProperties(clip_layer, target_layer); + CreateTransformNode(target_layer).local = transform; + CreateClipNode(target_layer); + CopyProperties(target_layer, test_layer); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 30), test_layer->visible_layer_rect()); @@ -9127,31 +8188,31 @@ TEST_F(LayerTreeHostCommonTest, // Ensure clip rect is calculated correctly when render surface has unclipped // descendants. LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* between_clip_parent_and_child = AddChild<LayerImpl>(clip_parent); - LayerImpl* render_surface = - AddChild<LayerImpl>(between_clip_parent_and_child); - LayerImpl* test_layer = AddChild<LayerImpl>(render_surface); - - gfx::Transform translate; - translate.Translate(2.0, 2.0); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* between_clip_parent_and_child = AddLayer<LayerImpl>(); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 30)); - clip_parent->test_properties()->transform = translate; clip_parent->SetBounds(gfx::Size(30, 30)); - 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)); test_layer->SetDrawsContent(true); - render_surface->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(render_surface); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateTransformNode(clip_parent).local.Translate(2, 2); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, between_clip_parent_and_child); + CreateClipNode(between_clip_parent_and_child); + CreateTransformNode(between_clip_parent_and_child).local.Translate(2, 2); + CreateClipNode(between_clip_parent_and_child); + CopyProperties(between_clip_parent_and_child, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, test_layer); + test_layer->SetClipTreeIndex(clip_parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -9167,24 +8228,27 @@ TEST_F(LayerTreeHostCommonTest, // unclipped descendants is computed correctly, when the surface doesn't apply // a clip. LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface); - LayerImpl* child = AddChild<LayerImpl>(render_surface); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 10)); clip_parent->SetBounds(gfx::Size(30, 30)); render_surface->SetBounds(gfx::Size(10, 15)); - render_surface->test_properties()->force_render_surface = true; clip_child->SetBounds(gfx::Size(10, 10)); clip_child->SetDrawsContent(true); child->SetBounds(gfx::Size(40, 40)); child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CopyProperties(clip_parent, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + CopyProperties(clip_child, child); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 10), child->visible_layer_rect()); @@ -9193,19 +8257,16 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtreeAndHasUnclippedDescendants) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* test_layer1 = AddChild<LayerImpl>(render_surface); - LayerImpl* clip_child = AddChild<LayerImpl>(test_layer1); - LayerImpl* test_layer2 = AddChild<LayerImpl>(clip_child); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* test_layer1 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* test_layer2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 30)); - root->SetMasksToBounds(true); clip_parent->SetBounds(gfx::Size(30, 30)); render_surface->SetBounds(gfx::Size(50, 50)); - render_surface->SetMasksToBounds(true); render_surface->SetDrawsContent(true); - render_surface->test_properties()->force_render_surface = true; test_layer1->SetBounds(gfx::Size(50, 50)); test_layer1->SetDrawsContent(true); clip_child->SetBounds(gfx::Size(50, 50)); @@ -9213,10 +8274,17 @@ TEST_F(LayerTreeHostCommonTest, test_layer2->SetBounds(gfx::Size(50, 50)); test_layer2->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, clip_parent); + CopyProperties(clip_parent, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface); + CopyProperties(render_surface, test_layer1); + CopyProperties(test_layer1, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + CopyProperties(clip_child, test_layer2); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 30), render_surface->visible_layer_rect()); @@ -9227,24 +8295,26 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(50, 50)); clip_parent->SetBounds(gfx::Size(50, 50)); clip_parent->SetDrawsContent(true); render_surface->SetBounds(gfx::Size(30, 30)); - render_surface->test_properties()->force_render_surface = true; - render_surface->SetMasksToBounds(true); render_surface->SetDrawsContent(true); clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CopyProperties(clip_parent, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface); + CopyProperties(render_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -9260,39 +8330,48 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { // of surfaces : unclipped surfaces, surfaces with unclipped surfaces and // clipped surfaces. LayerImpl* root = root_layer_for_testing(); - LayerImpl* unclipped_surface = AddChildToRoot<LayerImpl>(); - LayerImpl* clip_parent = AddChild<LayerImpl>(unclipped_surface); - 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); - LayerImpl* clipped_surface = AddChild<LayerImpl>(clip_child); + LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface2 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); + LayerImpl* clipped_surface = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(80, 80)); + unclipped_surface->SetBounds(gfx::Size(50, 50)); - unclipped_surface->SetMasksToBounds(true); unclipped_surface->SetDrawsContent(true); - 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->SetDrawsContent(true); - unclipped_desc_surface->test_properties()->force_render_surface = true; unclipped_desc_surface2->SetBounds(gfx::Size(60, 60)); unclipped_desc_surface2->SetDrawsContent(true); - unclipped_desc_surface2->test_properties()->force_render_surface = true; clip_child->SetBounds(gfx::Size(100, 100)); clipped_surface->SetBounds(gfx::Size(70, 70)); clipped_surface->SetDrawsContent(true); - clipped_surface->test_properties()->force_render_surface = true; - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, unclipped_surface); + CreateEffectNode(unclipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(unclipped_surface); + CopyProperties(unclipped_surface, clip_parent); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, unclipped_desc_surface); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface, unclipped_desc_surface2); + CreateEffectNode(unclipped_desc_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface2, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); + CopyProperties(clip_child, clipped_surface); + CreateEffectNode(clipped_surface).render_surface_reason = + RenderSurfaceReason::kTest; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(50, 50), @@ -9309,37 +8388,35 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { // Tests the value of render surface content rect when we have a layer that // clips between the clip parent's target and clip child's target. LayerImpl* root = root_layer_for_testing(); - LayerImpl* surface = AddChildToRoot<LayerImpl>(); - LayerImpl* clip_layer = AddChild<LayerImpl>(surface); - LayerImpl* clip_parent = AddChild<LayerImpl>(clip_layer); - LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(unclipped_desc_surface); - - gfx::Transform translate; - translate.Translate(10, 10); - - gfx::Transform rotate; - rotate.RotateAboutXAxis(10); + LayerImpl* surface = AddLayer<LayerImpl>(); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); surface->SetBounds(gfx::Size(100, 100)); - surface->SetMasksToBounds(true); - surface->test_properties()->force_render_surface = true; - surface->test_properties()->transform = rotate; clip_layer->SetBounds(gfx::Size(20, 20)); - clip_layer->SetMasksToBounds(true); clip_parent->SetBounds(gfx::Size(50, 50)); - unclipped_desc_surface->test_properties()->transform = translate; unclipped_desc_surface->SetBounds(gfx::Size(100, 100)); unclipped_desc_surface->SetDrawsContent(true); - unclipped_desc_surface->test_properties()->force_render_surface = true; clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, surface); + CreateTransformNode(surface).local.RotateAboutXAxis(10); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + CreateClipNode(surface); + CopyProperties(surface, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, clip_parent); + CopyProperties(clip_parent, unclipped_desc_surface); + CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -9349,34 +8426,34 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* surface = AddChildToRoot<LayerImpl>(); - LayerImpl* clip_layer = AddChild<LayerImpl>(surface); - LayerImpl* clip_parent = AddChild<LayerImpl>(clip_layer); - LayerImpl* unclipped_desc_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(unclipped_desc_surface); - - - gfx::Transform scale; - scale.Scale(2, 2); + LayerImpl* surface = AddLayer<LayerImpl>(); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - surface->test_properties()->transform = scale; surface->SetBounds(gfx::Size(100, 100)); - surface->SetMasksToBounds(true); - surface->test_properties()->force_render_surface = true; clip_layer->SetBounds(gfx::Size(20, 20)); - clip_layer->SetMasksToBounds(true); clip_parent->SetBounds(gfx::Size(50, 50)); unclipped_desc_surface->SetBounds(gfx::Size(100, 100)); unclipped_desc_surface->SetDrawsContent(true); - unclipped_desc_surface->test_properties()->force_render_surface = true; clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, surface); + CreateTransformNode(surface).local.Scale(2, 2); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + CreateClipNode(surface); + CopyProperties(surface, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, clip_parent); + CopyProperties(clip_parent, unclipped_desc_surface); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); @@ -9385,8 +8462,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChild<LayerImpl>(root); - LayerImpl* test_layer = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); gfx::Transform translation; translation.Translate(10, 10); @@ -9394,15 +8471,21 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { root->SetBounds(gfx::Size(30, 30)); render_surface->SetBounds(gfx::Size(30, 30)); render_surface->SetMasksToBounds(true); - render_surface->test_properties()->force_render_surface = true; - test_layer->test_properties()->transform = translation; test_layer->SetBounds(gfx::Size(20, 20)); test_layer->SetDrawsContent(true); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20)); test_layer->SetTouchActionRegion(std::move(touch_action_region)); - test_layer->test_properties()->opacity = 0.f; + + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface); + CopyProperties(render_surface, test_layer); + CreateTransformNode(test_layer).local = translation; + CreateEffectNode(test_layer).opacity = 0.f; ExecuteCalculateDrawProperties(root); EXPECT_TRANSFORMATION_MATRIX_EQ(translation, @@ -9411,31 +8494,33 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_layer = AddChild<LayerImpl>(root); - LayerImpl* clip_parent = AddChild<LayerImpl>(clip_layer); - 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); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* clip_parent_child = AddLayer<LayerImpl>(); + LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); 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; clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - gfx::Transform translate; - translate.Translate(10, 10); - unclipped_desc_surface->test_properties()->transform = translate; - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, clip_parent); + CopyProperties(clip_parent, clip_parent_child); + CreateClipNode(clip_parent_child); + CopyProperties(clip_parent_child, unclipped_desc_surface); + CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10); + CreateEffectNode(unclipped_desc_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(unclipped_desc_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); float device_scale_factor = 1.f; ExecuteCalculateDrawProperties(root, device_scale_factor); @@ -9450,24 +8535,26 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip_parent = AddChildToRoot<LayerImpl>(); - LayerImpl* render_surface = AddChild<LayerImpl>(clip_parent); - LayerImpl* clip_child = AddChild<LayerImpl>(render_surface); + LayerImpl* clip_parent = AddLayer<LayerImpl>(); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 30)); clip_parent->SetBounds(gfx::Size(40, 40)); - clip_parent->SetMasksToBounds(true); render_surface->SetBounds(gfx::Size(50, 50)); - render_surface->SetMasksToBounds(true); render_surface->SetDrawsContent(true); - render_surface->test_properties()->force_render_surface = true; clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - clip_child->test_properties()->clip_parent = clip_parent; - clip_parent->test_properties()->clip_children = - std::make_unique<std::set<LayerImpl*>>(); - clip_parent->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CopyProperties(root, clip_parent); + CreateClipNode(clip_parent); + CopyProperties(clip_parent, render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface); + CopyProperties(render_surface, clip_child); + clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect()); @@ -9476,19 +8563,27 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { TEST_F(LayerTreeHostCommonTest, LayerClipRectLargerThanClippingRenderSurfaceRect) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChild<LayerImpl>(root); - LayerImpl* test_layer = AddChild<LayerImpl>(render_surface); + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 30)); - root->SetMasksToBounds(true); root->SetDrawsContent(true); render_surface->SetBounds(gfx::Size(50, 50)); - render_surface->SetMasksToBounds(true); render_surface->SetDrawsContent(true); - render_surface->test_properties()->force_render_surface = true; + test_layer->SetBounds(gfx::Size(50, 50)); - test_layer->SetMasksToBounds(true); test_layer->SetDrawsContent(true); + + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, render_surface); + CreateTransformNode(render_surface); + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CreateClipNode(render_surface); + CopyProperties(render_surface, test_layer); + CreateClipNode(test_layer); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(30, 30), root->clip_rect()); @@ -9496,157 +8591,177 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(50, 50), test_layer->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, SubtreeIsHiddenTest) { +// Needs layer tree mode: hide_layer_and_subtree. +TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeIsHiddenTest) { // Tests that subtree is hidden is updated. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* hidden = AddChild<LayerImpl>(root); - LayerImpl* test = AddChild<LayerImpl>(hidden); + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto hidden = Layer::Create(); + root->AddChild(hidden); + auto test = Layer::Create(); + hidden->AddChild(test); root->SetBounds(gfx::Size(30, 30)); hidden->SetBounds(gfx::Size(30, 30)); - hidden->test_properties()->force_render_surface = true; - hidden->test_properties()->hide_layer_and_subtree = true; + hidden->SetForceRenderSurfaceForTesting(true); + hidden->SetHideLayerAndSubtree(true); test->SetBounds(gfx::Size(30, 30)); - test->test_properties()->force_render_surface = true; + test->SetForceRenderSurfaceForTesting(true); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(0.f, - GetRenderSurface(test)->OwningEffectNode()->screen_space_opacity); + CommitAndActivate(); - hidden->test_properties()->hide_layer_and_subtree = false; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1.f, - GetRenderSurface(test)->OwningEffectNode()->screen_space_opacity); + EXPECT_EQ( + 0.f, + GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity); + + hidden->SetHideLayerAndSubtree(false); + CommitAndActivate(); + EXPECT_EQ( + 1.f, + GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity); } TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { LayerImpl* root = root_layer_for_testing(); - 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); + LayerImpl* clip_layer = AddLayer<LayerImpl>(); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* clip_child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(30, 30)); - root->SetMasksToBounds(true); clip_layer->SetBounds(gfx::Size(30, 30)); - clip_layer->SetMasksToBounds(true); - render_surface1->test_properties()->position = gfx::PointF(10, 10); render_surface1->SetBounds(gfx::Size(30, 30)); render_surface1->SetDrawsContent(true); - render_surface1->test_properties()->force_render_surface = true; render_surface2->SetBounds(gfx::Size(30, 30)); 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 = - std::make_unique<std::set<LayerImpl*>>(); - root->test_properties()->clip_children->insert(clip_child); + SetupRootProperties(root); + CreateClipNode(root); + CopyProperties(root, clip_layer); + CreateClipNode(clip_layer); + CopyProperties(clip_layer, render_surface1); + CreateTransformNode(render_surface1).post_translation = + gfx::Vector2dF(10, 10); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface2, clip_child); + clip_child->SetClipTreeIndex(root->clip_tree_index()); ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, MaskLayerDrawProperties) { +// Needs layer tree mode: mask layer. +TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { // Tests that a mask layer's draw properties are computed correctly. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* child = AddChild<LayerImpl>(root); - child->test_properties()->SetMaskLayer( - LayerImpl::Create(root->layer_tree_impl(), 100)); - LayerImpl* mask = child->test_properties()->mask_layer; + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + FakeContentLayerClient client; + auto mask = PictureLayer::Create(&client); + child->SetMaskLayer(mask); gfx::Transform transform; transform.Translate(10, 10); root->SetBounds(gfx::Size(40, 40)); - root->SetDrawsContent(true); - child->test_properties()->transform = transform; + root->SetIsDrawable(true); + child->SetTransform(transform); child->SetBounds(gfx::Size(30, 30)); - child->SetDrawsContent(false); - mask->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawProperties(root); + child->SetIsDrawable(false); + mask->SetBounds(gfx::Size(30, 30)); + + CommitAndActivate(); // The render surface created for the mask has no contributing content, so the // mask doesn't contribute to a drawn render surface. This means it has an // empty visible rect, but its screen space transform can still be computed // correctly on-demand. - EXPECT_FALSE(mask->contributes_to_drawn_render_surface()); - EXPECT_EQ(gfx::Rect(), mask->visible_layer_rect()); - EXPECT_TRANSFORMATION_MATRIX_EQ(transform, mask->ScreenSpaceTransform()); + EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect()); + EXPECT_TRANSFORMATION_MATRIX_EQ(transform, + ImplOf(mask)->ScreenSpaceTransform()); // Make the child's render surface have contributing content. - child->SetDrawsContent(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(mask->contributes_to_drawn_render_surface()); - EXPECT_EQ(gfx::Rect(20, 20), mask->visible_layer_rect()); - EXPECT_TRANSFORMATION_MATRIX_EQ(transform, mask->ScreenSpaceTransform()); + child->SetIsDrawable(true); + CommitAndActivate(); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect()); + EXPECT_TRANSFORMATION_MATRIX_EQ(transform, + ImplOf(mask)->ScreenSpaceTransform()); transform.Translate(10, 10); - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_TRANSFORMATION_MATRIX_EQ(transform, mask->ScreenSpaceTransform()); - EXPECT_EQ(gfx::Rect(20, 20), mask->visible_layer_rect()); + child->SetTransform(transform); + CommitAndActivate(); + EXPECT_TRANSFORMATION_MATRIX_EQ(transform, + ImplOf(mask)->ScreenSpaceTransform()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, SublayerScaleWithTransformNodeBetweenTwoTargets) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(root); - LayerImpl* between_targets = AddChild<LayerImpl>(render_surface1); - LayerImpl* render_surface2 = AddChild<LayerImpl>(between_targets); - LayerImpl* test_layer = AddChild<LayerImpl>(render_surface2); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* between_targets = AddLayer<LayerImpl>(); + LayerImpl* render_surface2 = AddLayer<LayerImpl>(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); gfx::Transform scale; scale.Scale(2.f, 2.f); root->SetBounds(gfx::Size(30, 30)); - render_surface1->test_properties()->transform = scale; render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->test_properties()->force_render_surface = true; between_targets->SetBounds(gfx::Size(30, 30)); render_surface2->SetBounds(gfx::Size(30, 30)); - render_surface2->test_properties()->force_render_surface = true; test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); // We want layer between the two targets to create a clip node and effect // node but it shouldn't create a render surface. between_targets->SetMasksToBounds(true); - between_targets->test_properties()->opacity = 0.5f; - - ExecuteCalculateDrawProperties(root); - - EffectTree& tree = root->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = tree.Node(render_surface1->effect_tree_index()); - EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); - - node = tree.Node(between_targets->effect_tree_index()); - EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); - - node = tree.Node(render_surface2->effect_tree_index()); - EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); + SetupRootProperties(root); + CopyProperties(root, render_surface1); + CreateTransformNode(render_surface1).local = scale; + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, between_targets); + CreateEffectNode(between_targets).opacity = 0.5f; + CreateClipNode(between_targets); + CopyProperties(between_targets, render_surface2); + CreateEffectNode(render_surface2).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface2, test_layer); + + ExecuteCalculateDrawProperties(root); + + EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), + GetEffectNode(render_surface1)->surface_contents_scale); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f), + GetEffectNode(between_targets)->surface_contents_scale); + EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), + GetEffectNode(render_surface2)->surface_contents_scale); EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect()); } TEST_F(LayerTreeHostCommonTest, NoisyTransform) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface = AddChild<LayerImpl>(root); - LayerImpl* scroll_child = AddChild<LayerImpl>(render_surface); - LayerImpl* scroll_clip = AddChild<LayerImpl>(render_surface); - LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_clip); - - scroll_child->test_properties()->scroll_parent = scroll_parent; + LayerImpl* render_surface = AddLayer<LayerImpl>(); + LayerImpl* parent = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); - scroll_parent->SetDrawsContent(true); - scroll_child->SetDrawsContent(true); - render_surface->test_properties()->force_render_surface = true; + root->SetBounds(gfx::Size(30, 30)); + parent->SetBounds(gfx::Size(30, 30)); + parent->SetDrawsContent(true); + child->SetBounds(gfx::Size(30, 30)); + child->SetDrawsContent(true); // A noisy transform that's invertible. gfx::Transform transform; @@ -9655,12 +8770,15 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { transform.matrix().setDouble(2, 2, 6.12323e-17); transform.matrix().setDouble(2, 0, -1); - scroll_child->test_properties()->transform = transform; - render_surface->test_properties()->transform = transform; + SetupRootProperties(root); + CopyProperties(root, render_surface); + CreateTransformNode(render_surface).local = transform; + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface, parent); + CopyProperties(parent, child); + CreateTransformNode(child).local = transform; - root->SetBounds(gfx::Size(30, 30)); - scroll_child->SetBounds(gfx::Size(30, 30)); - scroll_parent->SetBounds(gfx::Size(30, 30)); ExecuteCalculateDrawProperties(root); gfx::Transform expected; @@ -9668,14 +8786,13 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { expected.matrix().setDouble(0, 2, 6.12323e-17); expected.matrix().setDouble(2, 0, -1); expected.matrix().setDouble(2, 2, 6.12323e-17); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected, - scroll_child->ScreenSpaceTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected, child->ScreenSpaceTransform()); } TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { LayerImpl* root = root_layer_for_testing(); - LayerImpl* render_surface1 = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(render_surface1); + LayerImpl* render_surface1 = AddLayer<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetDrawsContent(true); child->SetMasksToBounds(true); @@ -9688,16 +8805,22 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { root->SetBounds(gfx::Size(30, 30)); render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->test_properties()->force_render_surface = true; // TODO(sunxd): we make child have no render surface, because if the // child has one, the large transform applied to child will result in NaNs in // the draw_transform of the render_surface, thus make draw property updates // skip the child layer. We need further investigation into this to know // what exactly happens here. - child->test_properties()->transform = large_transform; child->SetBounds(gfx::Size(30, 30)); + SetupRootProperties(root); + CopyProperties(root, render_surface1); + CreateEffectNode(render_surface1).render_surface_reason = + RenderSurfaceReason::kTest; + CopyProperties(render_surface1, child); + CreateTransformNode(child).local = large_transform; + CreateClipNode(child); + ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(), @@ -9716,7 +8839,10 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { EXPECT_TRUE(base::Contains(*rsl, GetRenderSurface(root))); } -TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { +// Needs layer tree mode: testing needs_rebuild flag. +// Not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + PropertyTreesRebuildWithOpacityChanges) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child = Layer::Create(); child->SetIsDrawable(true); @@ -9725,7 +8851,7 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { root->SetBounds(gfx::Size(100, 100)); child->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); // Changing the opacity from 1 to non-1 value should trigger rebuild of // property trees as a new effect node will be created. @@ -9733,9 +8859,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { PropertyTrees* property_trees = host()->property_trees(); EXPECT_TRUE(property_trees->needs_rebuild); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_NE(property_trees->effect_tree.Node(child->effect_tree_index()), - property_trees->effect_tree.Node(root->effect_tree_index())); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); // child already has an effect node. Changing its opacity shouldn't trigger // a property trees rebuild. @@ -9743,9 +8868,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { property_trees = host()->property_trees(); EXPECT_FALSE(property_trees->needs_rebuild); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_NE(property_trees->effect_tree.Node(child->effect_tree_index()), - property_trees->effect_tree.Node(root->effect_tree_index())); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); // 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. @@ -9753,12 +8877,12 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { property_trees = host()->property_trees(); EXPECT_TRUE(property_trees->needs_rebuild); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_EQ(property_trees->effect_tree.Node(child->effect_tree_index()), - property_trees->effect_tree.Node(root->effect_tree_index())); + ExecuteCalculateDrawProperties(root.get()); + EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index()); } -TEST_F(LayerTreeHostCommonTest, OpacityAnimationsTrackingTest) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -9788,27 +8912,27 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); - EffectTree& tree = root->layer_tree_host()->property_trees()->effect_tree; - EffectNode* node = tree.Node(animated->effect_tree_index()); + EffectNode* node = GetEffectNode(animated.get()); EXPECT_FALSE(node->is_currently_animating_opacity); EXPECT_TRUE(node->has_potential_opacity_animation); keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0)); host()->AnimateLayers(base::TimeTicks::Max()); - node = tree.Node(animated->effect_tree_index()); + node = GetEffectNode(animated.get()); EXPECT_TRUE(node->is_currently_animating_opacity); EXPECT_TRUE(node->has_potential_opacity_animation); animation->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY, false /*needs_completion*/); - node = tree.Node(animated->effect_tree_index()); + node = GetEffectNode(animated.get()); EXPECT_FALSE(node->is_currently_animating_opacity); EXPECT_FALSE(node->has_potential_opacity_animation); } -TEST_F(LayerTreeHostCommonTest, TransformAnimationsTrackingTest) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -9846,615 +8970,336 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); + ExecuteCalculateDrawProperties(root.get()); - TransformTree& tree = - root->layer_tree_host()->property_trees()->transform_tree; - TransformNode* node = tree.Node(animated->transform_tree_index()); + TransformNode* node = GetTransformNode(animated.get()); EXPECT_FALSE(node->is_currently_animating); EXPECT_TRUE(node->has_potential_animation); keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0)); host()->AnimateLayers(base::TimeTicks::Max()); - node = tree.Node(animated->transform_tree_index()); + node = GetTransformNode(animated.get()); EXPECT_TRUE(node->is_currently_animating); EXPECT_TRUE(node->has_potential_animation); animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM, false /*needs_completion*/); - node = tree.Node(animated->transform_tree_index()); + node = GetTransformNode(animated.get()); EXPECT_FALSE(node->is_currently_animating); EXPECT_FALSE(node->has_potential_animation); } -TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { - // Test the behavior of scroll tree builder - // Topology: - // +root1(1)[inner_viewport_container_layer] - // +-page_scale_layer - // +----parent2(2)[kHasBackgroundAttachmentFixedObjects|kScrollbarScrolling & - // scrollable, inner_viewport_scroll_layer] - // +------child6(6)[kScrollbarScrolling] - // +--------grand_child10(10)[kScrollbarScrolling] - // +----parent3(3) - // +------child7(7)[scrollable] - // +------child8(8)[scroll_parent=7] - // +--------grand_child11(11)[scrollable] - // +----parent4(4) - // +------child9(9) - // +--------grand_child12(12) - // +----parent5(5)[contains_non_fast_scrollable_region] - // - // Expected scroll tree topology: - // +property_tree_root---owner:-1 - // +--root---owner:1, id:1 - // +----node---owner:2, id:2 - // +------node---owner:6, id:3 - // +----node---owner:7, id:4 - // +------node---owner:11, id:5 - // +----node---owner:5, id:6 - // - // Extra check: - // scroll_tree_index() of: - // grand_child10:3 - // parent3:1 - // child8:4 - // parent4:1 - // child9:1 - // grand_child12:1 - scoped_refptr<Layer> root1 = Layer::Create(); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> parent2 = Layer::Create(); - scoped_refptr<Layer> parent3 = Layer::Create(); - scoped_refptr<Layer> parent4 = Layer::Create(); - scoped_refptr<Layer> parent5 = Layer::Create(); - scoped_refptr<Layer> child6 = Layer::Create(); - scoped_refptr<Layer> child7 = Layer::Create(); - scoped_refptr<Layer> child8 = Layer::Create(); - scoped_refptr<Layer> child9 = Layer::Create(); - scoped_refptr<Layer> grand_child10 = Layer::Create(); - scoped_refptr<Layer> grand_child11 = Layer::Create(); - scoped_refptr<Layer> grand_child12 = Layer::Create(); - - root1->AddChild(page_scale_layer); - page_scale_layer->AddChild(parent2); - page_scale_layer->AddChild(parent3); - page_scale_layer->AddChild(parent4); - page_scale_layer->AddChild(parent5); - parent2->AddChild(child6); - parent3->AddChild(child7); - parent3->AddChild(child8); - parent4->AddChild(child9); - child6->AddChild(grand_child10); - child8->AddChild(grand_child11); - child9->AddChild(grand_child12); - host()->SetRootLayer(root1); - - root1->SetBounds(gfx::Size(1, 1)); - parent2->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); - parent2->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling); - parent2->SetElementId(LayerIdToElementIdForTesting(parent2->id())); - parent2->SetScrollable(root1->bounds()); - child6->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling); - grand_child10->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling); - - parent3->SetBounds(gfx::Size(2, 2)); - child7->SetScrollable(parent3->bounds()); - child7->SetElementId(LayerIdToElementIdForTesting(child7->id())); - - child8->SetScrollParent(child7.get()); - child8->SetBounds(gfx::Size(3, 3)); - grand_child11->SetScrollable(child8->bounds()); - grand_child11->SetElementId( - LayerIdToElementIdForTesting(grand_child11->id())); - - parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); - parent5->SetBounds(gfx::Size(10, 10)); - - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root1; - viewport_layers.inner_viewport_scroll = parent2; - host()->RegisterViewportLayers(viewport_layers); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root1.get()); - - const int kRootPropertyTreeNodeId = 0; - - // Property tree root - ScrollTree& scroll_tree = host()->property_trees()->scroll_tree; - PropertyTrees property_trees; - property_trees.is_main_thread = true; - property_trees.is_active = false; - ScrollTree& expected_scroll_tree = property_trees.scroll_tree; - ScrollNode* property_tree_root = expected_scroll_tree.Node(0); - property_tree_root->id = kRootPropertyTreeNodeId; - property_tree_root->parent_id = ScrollTree::kInvalidNodeId; - property_tree_root->scrollable = false; - property_tree_root->main_thread_scrolling_reasons = - MainThreadScrollingReason::kNotScrollingOnMain; - property_tree_root->transform_id = kRootPropertyTreeNodeId; - - // The node owned by root1 - ScrollNode scroll_root1; - scroll_root1.id = 1; - scroll_root1.bounds = root1->bounds(); - scroll_root1.user_scrollable_horizontal = true; - scroll_root1.user_scrollable_vertical = true; - scroll_root1.transform_id = root1->transform_tree_index(); - expected_scroll_tree.Insert(scroll_root1, 0); - - // The node owned by parent2 - ScrollNode scroll_parent2; - scroll_parent2.id = 2; - scroll_parent2.element_id = parent2->element_id(); - scroll_parent2.scrollable = true; - scroll_parent2.main_thread_scrolling_reasons = - parent2->GetMainThreadScrollingReasons(); - scroll_parent2.container_bounds = root1->bounds(); - scroll_parent2.bounds = parent2->bounds(); - scroll_parent2.max_scroll_offset_affected_by_page_scale = true; - scroll_parent2.scrolls_inner_viewport = true; - scroll_parent2.user_scrollable_horizontal = true; - scroll_parent2.user_scrollable_vertical = true; - scroll_parent2.transform_id = parent2->transform_tree_index(); - expected_scroll_tree.Insert(scroll_parent2, 1); - - // The node owned by child6 - ScrollNode scroll_child6; - scroll_child6.id = 3; - scroll_child6.main_thread_scrolling_reasons = - child6->GetMainThreadScrollingReasons(); - scroll_child6.should_flatten = true; - scroll_child6.user_scrollable_horizontal = true; - scroll_child6.user_scrollable_vertical = true; - scroll_child6.transform_id = child6->transform_tree_index(); - expected_scroll_tree.Insert(scroll_child6, 2); - - // The node owned by child7, child7 also owns a transform node - ScrollNode scroll_child7; - scroll_child7.id = 4; - scroll_child7.element_id = child7->element_id(); - scroll_child7.scrollable = true; - scroll_child7.container_bounds = parent3->bounds(); - scroll_child7.bounds = child7->bounds(); - scroll_child7.user_scrollable_horizontal = true; - scroll_child7.user_scrollable_vertical = true; - scroll_child7.transform_id = child7->transform_tree_index(); - expected_scroll_tree.Insert(scroll_child7, 1); - - // The node owned by grand_child11, grand_child11 also owns a transform node - ScrollNode scroll_grand_child11; - scroll_grand_child11.id = 5; - scroll_grand_child11.element_id = grand_child11->element_id(); - scroll_grand_child11.scrollable = true; - scroll_grand_child11.container_bounds = child8->bounds(); - scroll_grand_child11.user_scrollable_horizontal = true; - 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); - - // The node owned by parent5 - ScrollNode scroll_parent5; - scroll_parent5.id = 8; - scroll_parent5.bounds = gfx::Size(10, 10); - scroll_parent5.should_flatten = true; - scroll_parent5.user_scrollable_horizontal = true; - scroll_parent5.user_scrollable_vertical = true; - scroll_parent5.transform_id = parent5->transform_tree_index(); - expected_scroll_tree.Insert(scroll_parent5, 1); - - expected_scroll_tree.SetScrollOffset(parent2->element_id(), - gfx::ScrollOffset(0, 0)); - expected_scroll_tree.SetScrollOffset(child7->element_id(), - gfx::ScrollOffset(0, 0)); - expected_scroll_tree.SetScrollOffset(grand_child11->element_id(), - gfx::ScrollOffset(0, 0)); - expected_scroll_tree.set_needs_update(false); - - EXPECT_EQ(expected_scroll_tree, scroll_tree); - - // Check other layers' scroll_tree_index - EXPECT_EQ(scroll_root1.id, page_scale_layer->scroll_tree_index()); - EXPECT_EQ(scroll_child6.id, grand_child10->scroll_tree_index()); - EXPECT_EQ(scroll_root1.id, parent3->scroll_tree_index()); - EXPECT_EQ(scroll_child7.id, child8->scroll_tree_index()); - EXPECT_EQ(scroll_root1.id, parent4->scroll_tree_index()); - EXPECT_EQ(scroll_root1.id, child9->scroll_tree_index()); - EXPECT_EQ(scroll_root1.id, grand_child12->scroll_tree_index()); -} - -TEST_F(LayerTreeHostCommonTest, CopyRequestScalingTest) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* scale_layer = AddChild<LayerImpl>(root); - LayerImpl* copy_layer = AddChild<LayerImpl>(scale_layer); - LayerImpl* clip_layer = AddChild<LayerImpl>(copy_layer); - LayerImpl* test_layer = AddChild<LayerImpl>(clip_layer); +// Needs layer tree mode: copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, CopyRequestScalingTest) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto scale_layer = Layer::Create(); + root->AddChild(scale_layer); + auto copy_layer = Layer::Create(); + scale_layer->AddChild(copy_layer); + auto clip_layer = Layer::Create(); + copy_layer->AddChild(clip_layer); + auto test_layer = Layer::Create(); + clip_layer->AddChild(test_layer); root->SetBounds(gfx::Size(150, 150)); scale_layer->SetBounds(gfx::Size(30, 30)); gfx::Transform transform; transform.Scale(5.f, 5.f); - scale_layer->test_properties()->transform = transform; + scale_layer->SetTransform(transform); // Need to persist the render surface after copy request is cleared. - copy_layer->test_properties()->force_render_surface = true; - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->SetForceRenderSurfaceForTesting(true); + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - clip_layer->SetDrawsContent(true); + clip_layer->SetIsDrawable(true); clip_layer->SetMasksToBounds(true); clip_layer->SetBounds(gfx::Size(10, 10)); - test_layer->SetDrawsContent(true); + test_layer->SetIsDrawable(true); test_layer->SetMasksToBounds(true); test_layer->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); // Check surface with copy request draw properties. - EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(copy_layer)->content_rect()); - EXPECT_EQ(gfx::Transform(), GetRenderSurface(copy_layer)->draw_transform()); + EXPECT_EQ(gfx::Rect(50, 50), + GetRenderSurfaceImpl(copy_layer)->content_rect()); + EXPECT_EQ(gfx::Transform(), + GetRenderSurfaceImpl(copy_layer)->draw_transform()); EXPECT_EQ(gfx::RectF(50.0f, 50.0f), - GetRenderSurface(copy_layer)->DrawableContentRect()); + GetRenderSurfaceImpl(copy_layer)->DrawableContentRect()); // Check test layer draw properties. - EXPECT_EQ(gfx::Rect(10, 10), test_layer->visible_layer_rect()); - EXPECT_EQ(transform, test_layer->DrawTransform()); - EXPECT_EQ(gfx::Rect(50, 50), test_layer->clip_rect()); - EXPECT_EQ(gfx::Rect(50, 50), test_layer->drawable_content_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(test_layer)->visible_layer_rect()); + EXPECT_EQ(transform, ImplOf(test_layer)->DrawTransform()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->clip_rect()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->drawable_content_rect()); // Clear the copy request and call UpdateSurfaceContentsScale. - host_impl()->active_tree()->property_trees()->effect_tree.ClearCopyRequests(); - ExecuteCalculateDrawProperties(root); + GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests(); + CommitAndActivate(); } -TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCacheRenderSurface) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.pending_tree(), 1); +// Needs layer tree mode: hide_layer_and_subtree, etc. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + SubtreeHiddenWithCacheRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); - LayerImpl* root_layer = root.get(); + root->SetIsDrawable(true); + + auto cache_grand_parent_sibling_before = Layer::Create(); + root->AddChild(cache_grand_parent_sibling_before); + cache_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40)); + cache_grand_parent_sibling_before->SetIsDrawable(true); - std::unique_ptr<LayerImpl> cache_grand_parent = - LayerImpl::Create(host_impl.pending_tree(), 2); + auto cache_grand_parent = Layer::Create(); + root->AddChild(cache_grand_parent); cache_grand_parent->SetBounds(gfx::Size(40, 40)); - cache_grand_parent->SetDrawsContent(true); - LayerImpl* cache_grand_parent_layer = cache_grand_parent.get(); + cache_grand_parent->SetIsDrawable(true); - std::unique_ptr<LayerImpl> cache_parent = - LayerImpl::Create(host_impl.pending_tree(), 3); + auto cache_parent = Layer::Create(); + cache_grand_parent->AddChild(cache_parent); cache_parent->SetBounds(gfx::Size(30, 30)); - cache_parent->SetDrawsContent(true); - cache_parent->test_properties()->force_render_surface = true; - LayerImpl* cache_parent_layer = cache_parent.get(); + cache_parent->SetIsDrawable(true); + cache_parent->SetForceRenderSurfaceForTesting(true); - std::unique_ptr<LayerImpl> cache_render_surface = - LayerImpl::Create(host_impl.pending_tree(), 4); + auto cache_render_surface = Layer::Create(); + cache_parent->AddChild(cache_render_surface); cache_render_surface->SetBounds(gfx::Size(20, 20)); - cache_render_surface->SetDrawsContent(true); - cache_render_surface->test_properties()->cache_render_surface = true; - LayerImpl* cache_layer = cache_render_surface.get(); + cache_render_surface->SetIsDrawable(true); + cache_render_surface->SetCacheRenderSurface(true); - std::unique_ptr<LayerImpl> cache_child = - LayerImpl::Create(host_impl.pending_tree(), 5); + auto cache_child = Layer::Create(); + cache_render_surface->AddChild(cache_child); cache_child->SetBounds(gfx::Size(20, 20)); - cache_child->SetDrawsContent(true); - LayerImpl* cache_child_layer = cache_child.get(); + cache_child->SetIsDrawable(true); - std::unique_ptr<LayerImpl> cache_grand_child = - LayerImpl::Create(host_impl.pending_tree(), 6); + auto cache_grand_child = Layer::Create(); + cache_child->AddChild(cache_grand_child); cache_grand_child->SetBounds(gfx::Size(20, 20)); - cache_grand_child->SetDrawsContent(true); - LayerImpl* cache_grand_child_layer = cache_grand_child.get(); - - std::unique_ptr<LayerImpl> cache_grand_parent_sibling_before = - LayerImpl::Create(host_impl.pending_tree(), 7); - cache_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40)); - cache_grand_parent_sibling_before->SetDrawsContent(true); - LayerImpl* cache_grand_parent_sibling_before_layer = - cache_grand_parent_sibling_before.get(); + cache_grand_child->SetIsDrawable(true); - std::unique_ptr<LayerImpl> cache_grand_parent_sibling_after = - LayerImpl::Create(host_impl.pending_tree(), 8); + auto cache_grand_parent_sibling_after = Layer::Create(); + root->AddChild(cache_grand_parent_sibling_after); cache_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40)); - cache_grand_parent_sibling_after->SetDrawsContent(true); - LayerImpl* cache_grand_parent_sibling_after_layer = - cache_grand_parent_sibling_after.get(); - - cache_child->test_properties()->AddChild(std::move(cache_grand_child)); - cache_render_surface->test_properties()->AddChild(std::move(cache_child)); - cache_parent->test_properties()->AddChild(std::move(cache_render_surface)); - cache_grand_parent->test_properties()->AddChild(std::move(cache_parent)); - root->test_properties()->AddChild( - std::move(cache_grand_parent_sibling_before)); - root->test_properties()->AddChild(std::move(cache_grand_parent)); - root->test_properties()->AddChild( - std::move(cache_grand_parent_sibling_after)); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); + cache_grand_parent_sibling_after->SetIsDrawable(true); // Hide the cache_grand_parent and its subtree. But cache a render surface in // that hidden subtree on cache_layer. Also hide the cache grand child and its // subtree. - cache_grand_parent_layer->test_properties()->hide_layer_and_subtree = true; - cache_grand_parent_sibling_before_layer->test_properties() - ->hide_layer_and_subtree = true; - cache_grand_parent_sibling_after_layer->test_properties() - ->hide_layer_and_subtree = true; - cache_grand_child_layer->test_properties()->hide_layer_and_subtree = true; - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + cache_grand_parent->SetHideLayerAndSubtree(true); + cache_grand_parent_sibling_before->SetHideLayerAndSubtree(true); + cache_grand_parent_sibling_after->SetHideLayerAndSubtree(true); + cache_grand_child->SetHideLayerAndSubtree(true); + + CommitAndActivate(); // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent - // since it owns a surface, and one for the cache_layer. - ASSERT_EQ(4u, render_surface_list.size()); - EXPECT_EQ(static_cast<uint64_t>(root_layer->id()), - render_surface_list.at(0)->id()); - EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent_layer->id()), - render_surface_list.at(1)->id()); - EXPECT_EQ(static_cast<uint64_t>(cache_parent_layer->id()), - render_surface_list.at(2)->id()); - EXPECT_EQ(static_cast<uint64_t>(cache_layer->id()), - render_surface_list.at(3)->id()); + // since it owns a surface, and one for the cache. + ASSERT_EQ(4u, render_surface_list_impl()->size()); + EXPECT_EQ(static_cast<uint64_t>(root->id()), + render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent->id()), + render_surface_list_impl()->at(1)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_parent->id()), + render_surface_list_impl()->at(2)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_render_surface->id()), + render_surface_list_impl()->at(3)->id()); // The root render surface should have 2 contributing layers. - EXPECT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); - EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(cache_grand_parent_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(cache_grand_parent_sibling_before_layer + EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); + EXPECT_FALSE( + ImplOf(cache_grand_parent)->contributes_to_drawn_render_surface()); + EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_before) ->contributes_to_drawn_render_surface()); - EXPECT_FALSE(cache_grand_parent_sibling_after_layer + EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_after) ->contributes_to_drawn_render_surface()); - // Nothing actually draws into the cache parent, so only the cache_layer will + // Nothing actually draws into the cache parent, so only the cache will // appear in its list, since it needs to be drawn for the cache render // surface. - ASSERT_EQ(1, GetRenderSurface(cache_parent_layer)->num_contributors()); - EXPECT_FALSE(cache_parent_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(1, GetRenderSurfaceImpl(cache_parent)->num_contributors()); + EXPECT_FALSE(ImplOf(cache_parent)->contributes_to_drawn_render_surface()); // The cache layer's render surface should have 2 contributing layers. - ASSERT_EQ(2, GetRenderSurface(cache_layer)->num_contributors()); - EXPECT_TRUE(cache_layer->contributes_to_drawn_render_surface()); - EXPECT_TRUE(cache_child_layer->contributes_to_drawn_render_surface()); - EXPECT_FALSE(cache_grand_child_layer->contributes_to_drawn_render_surface()); + ASSERT_EQ(2, GetRenderSurfaceImpl(cache_render_surface)->num_contributors()); + EXPECT_TRUE( + ImplOf(cache_render_surface)->contributes_to_drawn_render_surface()); + EXPECT_TRUE(ImplOf(cache_child)->contributes_to_drawn_render_surface()); + EXPECT_FALSE( + ImplOf(cache_grand_child)->contributes_to_drawn_render_surface()); // cache_grand_parent, cache_parent shouldn't be drawn because they are - // hidden, but the cache_layer and cache_child should be drawn for the cache + // hidden, but the cache and cache_child should be drawn for the cache // render surface. cache grand child should not be drawn as its hidden even in // the cache render surface. - EffectTree& tree = - root_layer->layer_tree_impl()->property_trees()->effect_tree; - EffectNode* node = tree.Node(cache_grand_parent_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - node = tree.Node(cache_parent_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - node = tree.Node(cache_layer->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); - node = tree.Node(cache_child_layer->effect_tree_index()); - EXPECT_TRUE(node->is_drawn); - node = tree.Node(cache_grand_child_layer->effect_tree_index()); - EXPECT_FALSE(node->is_drawn); - - // Though cache_layer is drawn, it shouldn't contribute to drawn surface as + EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_parent))->is_drawn); + EXPECT_FALSE(GetEffectNode(ImplOf(cache_parent))->is_drawn); + EXPECT_TRUE(GetEffectNode(ImplOf(cache_render_surface))->is_drawn); + EXPECT_TRUE(GetEffectNode(ImplOf(cache_child))->is_drawn); + EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_child))->is_drawn); + + // Though cache is drawn, it shouldn't contribute to drawn surface as // its actually hidden. - EXPECT_FALSE(GetRenderSurface(cache_layer)->contributes_to_drawn_surface()); + EXPECT_FALSE(GetRenderSurfaceImpl(cache_render_surface) + ->contributes_to_drawn_surface()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCacheRenderSurface) { - LayerImpl* root = root_layer_for_testing(); +// Needs layer tree mode: copy request. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + VisibleRectInNonRootCacheRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); - root->SetDrawsContent(true); + root->SetIsDrawable(true); root->SetMasksToBounds(true); - LayerImpl* cache_render_surface_layer = AddChild<LayerImpl>(root); + auto cache_render_surface_layer = Layer::Create(); + root->AddChild(cache_render_surface_layer); cache_render_surface_layer->SetBounds(gfx::Size(120, 120)); - cache_render_surface_layer->SetDrawsContent(true); - cache_render_surface_layer->test_properties()->cache_render_surface = true; + cache_render_surface_layer->SetIsDrawable(true); + cache_render_surface_layer->SetCacheRenderSurface(true); - LayerImpl* copy_layer = AddChild<LayerImpl>(cache_render_surface_layer); + auto copy_layer = Layer::Create(); + cache_render_surface_layer->AddChild(copy_layer); copy_layer->SetBounds(gfx::Size(100, 100)); - copy_layer->SetDrawsContent(true); - copy_layer->test_properties()->force_render_surface = true; + copy_layer->SetIsDrawable(true); + copy_layer->SetForceRenderSurfaceForTesting(true); - LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); - copy_child->test_properties()->position = gfx::PointF(40.f, 40.f); + auto copy_child = Layer::Create(); + copy_layer->AddChild(copy_child); + copy_child->SetPosition(gfx::PointF(40.f, 40.f)); copy_child->SetBounds(gfx::Size(20, 20)); - copy_child->SetDrawsContent(true); + copy_child->SetIsDrawable(true); - LayerImpl* copy_clip = AddChild<LayerImpl>(copy_layer); + auto copy_clip = Layer::Create(); + copy_layer->AddChild(copy_clip); copy_clip->SetBounds(gfx::Size(55, 55)); copy_clip->SetMasksToBounds(true); - LayerImpl* copy_clipped_child = AddChild<LayerImpl>(copy_clip); - copy_clipped_child->test_properties()->position = gfx::PointF(40.f, 40.f); + auto copy_clipped_child = Layer::Create(); + copy_clip->AddChild(copy_clipped_child); + copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f)); copy_clipped_child->SetBounds(gfx::Size(20, 20)); - copy_clipped_child->SetDrawsContent(true); + copy_clipped_child->SetIsDrawable(true); - LayerImpl* cache_surface = AddChild<LayerImpl>(copy_clip); - cache_surface->test_properties()->position = gfx::PointF(45.f, 45.f); + auto cache_surface = Layer::Create(); + copy_clip->AddChild(cache_surface); + cache_surface->SetPosition(gfx::PointF(45.f, 45.f)); cache_surface->SetBounds(gfx::Size(20, 20)); - cache_surface->SetDrawsContent(true); + cache_surface->SetIsDrawable(true); + + CommitAndActivate(); - ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(120, 120), - cache_render_surface_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), cache_surface->visible_layer_rect()); + ImplOf(cache_render_surface_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect()); // Case 2: When the non root cache render surface layer is clipped. cache_render_surface_layer->SetBounds(gfx::Size(50, 50)); cache_render_surface_layer->SetMasksToBounds(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); + CommitAndActivate(); EXPECT_EQ(gfx::Rect(50, 50), - cache_render_surface_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(5, 5), cache_surface->visible_layer_rect()); + ImplOf(cache_render_surface_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect()); // Case 3: When there is device scale factor. float device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + CommitAndActivate(device_scale_factor); EXPECT_EQ(gfx::Rect(50, 50), - cache_render_surface_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(5, 5), cache_surface->visible_layer_rect()); + ImplOf(cache_render_surface_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect()); // Case 4: When the non root cache render surface layer is clipped and there // is a copy request layer beneath it. - copy_layer->test_properties()->copy_requests.push_back( + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(); + ASSERT_FALSE(copy_layer->HasCopyRequest()); EXPECT_EQ(gfx::Rect(50, 50), - cache_render_surface_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), cache_surface->visible_layer_rect()); + ImplOf(cache_render_surface_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect()); // Case 5: When there is another cache render surface layer under the copy // request layer. - cache_surface->test_properties()->cache_render_surface = true; - copy_layer->test_properties()->copy_requests.push_back( + cache_surface->SetCacheRenderSurface(true); + copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - DCHECK(!copy_layer->test_properties()->copy_requests.empty()); - ExecuteCalculateDrawProperties(root); - DCHECK(copy_layer->test_properties()->copy_requests.empty()); + ASSERT_TRUE(copy_layer->HasCopyRequest()); + CommitAndActivate(); + ASSERT_FALSE(copy_layer->HasCopyRequest()); EXPECT_EQ(gfx::Rect(50, 50), - cache_render_surface_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(20, 20), cache_surface->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, BuildPropertyNodesForScrollChildrenInOrder) { - // This test is intended to test against a bug that scroll children were - // visited in unspecified order, which can cause data dependency to fail - // while resolving clip parent. - - // Try multiple times because in the original bug the probability to fail - // was 50%, depends on the hash values. - int trial = 10; - while (trial--) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> scroller = Layer::Create(); - scoped_refptr<Layer> scroll_sibling_1 = Layer::Create(); - scoped_refptr<Layer> scroll_sibling_2 = Layer::Create(); - scoped_refptr<Layer> clip_escaper = Layer::Create(); - - root->SetBounds(gfx::Size(100, 100)); - scroll_sibling_1->SetBounds(gfx::Size(10, 20)); - scroll_sibling_1->SetMasksToBounds(true); - scroll_sibling_2->SetBounds(gfx::Size(20, 10)); - scroll_sibling_2->SetMasksToBounds(true); - clip_escaper->SetBounds(gfx::Size(30, 30)); - clip_escaper->SetIsDrawable(true); - - host()->SetRootLayer(root); - root->AddChild(scroller.get()); - root->AddChild(scroll_sibling_1.get()); - root->AddChild(scroll_sibling_2.get()); - scroll_sibling_2->AddChild(clip_escaper.get()); - - // Also randomize scroll children insertion order. - if (trial & 1) { - scroll_sibling_1->SetScrollParent(scroller.get()); - scroll_sibling_2->SetScrollParent(scroller.get()); - } else { - scroll_sibling_2->SetScrollParent(scroller.get()); - scroll_sibling_1->SetScrollParent(scroller.get()); - } - clip_escaper->SetClipParent(scroll_sibling_1.get()); - - ExecuteCalculateDrawProperties(root.get()); - - EXPECT_EQ(scroll_sibling_1->clip_tree_index(), - clip_escaper->clip_tree_index()); - } -} - -TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTrilinearFiltering) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); + ImplOf(cache_render_surface_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), + ImplOf(copy_clipped_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), ImplOf(cache_surface)->visible_layer_rect()); +} + +// Needs layer tree mode: testing PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RenderSurfaceListForTrilinearFiltering) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); gfx::Transform scale_matrix; scale_matrix.Scale(.25f, .25f); root->SetBounds(gfx::Size(200, 200)); - parent->test_properties()->transform = scale_matrix; - parent->test_properties()->trilinear_filtering = true; + parent->SetTransform(scale_matrix); + parent->SetTrilinearFiltering(true); child1->SetBounds(gfx::Size(50, 50)); - child1->SetDrawsContent(true); - child1->test_properties()->force_render_surface = true; - child2->test_properties()->position = gfx::PointF(50, 50); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(50, 50)); child2->SetBounds(gfx::Size(50, 50)); - child2->SetDrawsContent(true); - child2->test_properties()->force_render_surface = true; + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + CommitAndActivate(); - ASSERT_TRUE(GetRenderSurface(parent)); - EXPECT_EQ(2, GetRenderSurface(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list.size()); + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, render_surface_list_impl()->size()); // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the // scale matrix to (0,0 25x25). EXPECT_EQ(gfx::RectF(0, 0, 25, 25), - GetRenderSurface(parent)->DrawableContentRect()); + GetRenderSurfaceImpl(parent)->DrawableContentRect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectClippedByViewport) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - gfx::Size root_layer_size = gfx::Size(300, 500); - gfx::Size device_viewport_size = gfx::Size(300, 600); - gfx::Rect viewport_visible_rect = gfx::Rect(100, 100, 200, 200); - - host_impl.active_tree()->SetDeviceViewportSize(device_viewport_size); - host_impl.active_tree()->SetViewportVisibleRect(viewport_visible_rect); - host_impl.active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl.active_tree(), 1)); - - LayerImpl* root = host_impl.active_tree()->root_layer_for_testing(); - root->SetBounds(root_layer_size); - root->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); - - EXPECT_EQ(viewport_visible_rect, root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(root_layer_size), root->drawable_content_rect()); -} - -TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, RoundedCornerBounds) { // Layer Tree: // +root // +--render surface @@ -10565,13 +9410,9 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. - const EffectNode* effect_node = - effect_tree.Node(rounded_corner_layer_1->effect_tree_index()); + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), @@ -10581,7 +9422,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { // Since this node has descendants with roudned corners, it needs a render // surface. It also has 2 descendants that draw. - effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_2.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), @@ -10591,7 +9432,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { // Since this node has a descendant that has a rounded corner, it will trigger // the creation of a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_3.get()); gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), @@ -10601,7 +9442,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { // Since this node has no descendants that draw nor any descendant that has a // rounded corner, it does not need a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_4->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_4.get()); gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), @@ -10701,7 +9542,9 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBounds) { kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale); } -TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RoundedCornerBoundsInterveningRenderTarget) { // Layer Tree: // +root // +--rounded corner layer 1 [should not trigger render surface] @@ -10759,14 +9602,10 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this effect node has only 1 descendant that draws and no descendant // that has a rounded corner before the render surface, it does not need a // render surface. - const EffectNode* effect_node = - effect_tree.Node(rounded_corner_layer_1->effect_tree_index()); + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), @@ -10776,7 +9615,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) { // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_2.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), @@ -10829,7 +9668,9 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsInterveningRenderTarget) { kRoundedCorner2Radius * kDeviceScale); } -TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + RoundedCornerBoundsSiblingRenderTarget) { // Layer Tree: // +root // +--rounded corner layer 1 [should trigger render surface] @@ -10887,13 +9728,9 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this effect node has 1 descendant with a rounded corner without a // render surface along the chain, it need a render surface. - const EffectNode* effect_node = - effect_tree.Node(rounded_corner_layer_1->effect_tree_index()); + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), @@ -10903,7 +9740,7 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) { // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_2.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), @@ -10960,7 +9797,9 @@ TEST_F(LayerTreeHostCommonTest, RoundedCornerBoundsSiblingRenderTarget) { kRoundedCorner2Radius * kDeviceScale); } -TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + FastRoundedCornerDoesNotTriggerRenderSurface) { // Layer Tree: // +root // +--fast rounded corner layer [should not trigger render surface] @@ -11038,13 +9877,10 @@ TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this layer has a fast rounded corner, it should not have a render // surface even though it has 2 layers in the subtree that draws content. const EffectNode* effect_node = - effect_tree.Node(fast_rounded_corner_layer->effect_tree_index()); + GetEffectNode(fast_rounded_corner_layer.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_TRUE(effect_node->is_fast_rounded_corner); @@ -11054,7 +9890,7 @@ TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) { gfx::RectF(kRoundedCornerLayer1Bound.size())); // Since this node has 2 descendants that draw, it will have a rounded corner. - effect_node = effect_tree.Node(rounded_corner_layer->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11136,7 +9972,8 @@ TEST_F(LayerTreeHostCommonTest, FastRoundedCornerDoesNotTriggerRenderSurface) { EXPECT_TRUE(layer_4_rrect.IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, FastRoundedCornerTriggersRenderSurfaceInAncestor) { // Layer Tree: // +root @@ -11215,13 +10052,9 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this layer has a descendant that has rounded corner, this node will // require a render surface. - const EffectNode* effect_node = - effect_tree.Node(rounded_corner_layer_1->effect_tree_index()); + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11232,8 +10065,7 @@ TEST_F(LayerTreeHostCommonTest, // Since this layer has no descendant with rounded corner or drawable, it will // not have a render surface. - effect_node = - effect_tree.Node(fast_rounded_corner_layer_2->effect_tree_index()); + effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_TRUE(effect_node->is_fast_rounded_corner); @@ -11244,7 +10076,7 @@ TEST_F(LayerTreeHostCommonTest, // Since this layer has 1 descendant with a rounded corner, it should have a // render surface. - effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_3.get()); gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11254,7 +10086,7 @@ TEST_F(LayerTreeHostCommonTest, gfx::RectF(kRoundedCornerLayer3Bound.size())); // Since this layer no descendants, it would no thave a render pass. - effect_node = effect_tree.Node(rounded_corner_layer_4->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_4.get()); gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11346,7 +10178,8 @@ TEST_F(LayerTreeHostCommonTest, kRoundedCorner4Radius * kDeviceScale); } -TEST_F(LayerTreeHostCommonTest, +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) { // Layer Tree: // +root @@ -11423,13 +10256,10 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const EffectTree& effect_tree = - root->layer_tree_host()->property_trees()->effect_tree; - // Since this layer has a descendant with rounded corner, it needs a render // surface. const EffectNode* effect_node = - effect_tree.Node(fast_rounded_corner_layer_1->effect_tree_index()); + GetEffectNode(fast_rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_TRUE(effect_node->is_fast_rounded_corner); @@ -11440,7 +10270,7 @@ TEST_F(LayerTreeHostCommonTest, // Since this layer has no descendant with rounded corner or drawable, it will // not have a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_1->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_1.get()); gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11451,7 +10281,7 @@ TEST_F(LayerTreeHostCommonTest, // Since this layer has a descendant with rounded corner, it should have a // render surface. - effect_node = effect_tree.Node(rounded_corner_layer_2->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_2.get()); gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11461,7 +10291,7 @@ TEST_F(LayerTreeHostCommonTest, gfx::RectF(kRoundedCornerLayer3Bound.size())); // Since this layer has no descendant, it does not need a render surface. - effect_node = effect_tree.Node(rounded_corner_layer_3->effect_tree_index()); + effect_node = GetEffectNode(rounded_corner_layer_3.get()); gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FALSE(effect_node->is_fast_rounded_corner); @@ -11554,7 +10384,8 @@ TEST_F(LayerTreeHostCommonTest, kRoundedCorner4Radius * kDeviceScale); } -TEST_F(LayerTreeHostCommonTest, CustomLayerClipBounds) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -11624,15 +10455,10 @@ TEST_F(LayerTreeHostCommonTest, CustomLayerClipBounds) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const ClipTree& clip_tree = - root->layer_tree_host()->property_trees()->clip_tree; - - const ClipNode* parent_clip_node = clip_tree.Node(parent->clip_tree_index()); - EXPECT_EQ(parent_clip_node->clip, gfx::RectF(kClipBounds)); + EXPECT_EQ(GetClipNode(parent.get())->clip, gfx::RectF(kClipBounds)); EXPECT_TRUE(!parent->clip_rect().IsEmpty()); - const ClipNode* child_clip_node = clip_tree.Node(child->clip_tree_index()); - EXPECT_EQ(child_clip_node->clip, gfx::RectF(kClipBounds)); + EXPECT_EQ(GetClipNode(child.get())->clip, gfx::RectF(kClipBounds)); host()->host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); @@ -11663,7 +10489,9 @@ TEST_F(LayerTreeHostCommonTest, CustomLayerClipBounds) { EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, CustomLayerClipBoundsWithMaskToBounds) { +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(LayerTreeHostCommonTestWithLayerTree, + CustomLayerClipBoundsWithMaskToBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -11737,17 +10565,12 @@ TEST_F(LayerTreeHostCommonTest, CustomLayerClipBoundsWithMaskToBounds) { ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - const ClipTree& clip_tree = - root->layer_tree_host()->property_trees()->clip_tree; - - const ClipNode* parent_clip_node = clip_tree.Node(parent->clip_tree_index()); const gfx::RectF expected_clip_bounds = gfx::IntersectRects( gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds)); - EXPECT_EQ(parent_clip_node->clip, expected_clip_bounds); + EXPECT_EQ(GetClipNode(parent.get())->clip, expected_clip_bounds); EXPECT_TRUE(!parent->clip_rect().IsEmpty()); - const ClipNode* child_clip_node = clip_tree.Node(child->clip_tree_index()); - EXPECT_EQ(child_clip_node->clip, expected_clip_bounds); + EXPECT_EQ(GetClipNode(child.get())->clip, expected_clip_bounds); host()->host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 0585a41551c..49112276c53 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -51,6 +51,9 @@ #include "cc/layers/scrollbar_layer_impl_base.h" #include "cc/layers/surface_layer_impl.h" #include "cc/layers/viewport.h" +#include "cc/metrics/compositor_frame_reporting_controller.h" +#include "cc/paint/display_item_list.h" +#include "cc/paint/paint_worklet_job.h" #include "cc/paint/paint_worklet_layer_painter.h" #include "cc/raster/bitmap_raster_buffer_provider.h" #include "cc/raster/gpu_raster_buffer_provider.h" @@ -61,7 +64,6 @@ #include "cc/resources/memory_history.h" #include "cc/resources/resource_pool.h" #include "cc/resources/ui_resource_bitmap.h" -#include "cc/scheduler/compositor_frame_reporting_controller.h" #include "cc/tiles/eviction_tile_priority_queue.h" #include "cc/tiles/frame_viewer_instrumentation.h" #include "cc/tiles/gpu_image_decode_cache.h" @@ -175,49 +177,6 @@ viz::ResourceFormat TileRasterBufferFormat( return viz::PlatformColor::BestSupportedTextureFormat(caps); } -// Small helper class that saves the current viewport location as the user sees -// it and resets to the same location. -class ViewportAnchor { - public: - ViewportAnchor(ScrollNode* inner_scroll, - LayerImpl* outer_scroll, - LayerTreeImpl* tree_impl) - : inner_(inner_scroll), outer_(outer_scroll), tree_impl_(tree_impl) { - viewport_in_content_coordinates_ = - scroll_tree().current_scroll_offset(inner_->element_id); - - if (outer_) - viewport_in_content_coordinates_ += outer_->CurrentScrollOffset(); - } - - void ResetViewportToAnchoredPosition() { - DCHECK(outer_); - - scroll_tree().ClampScrollToMaxScrollOffset(inner_, tree_impl_); - outer_->ClampScrollToMaxScrollOffset(); - - gfx::ScrollOffset viewport_location = - scroll_tree().current_scroll_offset(inner_->element_id) + - outer_->CurrentScrollOffset(); - - gfx::Vector2dF delta = - viewport_in_content_coordinates_.DeltaFrom(viewport_location); - - delta = scroll_tree().ScrollBy(inner_, delta, tree_impl_); - outer_->ScrollBy(delta); - } - - private: - ScrollTree& scroll_tree() { - return tree_impl_->property_trees()->scroll_tree; - } - - ScrollNode* inner_; - LayerImpl* outer_; - LayerTreeImpl* tree_impl_; - gfx::ScrollOffset viewport_in_content_coordinates_; -}; - void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { if (visible) { TRACE_EVENT_ASYNC_BEGIN1("cc", "LayerTreeHostImpl::SetVisible", id, @@ -360,6 +319,7 @@ LayerTreeHostImpl::LayerTreeHostImpl( is_animating_for_snap_(false), paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()), scrollbar_controller_(std::make_unique<ScrollbarController>(this)), + frame_trackers_(compositor_frame_reporting_controller_.get()), scroll_gesture_did_end_(false) { DCHECK(mutator_host_); mutator_host_->SetMutatorHostClient(this); @@ -485,6 +445,15 @@ void LayerTreeHostImpl::CommitComplete() { ActivateAnimations(); } + // We clear the entries that were never mutated by CC animations from the last + // commit until now. Moreover, we reset the values of input properties and + // relies on the fact that CC animation will mutate those values when pending + // tree is animated below. + // With that, when CC finishes animating an input property, the value of that + // property stays at finish state until a commit kicks in, which is consistent + // with current composited animations. + paint_worklet_tracker_.ClearUnusedInputProperties(); + // Start animations before UpdateDrawProperties and PrepareTiles, as they can // change the results. When doing commit to the active tree, this must happen // after ActivateAnimations() in order for this ticking to be propogated @@ -497,15 +466,11 @@ void LayerTreeHostImpl::CommitComplete() { UpdateSyncTreeAfterCommitOrImplSideInvalidation(); micro_benchmark_controller_.DidCompleteCommit(); - if (mutator_host_->CurrentFrameHadRAF() && - !request_animation_frame_tracker_) { - request_animation_frame_tracker_ = - frame_trackers_.CreateTracker(FrameSequenceTrackerType::kRAF); - } + if (mutator_host_->CurrentFrameHadRAF()) + frame_trackers_.StartSequence(FrameSequenceTrackerType::kRAF); - if (mutator_host_->MainThreadAnimationsCount() > 0 && - !main_thread_animation_frame_tracker_) { - main_thread_animation_frame_tracker_ = frame_trackers_.CreateTracker( + if (mutator_host_->MainThreadAnimationsCount() > 0) { + frame_trackers_.StartSequence( FrameSequenceTrackerType::kMainThreadAnimation); } } @@ -544,6 +509,27 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { const auto& animated_images = image_animation_controller_.AnimateForSyncTree(CurrentBeginFrameArgs()); images_to_invalidate.insert(animated_images.begin(), animated_images.end()); + + // Invalidate cached PaintRecords for worklets whose input properties were + // mutated since the last pending tree. We keep requesting invalidations until + // the animation is ticking on impl thread. Note that this works since the + // animation starts ticking on the pending tree + // (AnimatePendingTreeAfterCommit) which committed this animation timeline. + // After this the animation may only tick on the active tree for impl-side + // invalidations (since AnimatePendingTreeAfterCommit is not done for pending + // trees created by impl-side invalidations). But we ensure here that we + // request another invalidation if an input property was mutated on the active + // tree. + if (paint_worklet_tracker_.InvalidatePaintWorkletsOnPendingTree()) { + client_->NeedsImplSideInvalidation( + true /* needs_first_draw_on_activation */); + } + PaintImageIdFlatSet dirty_paint_worklet_ids; + PaintWorkletJobMap dirty_paint_worklets = + GatherDirtyPaintWorklets(&dirty_paint_worklet_ids); + images_to_invalidate.insert(dirty_paint_worklet_ids.begin(), + dirty_paint_worklet_ids.end()); + sync_tree()->InvalidateRegionForImages(images_to_invalidate); // Note that it is important to push the state for checkerboarded and animated @@ -563,7 +549,6 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { return; } - PaintWorkletJobMap dirty_paint_worklets = GatherDirtyPaintWorklets(); if (!dirty_paint_worklets.size()) { pending_tree_fully_painted_ = true; NotifyPendingTreeFullyPainted(); @@ -578,33 +563,60 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { std::move(done_callback)); } -PaintWorkletJobMap LayerTreeHostImpl::GatherDirtyPaintWorklets() const { +PaintWorkletJobMap LayerTreeHostImpl::GatherDirtyPaintWorklets( + PaintImageIdFlatSet* dirty_paint_worklet_ids) const { PaintWorkletJobMap dirty_paint_worklets; for (PictureLayerImpl* layer : sync_tree()->picture_layers_with_paint_worklets()) { for (const auto& entry : layer->GetPaintWorkletRecordMap()) { + const scoped_refptr<const PaintWorkletInput>& input = entry.first; + const PaintImage::Id& paint_image_id = entry.second.first; + const sk_sp<PaintRecord>& record = entry.second.second; // If we already have a record we can reuse it and so the // PaintWorkletInput isn't dirty. - if (entry.second) + if (record) continue; - int id = entry.first->WorkletId(); - auto result = dirty_paint_worklets.insert( - std::make_pair(id, scoped_refptr<PaintWorkletJobVector>{})); - scoped_refptr<PaintWorkletJobVector>& job_vector = result.first->second; + // Mark this PaintWorklet as needing invalidation. + dirty_paint_worklet_ids->insert(paint_image_id); + + // Create an entry in the appropriate PaintWorkletJobVector for this dirty + // PaintWorklet. + int worklet_id = input->WorkletId(); + auto& job_vector = dirty_paint_worklets[worklet_id]; if (!job_vector) - job_vector = base::WrapRefCounted(new PaintWorkletJobVector); - job_vector->data.emplace_back(layer->id(), entry.first); + job_vector = base::MakeRefCounted<PaintWorkletJobVector>(); + + PaintWorkletJob::AnimatedPropertyValues animated_property_values; + for (const auto& element : input->GetPropertyKeys()) { + // We should not have multiple property ids with the same name. + DCHECK(!animated_property_values.contains(element.first)); + const PaintWorkletInput::PropertyValue& animated_property_value = + paint_worklet_tracker_.GetPropertyAnimationValue(element); + // No value indicates that the input property was not mutated by CC + // animation. + if (animated_property_value.has_value()) { + animated_property_values.emplace(element.first, + animated_property_value); + } + } + + job_vector->data.emplace_back(layer->id(), input, + std::move(animated_property_values)); } } return dirty_paint_worklets; } void LayerTreeHostImpl::OnPaintWorkletResultsReady(PaintWorkletJobMap results) { +#if DCHECK_IS_ON() // Nothing else should have painted the PaintWorklets while we were waiting, // and the results should have painted every PaintWorklet, so these should be // the same. - DCHECK_EQ(results.size(), GatherDirtyPaintWorklets().size()); + PaintImageIdFlatSet dirty_paint_worklet_ids; + DCHECK_EQ(results.size(), + GatherDirtyPaintWorklets(&dirty_paint_worklet_ids).size()); +#endif for (const auto& entry : results) { for (const PaintWorkletJob& job : entry.second->data) { @@ -1043,7 +1055,6 @@ DrawMode LayerTreeHostImpl::GetDrawMode() const { } static void AppendQuadsToFillScreen( - const gfx::Rect& root_scroll_layer_rect, viz::RenderPass* target_render_pass, const RenderSurfaceImpl* root_render_surface, SkColor screen_background_color, @@ -1225,6 +1236,9 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { active_tree()->property_trees()->effect_tree.HasCopyRequests(); bool have_missing_animated_tiles = false; + // Advance our de-jelly state. This is a no-op if de-jelly is not active. + de_jelly_state_.AdvanceFrame(active_tree_.get()); + for (EffectTreeLayerListIterator it(active_tree()); it.state() != EffectTreeLayerListIterator::State::END; ++it) { auto target_render_pass_id = it.target_render_surface()->id(); @@ -1248,6 +1262,11 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { if (render_surface->contributes_to_drawn_surface()) { render_surface->AppendQuads(draw_mode, target_render_pass, &append_quads_data); + if (settings_.allow_de_jelly_effect) { + de_jelly_state_.UpdateSharedQuadState( + active_tree_.get(), render_surface->TransformTreeIndex(), + target_render_pass); + } } } else if (it.state() == EffectTreeLayerListIterator::State::LAYER) { LayerImpl* layer = it.current_layer(); @@ -1259,6 +1278,11 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { frame->may_contain_video = true; layer->AppendQuads(target_render_pass, &append_quads_data); + if (settings_.allow_de_jelly_effect) { + de_jelly_state_.UpdateSharedQuadState(active_tree_.get(), + layer->transform_tree_index(), + target_render_pass); + } } rendering_stats_instrumentation_->AddVisibleContentArea( @@ -1298,7 +1322,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { } frame->use_default_lower_bound_deadline |= append_quads_data.use_default_lower_bound_deadline; - frame->mirror_rect.Union(append_quads_data.mirror_rect); } // If CommitToActiveTree() is true, then we wait to draw until @@ -1329,16 +1352,25 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { for (auto* quad : render_pass->quad_list) DCHECK(quad->shared_quad_state); } - DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin()); + DCHECK_EQ(frame->render_passes.back()->output_rect.origin(), + active_tree_->GetDeviceViewport().origin()); #endif bool has_transparent_background = SkColorGetA(active_tree_->background_color()) != SK_AlphaOPAQUE; - if (!has_transparent_background) { + auto* root_render_surface = active_tree_->RootRenderSurface(); + if (root_render_surface && !has_transparent_background) { frame->render_passes.back()->has_transparent_background = false; - AppendQuadsToFillScreen( - active_tree_->RootScrollLayerDeviceViewportBounds(), - frame->render_passes.back().get(), active_tree_->RootRenderSurface(), - active_tree_->background_color(), unoccluded_screen_space_region); + + // If any tiles are missing, then fill behind the entire root render + // surface. This is a workaround for this edge case, instead of tracking + // individual tiles that are missing. + Region fill_region = unoccluded_screen_space_region; + if (num_missing_tiles > 0) + fill_region = root_render_surface->content_rect(); + + AppendQuadsToFillScreen(frame->render_passes.back().get(), + root_render_surface, + active_tree_->background_color(), fill_region); } RemoveRenderPasses(frame); @@ -1354,6 +1386,9 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { active_tree()->set_needs_update_draw_properties(); } + frame->has_missing_content = + num_missing_tiles > 0 || num_incomplete_tiles > 0; + if (ukm_manager_) { ukm_manager_->AddCheckerboardStatsForFrame( checkerboarded_no_recording_content_area + @@ -2017,6 +2052,10 @@ void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform, bool resourceless_software_draw, bool skip_draw) { DCHECK(!resourceless_software_draw_); + // This function is only ever called by Android WebView, in which case we + // expect the device viewport to be at the origin. We never expect an + // external viewport to be set otherwise. + DCHECK(active_tree_->internal_device_viewport().origin().IsOrigin()); if (skip_draw) { client_->OnDrawForLayerTreeFrameSink(resourceless_software_draw_, true); @@ -2104,36 +2143,12 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() { child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() .allocation_time(); -#if defined(OS_ANDROID) - metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); - metadata.root_layer_size = active_tree_->ScrollableSize(); - - if (const auto* outer_viewport_scroll_node = OuterViewportScrollNode()) { - metadata.root_overflow_y_hidden = - !outer_viewport_scroll_node->user_scrollable_vertical; + if (InnerViewportScrollNode()) { + // TODO(miletus) : Change the metadata to hold ScrollOffset. + metadata.root_scroll_offset = + gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset()); } - metadata.bottom_controls_height = - browser_controls_offset_manager_->BottomControlsHeight(); - metadata.bottom_controls_shown_ratio = - browser_controls_offset_manager_->BottomControlsShownRatio(); - - active_tree_->GetViewportSelection(&metadata.selection); -#endif - - const auto* inner_viewport_scroll_node = InnerViewportScrollNode(); - if (!inner_viewport_scroll_node) - return metadata; - -#if defined(OS_ANDROID) - metadata.root_overflow_y_hidden |= - !inner_viewport_scroll_node->user_scrollable_vertical; -#endif - - // TODO(miletus) : Change the metadata to hold ScrollOffset. - metadata.root_scroll_offset = - gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset()); - return metadata; } @@ -2238,19 +2253,15 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { std::move(compositor_frame), /*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders); - frame_trackers_.NotifySubmitFrame(compositor_frame.metadata.frame_token, - frame->begin_frame_ack, - frame->origin_begin_main_frame_args); - if (request_animation_frame_tracker_ && - !mutator_host_->NextFrameHasPendingRAF()) { - frame_trackers_.ScheduleRemoval( - std::move(request_animation_frame_tracker_)); - } + frame_trackers_.NotifySubmitFrame( + compositor_frame.metadata.frame_token, frame->has_missing_content, + frame->begin_frame_ack, frame->origin_begin_main_frame_args); + if (!mutator_host_->NextFrameHasPendingRAF()) + frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF); - if (main_thread_animation_frame_tracker_ && - mutator_host_->MainThreadAnimationsCount() == 0) { - frame_trackers_.ScheduleRemoval( - std::move(main_thread_animation_frame_tracker_)); + if (mutator_host_->MainThreadAnimationsCount() == 0) { + frame_trackers_.StopSequence( + FrameSequenceTrackerType::kMainThreadAnimation); } // Clears the list of swap promises after calling DidSwap on each of them to @@ -2382,8 +2393,6 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( frame->begin_frame_ack.sequence_number); metadata.begin_frame_ack = frame->begin_frame_ack; - metadata.mirror_rect = frame->mirror_rect; - viz::CompositorFrame compositor_frame; compositor_frame.metadata = std::move(metadata); resource_provider_.PrepareSendToParent( @@ -2677,107 +2686,6 @@ void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) { layer_tree_frame_sink_->DidNotProduceFrame(ack); } -void LayerTreeHostImpl::UpdateViewportContainerSizes() { - if (!InnerViewportScrollNode()) - return; - - ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollLayer(), - active_tree_.get()); - - float top_controls_layout_height = - active_tree_->browser_controls_shrink_blink_size() - ? active_tree_->top_controls_height() - : 0.f; - float delta_from_top_controls = - top_controls_layout_height - - browser_controls_offset_manager_->ContentTopOffset(); - float bottom_controls_layout_height = - active_tree_->browser_controls_shrink_blink_size() - ? active_tree_->bottom_controls_height() - : 0.f; - delta_from_top_controls += - bottom_controls_layout_height - - browser_controls_offset_manager_->ContentBottomOffset(); - - // Adjust the viewport layers by shrinking/expanding the container to account - // for changes in the size (e.g. browser controls) since the last resize from - // Blink. - auto* property_trees = active_tree_->property_trees(); - gfx::Vector2dF bounds_delta(0.f, delta_from_top_controls); - if (property_trees->inner_viewport_container_bounds_delta() == bounds_delta) - return; - - property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta); - - ClipNode* inner_clip_node = property_trees->clip_tree.Node( - InnerViewportScrollLayer()->clip_tree_index()); - inner_clip_node->clip.set_height( - InnerViewportScrollNode()->container_bounds.height() + bounds_delta.y()); - - // Adjust the outer viewport container as well, since adjusting only the - // inner may cause its bounds to exceed those of the outer, causing scroll - // clamping. - if (OuterViewportScrollNode()) { - gfx::Vector2dF scaled_bounds_delta = gfx::ScaleVector2d( - bounds_delta, 1.f / active_tree_->min_page_scale_factor()); - - property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta); - property_trees->SetInnerViewportScrollBoundsDelta(scaled_bounds_delta); - - ClipNode* outer_clip_node = property_trees->clip_tree.Node( - OuterViewportScrollLayer()->clip_tree_index()); - - float adjusted_container_height = - OuterViewportScrollNode()->container_bounds.height() + - scaled_bounds_delta.y(); - - // TODO(bokan): The clip node bounds for the outer viewport are incorrectly - // computed pre-Blink-Gen-Property-Trees: they assume the outer viewport is - // the same size as the inner viewport. In reality, the outer viewport is - // sized such that it equals the inner viewport when at minimum page scale. - // This happens on mobile when a page doesn't have a |width=device-width| - // viewport meta tag (e.g. legacy desktop page). Thus, we must scale - // the container height and its adjustment to match the incorrect space of - // the clip node. https://crbug.com/901083, https://crbug.com/961649. - // Note: we don't fix this in the property tree builder since that code - // path is going away and it's not clear whether it depends on ClipNode - // being in this coordinate space pre-BGPT. - if (!settings().use_layer_lists) - adjusted_container_height *= active_tree_->min_page_scale_factor(); - - outer_clip_node->clip.set_height(adjusted_container_height); - - // Expand all clips between the outer viewport and the inner viewport. - auto* outer_ancestor = property_trees->clip_tree.parent(outer_clip_node); - while (outer_ancestor && outer_ancestor != inner_clip_node) { - outer_ancestor->clip.Union(outer_clip_node->clip); - outer_ancestor = property_trees->clip_tree.parent(outer_ancestor); - } - - anchor.ResetViewportToAnchoredPosition(); - } - - property_trees->clip_tree.set_needs_update(true); - property_trees->full_tree_damaged = true; - active_tree_->set_needs_update_draw_properties(); - - // Viewport scrollbar positions are determined using the viewport bounds - // delta. - active_tree_->SetScrollbarGeometriesNeedUpdate(); - active_tree_->set_needs_update_draw_properties(); - - // For pre-BlinkGenPropertyTrees mode, we need to ensure the layers are - // appropriately updated. - if (!settings().use_layer_lists) { - if (OuterViewportContainerLayer()) - OuterViewportContainerLayer()->NoteLayerPropertyChanged(); - if (InnerViewportScrollLayer()) - InnerViewportScrollLayer()->NoteLayerPropertyChanged(); - if (OuterViewportScrollLayer()) - OuterViewportScrollLayer()->NoteLayerPropertyChanged(); - } -} - void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() { // Only valid for the single-threaded non-scheduled/synchronous case // using the zero copy raster worker pool. @@ -3113,7 +3021,7 @@ void LayerTreeHostImpl::ActivateSyncTree() { active_tree_->ProcessUIResourceRequestQueue(); } - UpdateViewportContainerSizes(); + active_tree_->UpdateViewportContainerSizes(); if (InnerViewportScrollNode()) { active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset( @@ -3228,12 +3136,6 @@ void LayerTreeHostImpl::SetVisible(bool visible) { SetFullViewportDamage(); SetNeedsRedraw(); } - // If surface synchronization is off, force allocating a new LocalSurfaceId - // because the previous LocalSurfaceId might have been evicted while we were - // invisible. When surface synchronization is on, the embedder will pass us - // a new LocalSurfaceID. - if (layer_tree_frame_sink_ && !settings_.enable_surface_synchronization) - layer_tree_frame_sink_->ForceAllocateNewId(); } else { EvictAllUIResources(); // Call PrepareTiles to evict tiles when we become invisible. @@ -3518,11 +3420,6 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() { bool all_resources_are_lost = layer_tree_frame_sink_->context_provider(); // Destroy the submit-frame trackers before destroying the frame sink. - pinch_frame_tracker_ = nullptr; - scroll_frame_tracker_ = nullptr; - compositor_animation_frame_tracker_ = nullptr; - request_animation_frame_tracker_ = nullptr; - main_thread_animation_frame_tracker_ = nullptr; frame_trackers_.ClearAll(); // Detach from the old LayerTreeFrameSink and reset |layer_tree_frame_sink_| @@ -3634,14 +3531,10 @@ bool LayerTreeHostImpl::InitializeFrameSink( // Always allocate a new viz::LocalSurfaceId when we get a new // LayerTreeFrameSink to ensure that we do not reuse the same surface after // it might have been garbage collected. - if (settings_.enable_surface_synchronization) { - const viz::LocalSurfaceIdAllocation& local_surface_id_allocation = - child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); - if (local_surface_id_allocation.IsValid()) - AllocateLocalSurfaceId(); - } else { - layer_tree_frame_sink_->ForceAllocateNewId(); - } + const viz::LocalSurfaceIdAllocation& local_surface_id_allocation = + child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); + if (local_surface_id_allocation.IsValid()) + AllocateLocalSurfaceId(); return true; } @@ -3655,10 +3548,11 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { } void LayerTreeHostImpl::DidChangeBrowserControlsPosition() { - UpdateViewportContainerSizes(); + active_tree_->UpdateViewportContainerSizes(); + if (pending_tree_) + pending_tree_->UpdateViewportContainerSizes(); SetNeedsRedraw(); SetNeedsOneBeginImplFrame(); - active_tree_->set_needs_update_draw_properties(); SetFullViewportDamage(); } @@ -3737,9 +3631,13 @@ InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll( return scroll_status; } + // The outer viewport should be scrolled even if it has no scroll extent + // since it'll scroll using the Viewport class which will generate browser + // controls movement and overscroll delta. gfx::ScrollOffset max_scroll_offset = scroll_tree.MaxScrollOffset(scroll_node->id); - if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { + if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0 && + !scroll_node->scrolls_outer_viewport) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollable," " but has no affordance in either direction."); @@ -3837,28 +3735,53 @@ ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint( } } - // Falling back to the viewport layer ensures generation of root overscroll - // notifications. We use the viewport's main scroll layer to represent the - // viewport in scrolling code. - bool scrolls_inner_viewport = - impl_scroll_node && impl_scroll_node->scrolls_inner_viewport; - bool scrolls_outer_viewport = - impl_scroll_node && impl_scroll_node->scrolls_outer_viewport; - if (!impl_scroll_node || scrolls_inner_viewport || scrolls_outer_viewport) + // TODO(bokan): We shouldn't need this - ordinarily all scrolls should pass + // through the outer viewport. If we aren't able to find a scroller we should + // return nullptr here and ignore the scroll. However, it looks like on some + // pages (reddit.com) we start scrolling from the inner node. + if (!impl_scroll_node) + impl_scroll_node = InnerViewportScrollNode(); + + if (!impl_scroll_node) + return nullptr; + + // Blink has a notion of a "root scroller", which is the scroller in a page + // that is considered to host the main content. Typically this will be the + // document/LayoutView contents; however, in some situations Blink may choose + // a sub-scroller (div, iframe) that should scroll with "viewport" behavior. + // The "root scroller" is the node designated as the outer viewport in CC. + // See third_party/blink/renderer/core/page/scrolling/README.md for details. + // + // "Viewport" scrolling ensures generation of overscroll events, top controls + // movement, as well as correct multi-viewport panning in pinch-zoom and + // other scenarios. We use the viewport's outer scroll node to represent the + // viewport in the scroll chain and apply scroll delta using CC's Viewport + // class. + // + // Scrolling from position: fixed layers will chain directly up to the inner + // viewport. Whether that should use the outer viewport (and thus the + // Viewport class) to scroll or not depends on the root scroller scenario + // because we don't want setting a root scroller to change the scroll chain + // order. The |prevent_viewport_scrolling_from_inner| bit is used to + // communicate that context. + DCHECK(!impl_scroll_node->prevent_viewport_scrolling_from_inner || + impl_scroll_node->scrolls_inner_viewport); + bool should_use_viewport = + OuterViewportScrollNode() && impl_scroll_node->scrolls_inner_viewport && + !impl_scroll_node->prevent_viewport_scrolling_from_inner; + if (should_use_viewport) impl_scroll_node = OuterViewportScrollNode(); - if (impl_scroll_node) { - // Ensure that final layer scrolls on impl thread (crbug.com/625100) - ScrollStatus status = - TryScroll(device_viewport_point, scroll_tree, impl_scroll_node); - if (IsMainThreadScrolling(status, impl_scroll_node)) { - *scroll_on_main_thread = true; - *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; - } else if (non_fast_scrollable_nodes.contains(impl_scroll_node->id)) { - *scroll_on_main_thread = true; - *main_thread_scrolling_reasons = - MainThreadScrollingReason::kNonFastScrollableRegion; - } + // Ensure that final scroll node scrolls on impl thread (crbug.com/625100) + ScrollStatus status = + TryScroll(device_viewport_point, scroll_tree, impl_scroll_node); + if (IsMainThreadScrolling(status, impl_scroll_node)) { + *scroll_on_main_thread = true; + *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; + } else if (non_fast_scrollable_nodes.contains(impl_scroll_node->id)) { + *scroll_on_main_thread = true; + *main_thread_scrolling_reasons = + MainThreadScrollingReason::kNonFastScrollableRegion; } return impl_scroll_node; @@ -3902,6 +3825,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( // in input_handler_proxy instead. touch_scrolling_ = type == InputHandler::TOUCHSCREEN; wheel_scrolling_ = type == InputHandler::WHEEL; + middle_click_autoscrolling_ = type == InputHandler::AUTOSCROLL; scroll_state->set_is_direct_manipulation(touch_scrolling_); // Invoke |DistributeScrollDelta| even with zero delta and velocity to ensure // scroll customization callbacks are invoked. @@ -3926,9 +3850,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( scroll_status.bubble = true; } - scroll_frame_tracker_ = frame_trackers_.CreateTracker( - wheel_scrolling_ ? FrameSequenceTrackerType::kWheelScroll - : FrameSequenceTrackerType::kTouchScroll); + frame_trackers_.StartSequence(wheel_scrolling_ + ? FrameSequenceTrackerType::kWheelScroll + : FrameSequenceTrackerType::kTouchScroll); client_->RenewTreePriority(); RecordCompositorSlowScrollMetric(type, CC_THREAD); @@ -4014,9 +3938,18 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( } } - scrolling_node = FindScrollNodeForDeviceViewportPoint( - device_viewport_point, layer_impl, &scroll_on_main_thread, - &scroll_status.main_thread_scrolling_reasons); + ElementId current_native_scrolling_element = + scroll_state->data()->current_native_scrolling_element(); + if (current_native_scrolling_element.GetInternalValue() != 0) { + auto& scroll_tree = active_tree_->property_trees()->scroll_tree; + scrolling_node = + scroll_tree.FindNodeFromElementId(current_native_scrolling_element); + did_lock_scrolling_layer_ = true; + } else { + scrolling_node = FindScrollNodeForDeviceViewportPoint( + device_viewport_point, layer_impl, &scroll_on_main_thread, + &scroll_status.main_thread_scrolling_reasons); + } } if (scroll_on_main_thread) { @@ -4075,10 +4008,12 @@ bool LayerTreeHostImpl::IsInitialScrollHitTestReliable( scroll_node = scroll_tree.parent(scroll_node)) { if (scroll_node->scrollable) { // Ensure we use scroll chaining behavior for the inner viewport node. - if (viewport()->ShouldScroll(*scroll_node)) + if (scroll_node->scrolls_inner_viewport && + !scroll_node->prevent_viewport_scrolling_from_inner) { closest_scroll_node = viewport()->MainScrollNode(); - else + } else { closest_scroll_node = scroll_node; + } break; } } @@ -4333,11 +4268,10 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( break; } - gfx::Vector2dF scroll_delta = - ComputeScrollDelta(*scroll_node, pending_delta); - if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) { - did_scroll_x_for_scroll_gesture_ |= scroll_delta.x() != 0; - did_scroll_y_for_scroll_gesture_ |= scroll_delta.y() != 0; + gfx::Vector2dF delta = ComputeScrollDelta(*scroll_node, pending_delta); + if (ScrollAnimationCreate(scroll_node, delta, delayed_by)) { + did_scroll_x_for_scroll_gesture_ |= delta.x() != 0; + did_scroll_y_for_scroll_gesture_ |= delta.y() != 0; scroll_animating_latched_element_id_ = scroll_node->element_id; TRACE_EVENT_INSTANT0("cc", "created scroll animation", TRACE_EVENT_SCOPE_THREAD); @@ -4353,7 +4287,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( return scroll_status; } - pending_delta -= scroll_delta; + pending_delta -= delta; if (!CanPropagate(scroll_node, pending_delta.x(), pending_delta.y())) { scroll_state.set_is_scroll_chain_cut(true); @@ -4552,12 +4486,13 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, const float kEpsilon = 0.1f; if (viewport()->ShouldScroll(*scroll_node)) { - // This will be false if the scroll chains up to the viewport without going - // through the outer viewport scroll node. This can happen if we scroll an - // element that's not a descendant of the document.rootScroller. In that - // case we want to scroll *only* the inner viewport -- to allow panning - // while zoomed -- but still use Viewport::ScrollBy to also move browser - // controls if needed. + // |scroll_outer_vieiwport| will only ever be false if the scroll chains up + // to the viewport without going through the outer viewport scroll node. + // This is because we normally terminate the scroll chain at the outer + // viewport node. For example, if we start scrolling from an element + // that's not a descendant of the root scroller. In these cases we want to + // scroll *only* the inner viewport -- to allow panning while zoomed -- but + // still use Viewport::ScrollBy to also move browser controls if needed. bool scroll_outer_viewport = scroll_node->scrolls_outer_viewport; Viewport::ScrollResult result = viewport()->ScrollBy( delta, viewport_point, scroll_state->is_direct_manipulation(), @@ -4617,7 +4552,12 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) { ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); ScrollNode* viewport_scroll_node = ViewportMainScrollNode(); - if (scroll_node) { + if (did_lock_scrolling_layer_) { + DCHECK(scroll_node); + + // Needed for non-animated scrolls. + current_scroll_chain.push_front(scroll_node); + } else if (scroll_node) { // TODO(bokan): The loop checks for a null parent but don't we still want to // distribute to the root scroll node? for (; scroll_tree.parent(scroll_node); @@ -4634,6 +4574,11 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) { if (!scroll_node->scrollable) continue; + if (middle_click_autoscrolling_) { + current_scroll_chain.push_front(scroll_node); + break; + } + if (CanConsumeDelta(*scroll_node, *scroll_state)) current_scroll_chain.push_front(scroll_node); @@ -5004,7 +4949,9 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) { DistributeScrollDelta(scroll_state); browser_controls_offset_manager_->ScrollEnd(); ClearCurrentlyScrollingNode(); - frame_trackers_.ScheduleRemoval(std::move(scroll_frame_tracker_)); + frame_trackers_.StopSequence(wheel_scrolling_ + ? FrameSequenceTrackerType::kWheelScroll + : FrameSequenceTrackerType::kTouchScroll); } void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) { @@ -5033,7 +4980,7 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseDown( InputHandlerPointerResult result; if (settings().compositor_threaded_scrollbar_scrolling) - result = scrollbar_controller_->HandleMouseDown(viewport_point); + result = scrollbar_controller_->HandlePointerDown(viewport_point); return result; } @@ -5053,7 +5000,7 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseUp( InputHandlerPointerResult result; if (settings().compositor_threaded_scrollbar_scrolling) - result = scrollbar_controller_->HandleMouseUp(viewport_point); + result = scrollbar_controller_->HandlePointerUp(viewport_point); return result; } @@ -5138,8 +5085,7 @@ void LayerTreeHostImpl::PinchGestureBegin() { OuterViewportScrollNode() ? false : true); active_tree_->SetCurrentlyScrollingNode(OuterViewportScrollNode()); browser_controls_offset_manager_->PinchBegin(); - pinch_frame_tracker_ = - frame_trackers_.CreateTracker(FrameSequenceTrackerType::kPinchZoom); + frame_trackers_.StartSequence(FrameSequenceTrackerType::kPinchZoom); } void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, @@ -5172,7 +5118,7 @@ void LayerTreeHostImpl::PinchGestureEnd(const gfx::Point& anchor, // scales that we want when we're not inside a pinch. active_tree_->set_needs_update_draw_properties(); SetNeedsRedraw(); - frame_trackers_.ScheduleRemoval(std::move(pinch_frame_tracker_)); + frame_trackers_.StopSequence(FrameSequenceTrackerType::kPinchZoom); } void LayerTreeHostImpl::CollectScrollDeltas( @@ -5273,7 +5219,14 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { } void LayerTreeHostImpl::SetFullViewportDamage() { - SetViewportDamage(gfx::Rect(active_tree_->GetDeviceViewport().size())); + // In non-Android-WebView cases, we expect GetDeviceViewport() to be the same + // as internal_device_viewport(), so the full-viewport damage rect is just + // the internal viewport rect. In the case of Android WebView, + // GetDeviceViewport returns the external viewport, but we still want to use + // the internal viewport's origin for setting the damage. + // See https://chromium-review.googlesource.com/c/chromium/src/+/1257555. + SetViewportDamage(gfx::Rect(active_tree_->internal_device_viewport().origin(), + active_tree_->GetDeviceViewport().size())); } bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { @@ -5353,13 +5306,11 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, // still request an extra SetNeedsAnimate here. if (animated) { SetNeedsOneBeginImplFrame(); - if (!compositor_animation_frame_tracker_) { - compositor_animation_frame_tracker_ = frame_trackers_.CreateTracker( - FrameSequenceTrackerType::kCompositorAnimation); - } + frame_trackers_.StartSequence( + FrameSequenceTrackerType::kCompositorAnimation); } else { - frame_trackers_.ScheduleRemoval( - std::move(compositor_animation_frame_tracker_)); + frame_trackers_.StopSequence( + FrameSequenceTrackerType::kCompositorAnimation); } // TODO(crbug.com/551138): We could return true only if the animaitons are on @@ -6012,6 +5963,14 @@ void LayerTreeHostImpl::SetElementFilterMutated( } } +void LayerTreeHostImpl::OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value) { + paint_worklet_tracker_.OnCustomPropertyMutated( + element_id, custom_property_name, std::move(custom_property_value)); +} + void LayerTreeHostImpl::SetElementBackdropFilterMutated( ElementId element_id, ElementListType list_type, diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index ca403dbfd97..395419652fc 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -27,6 +27,8 @@ #include "cc/input/scrollbar_animation_controller.h" #include "cc/input/scrollbar_controller.h" #include "cc/layers/layer_collections.h" +#include "cc/metrics/frame_sequence_tracker.h" +#include "cc/paint/discardable_image_map.h" #include "cc/paint/paint_worklet_job.h" #include "cc/resources/ui_resource_client.h" #include "cc/scheduler/begin_frame_tracker.h" @@ -37,7 +39,8 @@ #include "cc/tiles/decoded_image_tracker.h" #include "cc/tiles/image_decode_cache.h" #include "cc/tiles/tile_manager.h" -#include "cc/trees/frame_sequence_tracker.h" +#include "cc/trees/animated_paint_worklet_tracker.h" +#include "cc/trees/de_jelly_state.h" #include "cc/trees/layer_tree_frame_sink_client.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_mutator.h" @@ -196,8 +199,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, FrameData& operator=(const FrameData&) = delete; void AsValueInto(base::trace_event::TracedValue* value) const; - uint32_t frame_token = 0; // frame_token is populated by the LayerTreeHostImpl when submitted. + uint32_t frame_token = 0; + + bool has_missing_content = false; std::vector<viz::SurfaceId> activation_dependencies; base::Optional<uint32_t> deadline_in_frames; @@ -211,10 +216,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, // The original BeginFrameArgs that triggered the latest update from the // main thread. viz::BeginFrameArgs origin_begin_main_frame_args; - - // Union of visible rects of MirrorLayers in the frame, used to force damage - // on the surface. - gfx::Rect mirror_rect; }; // A struct of data for a single UIResource, including the backing @@ -327,8 +328,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, base::WeakPtr<LayerTreeHostImpl> AsWeakPtr(); - void UpdateViewportContainerSizes(); - void set_resourceless_software_draw_for_testing() { resourceless_software_draw_ = true; } @@ -403,6 +402,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, ElementListType list_type, float maximum_scale, float starting_scale) override; + void OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value) override; void ScrollOffsetAnimationFinished() override; gfx::ScrollOffset GetScrollOffsetForAnimation( @@ -794,6 +797,9 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, void set_pending_tree_fully_painted_for_testing(bool painted) { pending_tree_fully_painted_ = painted; } + AnimatedPaintWorkletTracker& paint_worklet_tracker() { + return paint_worklet_tracker_; + } protected: LayerTreeHostImpl( @@ -866,7 +872,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, // Returns a job map for all 'dirty' PaintWorklets, e.g. PaintWorkletInputs // that do not map to a PaintRecord. - PaintWorkletJobMap GatherDirtyPaintWorklets() const; + PaintWorkletJobMap GatherDirtyPaintWorklets(PaintImageIdFlatSet*) const; // Called when all PaintWorklet results are ready (i.e. have been painted) for // the current pending tree. @@ -1055,6 +1061,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, bool did_lock_scrolling_layer_ = false; bool touch_scrolling_ = false; bool wheel_scrolling_ = false; + bool middle_click_autoscrolling_ = false; bool scroll_affects_scroll_handler_ = false; ElementId scroll_element_id_mouse_currently_over_; ElementId scroll_element_id_mouse_currently_captured_; @@ -1240,11 +1247,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, std::unique_ptr<ScrollbarController> scrollbar_controller_; FrameSequenceTrackerCollection frame_trackers_; - std::unique_ptr<FrameSequenceTracker> pinch_frame_tracker_; - std::unique_ptr<FrameSequenceTracker> scroll_frame_tracker_; - std::unique_ptr<FrameSequenceTracker> compositor_animation_frame_tracker_; - std::unique_ptr<FrameSequenceTracker> request_animation_frame_tracker_; - std::unique_ptr<FrameSequenceTracker> main_thread_animation_frame_tracker_; // Set to true when a scroll gesture being handled on the compositor has // ended. i.e. When a GSE has arrived and any ongoing scroll animation has @@ -1270,6 +1272,15 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, // not we are in that state. bool pending_tree_fully_painted_ = false; + // Provides support for PaintWorklets which depend on input properties that + // are being animated by the compositor (aka 'animated' PaintWorklets). + // Responsible for storing animated custom property values and for + // invalidating PaintWorklets as the property values change. + AnimatedPaintWorkletTracker paint_worklet_tracker_; + + // Helper for de-jelly logic. + DeJellyState de_jelly_state_; + // Must be the last member to ensure this is destroyed first in the // destruction order and invalidates all weak pointers. base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_{this}; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index 24ceca1c40c..f695646918f 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -65,6 +65,7 @@ #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" +#include "cc/trees/render_frame_metadata.h" #include "cc/trees/render_frame_metadata_observer.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" @@ -157,8 +158,8 @@ class LayerTreeHostImplTest : public testing::Test, void CreatePendingTree() { host_impl_->CreatePendingTree(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportSize( - host_impl_->active_tree()->GetDeviceViewport().size()); + pending_tree->SetDeviceViewportRect( + host_impl_->active_tree()->GetDeviceViewport()); pending_tree->SetDeviceScaleFactor( host_impl_->active_tree()->device_scale_factor()); // Normally a pending tree will not be fully painted until the commit has @@ -273,7 +274,7 @@ class LayerTreeHostImplTest : public testing::Test, layer_tree_frame_sink_ = std::move(layer_tree_frame_sink); host_impl_->SetVisible(true); bool init = host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 10)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent( viz::LocalSurfaceIdAllocation( @@ -463,7 +464,7 @@ class LayerTreeHostImplTest : public testing::Test, gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportSize(content_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); root->SetBounds(content_size); root->test_properties()->position = gfx::PointF(); @@ -567,7 +568,7 @@ class LayerTreeHostImplTest : public testing::Test, host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); host_impl_->active_tree()->DidBecomeActive(); return content_layer; @@ -624,6 +625,12 @@ class LayerTreeHostImplTest : public testing::Test, host_impl_->DidDrawAllLayers(frame); } + RenderFrameMetadata StartDrawAndProduceRenderFrameMetadata() { + TestFrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + return host_impl_->MakeRenderFrameMetadata(&frame); + } + void TestGPUMemoryForTilings(const gfx::Size& layer_size) { std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_size); @@ -638,7 +645,7 @@ class LayerTreeHostImplTest : public testing::Test, // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportSize(layer_size); + pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); pending_tree->SetRootLayerForTesting( FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, raster_source)); @@ -663,7 +670,7 @@ class LayerTreeHostImplTest : public testing::Test, void WhiteListedTouchActionTestHelper(float device_scale_factor, float page_scale_factor) { LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); DrawFrame(); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); @@ -715,8 +722,11 @@ class LayerTreeHostImplTest : public testing::Test, } LayerImpl* CreateLayerForSnapping() { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + SetupScrollAndContentsLayers(gfx::Size(200, 200)); + LayerImpl* scroll_layer = + host_impl_->active_tree()->OuterViewportScrollLayer(); + + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); gfx::Size overflow_size(400, 400); EXPECT_EQ(1u, scroll_layer->test_properties()->children.size()); @@ -939,12 +949,12 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { on_can_draw_state_changed_called_ = false; // Toggle the device viewport size to make sure it toggles can_draw. - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size()); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect()); EXPECT_FALSE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -956,7 +966,7 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_TRUE(host_impl_->CanDraw()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size()); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect()); EXPECT_FALSE(host_impl_->CanDraw()); auto* fake_layer_tree_frame_sink = @@ -967,11 +977,6 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { const bool resourceless_software_draw = true; host_impl_->OnDraw(identity, viewport, resourceless_software_draw, false); ASSERT_EQ(fake_layer_tree_frame_sink->num_sent_frames(), 1u); -#if defined(OS_ANDROID) - EXPECT_EQ( - gfx::SizeF(100.f, 100.f), - fake_layer_tree_frame_sink->last_sent_frame()->metadata.root_layer_size); -#endif } TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { @@ -1100,7 +1105,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1122,7 +1127,7 @@ TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1170,7 +1175,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); // We should not crash if the tree is replaced while we are scrolling. @@ -1198,7 +1203,7 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); scroll->SetWheelEventHandlerRegion(Region(gfx::Rect(20, 20))); DrawFrame(); @@ -1225,7 +1230,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); @@ -1279,7 +1284,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); root->test_properties()->main_thread_scrolling_reasons = @@ -1315,7 +1320,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportSize(content_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); root->SetBounds(content_size); root->test_properties()->position = gfx::PointF(); @@ -1371,7 +1376,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); @@ -1420,7 +1425,7 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); @@ -1453,7 +1458,7 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); EXPECT_FALSE(host_impl_->active_tree()->have_scroll_event_handlers()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1467,7 +1472,7 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); host_impl_->active_tree()->set_have_scroll_event_handlers(true); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1480,7 +1485,7 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); DrawFrame(); @@ -1752,8 +1757,13 @@ TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) { } TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + const gfx::Size kViewportSize(100, 100); + const gfx::Size kContentSize(200, 200); + CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + + LayerImpl* scroll_layer = + host_impl_->active_tree()->OuterViewportScrollLayer(); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); gfx::Size overflow_size(400, 400); ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); @@ -1790,10 +1800,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 30), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); - overflow->test_properties()->overscroll_behavior = + GetScrollNode(overflow)->overscroll_behavior = OverscrollBehavior(OverscrollBehavior::kOverscrollBehaviorTypeContain, OverscrollBehavior::kOverscrollBehaviorTypeAuto); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -1843,10 +1852,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); // Changing scroll-boundary-behavior to y axis. - overflow->test_properties()->overscroll_behavior = + GetScrollNode(overflow)->overscroll_behavior = OverscrollBehavior(OverscrollBehavior::kOverscrollBehaviorTypeAuto, OverscrollBehavior::kOverscrollBehaviorTypeContain); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -1897,10 +1905,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { // Gesture scroll should latch to the first scroller that has non-auto // overscroll-behavior. - overflow->test_properties()->overscroll_behavior = + GetScrollNode(overflow)->overscroll_behavior = OverscrollBehavior(OverscrollBehavior::kOverscrollBehaviorTypeContain, OverscrollBehavior::kOverscrollBehaviorTypeContain); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -1922,8 +1929,13 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { } TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + const gfx::Size kViewportSize(100, 100); + const gfx::Size kContentSize(200, 200); + CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + + LayerImpl* scroll_layer = + host_impl_->active_tree()->OuterViewportScrollLayer(); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); gfx::Size overflow_size(400, 400); ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); @@ -1994,7 +2006,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { TEST_F(LayerTreeHostImplTest, ForceMainThreadScrollWithoutScrollLayer) { SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); ScrollNode* scroll_node = @@ -2016,7 +2028,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); CreatePendingTree(); auto root_owned = LayerImpl::Create(host_impl_->pending_tree(), 1); @@ -2076,7 +2088,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingActiveTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->SetRootLayerForTesting( LayerImpl::Create(host_impl_->active_tree(), 1)); @@ -2143,7 +2155,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { CreateLayerTreeFrameSink(), &provider); EXPECT_TRUE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); auto* root = root_owned.get(); @@ -2166,7 +2178,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { // CommitComplete below. RenderSurfaceList list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(50, 50), &list); + root, gfx::Rect(50, 50), &list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_FALSE(did_request_next_frame_); @@ -2187,7 +2199,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { } TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->SetRootLayerForTesting( LayerImpl::Create(host_impl_->active_tree(), 1)); @@ -2280,7 +2292,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); @@ -2753,10 +2765,15 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { LayerImpl* viewport_scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + // This is to build property tree for viewport layers. The remaining part of + // this test is in layer list mode. + // TODO(crbug.com/994361): Avoid PropertyTreeBuilder. + host_impl_->active_tree()->BuildPropertyTreesForTesting(); // Set up two scrolling children of the root, one of which is a scroll parent // to the other. Scrolls shouldn't bubbling from the child. + LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); LayerImpl* parent; LayerImpl* child; LayerImpl* child_clip; @@ -2764,21 +2781,27 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { std::unique_ptr<LayerImpl> scroll_parent = CreateScrollableLayer(7, gfx::Size(10, 10)); parent = scroll_parent.get(); - viewport_scroll->test_properties()->AddChild(std::move(scroll_parent)); + root->test_properties()->AddChild(std::move(scroll_parent)); + CopyProperties(viewport_scroll, parent); + CreateTransformNode(parent); + CreateScrollNode(parent); std::unique_ptr<LayerImpl> scroll_child_clip = LayerImpl::Create(host_impl_->active_tree(), 8); + child_clip = scroll_child_clip.get(); + root->test_properties()->AddChild(std::move(scroll_child_clip)); + CopyProperties(viewport_scroll, child_clip); + // child_clip scrolls in scroll_parent. + child_clip->SetScrollTreeIndex(parent->scroll_tree_index()); + child_clip->SetTransformTreeIndex(parent->transform_tree_index()); + std::unique_ptr<LayerImpl> scroll_child = CreateScrollableLayer(9, gfx::Size(10, 10)); child = scroll_child.get(); - scroll_child->test_properties()->position = gfx::PointF(20.f, 20.f); - scroll_child_clip->test_properties()->AddChild(std::move(scroll_child)); - - child_clip = scroll_child_clip.get(); - viewport_scroll->test_properties()->AddChild(std::move(scroll_child_clip)); - - child_clip->test_properties()->scroll_parent = parent; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + root->test_properties()->AddChild(std::move(scroll_child)); + CopyProperties(child_clip, child); + CreateTransformNode(child).post_translation = gfx::Vector2d(20, 20); + CreateScrollNode(child); DrawFrame(); @@ -2834,7 +2857,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { TEST_F(LayerTreeHostImplTest, PinchGesture) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -3009,7 +3032,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -3057,7 +3080,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); @@ -3093,7 +3116,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); float min_page_scale = 1.f; @@ -3216,7 +3239,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); @@ -3346,7 +3369,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); @@ -3531,7 +3554,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); @@ -3581,7 +3604,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -3655,8 +3678,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { SetupScrollAndContentsLayers(content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f); - host_impl_->active_tree()->SetDeviceViewportSize( - gfx::Size(content_size.width() / 2, content_size.height() / 2)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(content_size.width() / 2, content_size.height() / 2)); std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400, @@ -3977,7 +4000,7 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest { CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( viewport_size); @@ -4132,7 +4155,7 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) { CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( viewport_size); @@ -4543,7 +4566,8 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportSize(device_viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(device_viewport_size)); CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( @@ -4626,7 +4650,7 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { // |activation_dependencies|. TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); std::vector<viz::SurfaceId> primary_surfaces = { @@ -4709,7 +4733,7 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { // damage. TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); auto* fake_layer_tree_frame_sink = static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); @@ -4744,7 +4768,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); { @@ -4754,12 +4778,6 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { EXPECT_EQ(1.f, metadata.page_scale_factor); EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); - -#if defined(OS_ANDROID) - EXPECT_EQ(4.f, metadata.max_page_scale_factor); - EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); - EXPECT_FALSE(metadata.root_overflow_y_hidden); -#endif } // Scrolling should update metadata immediately. @@ -4781,74 +4799,6 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); } - // Root "overflow: hidden" properties should be reflected on the outer - // viewport scroll layer. - { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - viz::CompositorFrameMetadata metadata = - host_impl_->MakeCompositorFrameMetadata(); -#if defined(OS_ANDROID) - EXPECT_FALSE(metadata.root_overflow_y_hidden); -#endif - - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - metadata = host_impl_->MakeCompositorFrameMetadata(); -#if defined(OS_ANDROID) - EXPECT_TRUE(metadata.root_overflow_y_hidden); -#endif - } - - // Re-enable scrollability and verify that overflows are no longer hidden. - { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = true; - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - viz::CompositorFrameMetadata metadata = - host_impl_->MakeCompositorFrameMetadata(); -#if defined(OS_ANDROID) - EXPECT_FALSE(metadata.root_overflow_y_hidden); -#endif - } - - // Root "overflow: hidden" properties should also be reflected on the - // inner viewport scroll layer. - { - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - viz::CompositorFrameMetadata metadata = - host_impl_->MakeCompositorFrameMetadata(); -#if defined(OS_ANDROID) - EXPECT_FALSE(metadata.root_overflow_y_hidden); -#endif - - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - metadata = host_impl_->MakeCompositorFrameMetadata(); -#if defined(OS_ANDROID) - EXPECT_TRUE(metadata.root_overflow_y_hidden); -#endif - } - // Page scale should update metadata correctly (shrinking only the viewport). host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN); @@ -4863,11 +4813,6 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { EXPECT_EQ(2.f, metadata.page_scale_factor); EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); - -#if defined(OS_ANDROID) - EXPECT_EQ(4.f, metadata.max_page_scale_factor); - EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); -#endif } // Likewise if set from the main thread. @@ -4881,11 +4826,6 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { EXPECT_EQ(4.f, metadata.page_scale_factor); EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); - -#if defined(OS_ANDROID) - EXPECT_EQ(4.f, metadata.max_page_scale_factor); - EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); -#endif } } @@ -4953,7 +4893,7 @@ class DidDrawCheckLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 10)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); auto* root = @@ -5122,7 +5062,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportSize(big_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); @@ -5354,10 +5294,12 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + { + TestFrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame); + host_impl_->DidDrawAllLayers(frame); + } for (size_t i = 0; i < cases.size(); ++i) { // Clean up host_impl_ state. @@ -5686,71 +5628,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollEnd(EndState().get()); } -// This test is the same as above but ensures the behavior prior to -// BlinkGenPropertyTrees because the outer viewport's clip node size is -// inconsistent with the scroll node's content bounds. Pre-BGPT, the outer -// viewport clip node is always the same size as the inner viewport clip node, -// even if the outer viewport changes size as a result of a non-1 minimum page -// scale factor. -// TODO(bokan): This test can be safely removed post-BGPT. See crbug.com/901083. -TEST_F(LayerTreeHostImplBrowserControlsTest, - MovingBrowserControlsChangesViewportClip) { - auto turn_off_layer_lists = base::BindOnce( - [](LayerTreeSettings* settings) { settings->use_layer_lists = false; }); - - SetupBrowserControlsAndScrollLayerWithVirtualViewport( - gfx::Size(50, 50), gfx::Size(25, 25), gfx::Size(100, 100), - std::move(turn_off_layer_lists)); - - LayerTreeImpl* active_tree = host_impl_->active_tree(); - - // Create a content layer beneath the outer viewport scroll layer. - int id = host_impl_->OuterViewportScrollLayer()->id(); - host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), id + 2)); - LayerImpl* content = - active_tree->OuterViewportScrollLayer()->test_properties()->children[0]; - content->SetBounds(gfx::Size(100, 100)); - host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - DrawFrame(); - - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - LayerImpl* outer_scroll = active_tree->OuterViewportScrollLayer(); - auto* property_trees = host_impl_->active_tree()->property_trees(); - ClipNode* outer_clip_node = - property_trees->clip_tree.Node(outer_scroll->clip_tree_index()); - - // The browser controls should start off showing so the viewport should be - // shrunk. - EXPECT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset()); - ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds()); - ASSERT_EQ(gfx::Size(25, 25), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(100, 100), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), outer_clip_node->clip.size()); - - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, - host_impl_ - ->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::TOUCHSCREEN) - .thread); - - // Hide the browser controls by 10px. The outer clip should expand by 10px as - // well because the clip node doesn't account for the "resize to - // minimum-scale" that occurs for the outer viewport layer (hence, why the - // outer viewport layer is half the size of the inner in this test). - { - host_impl_->ScrollBy( - UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 10.f)).get()); - ASSERT_EQ(40, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(gfx::SizeF(50, 60), outer_clip_node->clip.size()); - } - - host_impl_->ScrollEnd(EndState().get()); -} - // Tests that browser controls affect the position of horizontal scrollbars. TEST_F(LayerTreeHostImplBrowserControlsTest, HidingBrowserControlsAdjustsScrollbarPosition) { @@ -6094,9 +5971,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Ensure setting the browser controls position explicitly using the setters on // the TreeImpl correctly affects the browser controls manager and viewport -// bounds. +// bounds for the active tree. TEST_F(LayerTreeHostImplBrowserControlsTest, - PositionBrowserControlsExplicitly) { + PositionBrowserControlsToActiveTreeExplicitly) { SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -6126,6 +6003,51 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); } +// Ensure setting the browser controls position explicitly using the setters on +// the TreeImpl correctly affects the browser controls manager and viewport +// bounds for the pending tree. +TEST_F(LayerTreeHostImplBrowserControlsTest, + PositionBrowserControlsToPendingTreeExplicitly) { + CreatePendingTree(); + SetupBrowserControlsAndScrollLayerWithVirtualViewport( + host_impl_->pending_tree(), layer_size_, layer_size_, layer_size_); + + // Changing SetCurrentBrowserControlsShownRatio is one way to cause the + // pending tree to update it's viewport. + host_impl_->SetCurrentBrowserControlsShownRatio(0.f); + EXPECT_FLOAT_EQ(top_controls_height_, + host_impl_->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y()); + host_impl_->SetCurrentBrowserControlsShownRatio(0.5f); + EXPECT_FLOAT_EQ(0.5f * top_controls_height_, + host_impl_->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y()); + host_impl_->SetCurrentBrowserControlsShownRatio(1.f); + EXPECT_FLOAT_EQ(0.f, host_impl_->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y()); + + // Pushing changes from the main thread is the second way. These values are + // added to the 1.f set above. + host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-0.5f); + EXPECT_FLOAT_EQ(0.5f * top_controls_height_, + host_impl_->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y()); + host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-1.f); + EXPECT_FLOAT_EQ(top_controls_height_, + host_impl_->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y()); +} + // Test that the top_controls delta and sent delta are appropriately // applied on sync tree activation. The total browser controls offset shouldn't // change after the activation. @@ -6627,7 +6549,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { scroll_container_layer->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6652,7 +6574,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6675,7 +6597,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll event is ignored because the input coordinate is outside the layer @@ -6706,7 +6628,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll event is ignored because the scrollable layer is not facing the @@ -6736,7 +6658,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(scroll_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scrolling fails because the content layer is asking to be scrolled on the @@ -6957,6 +6879,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { CreateBasicVirtualViewportLayers(surface_size, surface_size); root->test_properties()->force_render_surface = true; + std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(13, content_size); @@ -6978,7 +6901,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(3, 0)); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(-8, -7); @@ -6994,16 +6917,12 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled up to its limit. - LayerImpl* child = host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]; EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child_layer->element_id(), gfx::ScrollOffset(0, -5))); // The child should not have scrolled. - ExpectNone(*scroll_info.get(), child->element_id()); + ExpectNone(*scroll_info.get(), child_layer->element_id()); } } @@ -7016,8 +6935,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { 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); @@ -7040,7 +6957,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 50)); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); base::TimeTicks start_time = @@ -7110,10 +7027,13 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(20, 20); gfx::Size viewport_size(10, 10); - const int kPageScaleLayerId = 1; - const int kViewportClipLayerId = 2; - const int kViewportScrollLayerId = 3; + const int kRootLayerId = 1; + const int kPageScaleLayerId = 2; + const int kViewportClipLayerId = 3; + const int kViewportScrollLayerId = 4; std::unique_ptr<LayerImpl> root_ptr = + LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); + std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); @@ -7126,23 +7046,24 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(5, surface_size); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(4, surface_size); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(6, surface_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); LayerImpl* child_layer = child.get(); root_scrolling->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scrolling)); - root_ptr->test_properties()->AddChild(std::move(root_clip)); + page_scale->test_properties()->AddChild(std::move(root_clip)); + root_ptr->test_properties()->AddChild(std::move(page_scale)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); LayerTreeImpl::ViewportLayerIds viewport_ids; viewport_ids.page_scale = kPageScaleLayerId; viewport_ids.inner_viewport_container = kViewportClipLayerId; viewport_ids.inner_viewport_scroll = kViewportScrollLayerId; host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); grand_child_layer->layer_tree_impl() ->property_trees() @@ -7168,21 +7089,12 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled up to its limit. - LayerImpl* child = host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->test_properties() - ->children[0] - ->test_properties() - ->children[0]; - LayerImpl* grand_child = child->test_properties()->children[0]; EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), - grand_child->element_id(), + grand_child_layer->element_id(), gfx::ScrollOffset(0, -2))); // The child should not have scrolled. - ExpectNone(*scroll_info.get(), child->element_id()); + ExpectNone(*scroll_info.get(), child_layer->element_id()); // The next time we scroll we should only scroll the parent. scroll_delta = gfx::Vector2d(0, -3); @@ -7192,21 +7104,22 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { InputHandler::TOUCHSCREEN) .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - grand_child->scroll_tree_index()); + grand_child_layer->scroll_tree_index()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - child->scroll_tree_index()); + child_layer->scroll_tree_index()); host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); // The child should have scrolled up to its limit. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + child_layer->element_id(), gfx::ScrollOffset(0, -3))); // The grand child should not have scrolled. EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), - grand_child->element_id(), + grand_child_layer->element_id(), gfx::ScrollOffset(0, -2))); // After scrolling the parent, another scroll on the opposite direction @@ -7218,21 +7131,22 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { InputHandler::TOUCHSCREEN) .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - grand_child->scroll_tree_index()); + grand_child_layer->scroll_tree_index()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - grand_child->scroll_tree_index()); + grand_child_layer->scroll_tree_index()); host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled. EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), - grand_child->element_id(), + grand_child_layer->element_id(), gfx::ScrollOffset(0, 5))); // The child should not have scrolled. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + child_layer->element_id(), gfx::ScrollOffset(0, -3))); // Scrolling should be adjusted from viewport space. @@ -7245,7 +7159,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(grand_child->scroll_tree_index(), + EXPECT_EQ(grand_child_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); @@ -7254,7 +7168,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // Should have scrolled by half the amount in layer space (5 - 2/2) EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), - grand_child->element_id(), + grand_child_layer->element_id(), gfx::ScrollOffset(0, 4))); } } @@ -7278,7 +7192,7 @@ TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) { content_layer->test_properties()->AddChild(std::move(fixed_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); // This is very hackish but we want to simulate the kind of property tree - // that BGPT would create where a fixed layer's ScrollNode is parented to + // that blink would create where a fixed layer's ScrollNode is parented to // the inner viewport, rather than the outer. host_impl_->active_tree() ->LayerById(kFixedLayerId) @@ -7365,14 +7279,14 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { } TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { - const int kPageScaleLayerId = 1; + const int kRootLayerId = 1; const int kInnerViewportClipLayerId = 2; const int kOuterViewportClipLayerId = 7; const int kInnerViewportScrollLayerId = 3; const int kOuterViewportScrollLayerId = 8; gfx::Size surface_size(10, 10); std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); + LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); std::unique_ptr<LayerImpl> inner_scroll = @@ -7392,7 +7306,6 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { root_ptr->test_properties()->AddChild(std::move(inner_clip)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; @@ -7401,13 +7314,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); // Draw one frame and then immediately rebuild the layer tree to mimic a tree // synchronization. DrawFrame(); - const int kPageScaleLayerId2 = 4; const int kInnerViewportClipLayerId2 = 5; const int kOuterViewportClipLayerId2 = 9; const int kInnerViewportScrollLayerId2 = 6; @@ -7435,7 +7347,6 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); LayerTreeImpl::ViewportLayerIds viewport_ids2; - viewport_ids2.page_scale = kPageScaleLayerId2; viewport_ids2.inner_viewport_container = kInnerViewportClipLayerId2; viewport_ids2.outer_viewport_container = kOuterViewportClipLayerId2; viewport_ids2.inner_viewport_scroll = kInnerViewportScrollLayerId2; @@ -7458,14 +7369,12 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { // Rotate the root layer 90 degrees counter-clockwise about its center. gfx::Transform rotate_transform; rotate_transform.Rotate(-90.0); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->transform = rotate_transform; + // Set external transform. + host_impl_->OnDraw(rotate_transform, gfx::Rect(0, 0, 50, 50), false, false); host_impl_->active_tree()->BuildPropertyTreesForTesting(); gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll to the right in screen coordinates with a gesture. @@ -7541,7 +7450,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { // Scroll down in screen coordinates with a gesture. @@ -7627,7 +7536,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -7686,12 +7595,12 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { int scale = 2; gfx::Transform scale_transform; scale_transform.Scale(scale, scale); - scroll_layer->test_properties()->parent->test_properties()->transform = - scale_transform; + // Set external transform above root. + host_impl_->OnDraw(scale_transform, gfx::Rect(0, 0, 50, 50), false, false); host_impl_->active_tree()->BuildPropertyTreesForTesting(); gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll down in screen coordinates with a gesture. @@ -7754,7 +7663,7 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { TestInputHandlerClient scroll_watcher; - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 20)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; @@ -7868,7 +7777,7 @@ void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) { TEST_F(LayerTreeHostImplTest, ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) { - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 20)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; @@ -8033,7 +7942,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -8200,7 +8109,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { ->scroll_tree.UpdateScrollOffsetBaseForTesting( grand_child_layer->element_id(), gfx::ScrollOffset(0, 2)); - host_impl_->active_tree()->SetDeviceViewportSize(surface_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(0, -10); @@ -8312,7 +8221,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { scroll_layer->SetHitTestable(true); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -9291,7 +9200,7 @@ static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) { TEST_F(LayerTreeHostImplTest, MayContainVideo) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportSize(big_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); int layer_id = 1; host_impl_->active_tree()->SetRootLayerForTesting( @@ -9563,8 +9472,8 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { bool software = false; CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); - host_impl_->active_tree()->SetDeviceViewportSize( - DipSizeToPixelSize(viewport_size_)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9579,8 +9488,8 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); host_impl_->active_tree()->SetDeviceScaleFactor(2.f); - host_impl_->active_tree()->SetDeviceViewportSize( - DipSizeToPixelSize(viewport_size_)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9596,8 +9505,8 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { // Pending tree to force active_tree size invalid. Not used otherwise. CreatePendingTree(); - host_impl_->active_tree()->SetDeviceViewportSize( - DipSizeToPixelSize(viewport_size_)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestEmptyLayerWithOnDraw()); @@ -9615,15 +9524,15 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { CreatePendingTree(); gfx::Size larger_viewport(viewport_size_.width() + 100, viewport_size_.height() + 100); - host_impl_->active_tree()->SetDeviceViewportSize( - DipSizeToPixelSize(larger_viewport)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(larger_viewport))); host_impl_->ActivateSyncTree(); EXPECT_TRUE(did_activate_pending_tree_); // Shrink pending tree viewport without activating. CreatePendingTree(); - host_impl_->active_tree()->SetDeviceViewportSize( - DipSizeToPixelSize(viewport_size_)); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestEmptyLayerWithOnDraw()); @@ -9669,8 +9578,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->InitializeFrameSink(layer_tree_frame_sink.get()); layer_tree_host_impl->WillBeginImplFrame( viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2)); - layer_tree_host_impl->active_tree()->SetDeviceViewportSize( - gfx::Size(500, 500)); + layer_tree_host_impl->active_tree()->SetDeviceViewportRect( + gfx::Rect(500, 500)); std::unique_ptr<LayerImpl> root = FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); @@ -9722,7 +9631,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { EXPECT_EQ(expected_swap_rect.ToString(), fake_layer_tree_frame_sink->last_swap_rect().ToString()); - layer_tree_host_impl->active_tree()->SetDeviceViewportSize(gfx::Size(10, 10)); + layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); // This will damage everything. layer_tree_host_impl->active_tree() ->root_layer_for_testing() @@ -9972,7 +9881,8 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { gfx::Size root_size(2000, 1000); gfx::Size device_viewport_size = gfx::ScaleToCeiledSize(root_size, device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportSize(device_viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect( + gfx::Rect(device_viewport_size)); CreatePendingTree(); host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor); @@ -10294,7 +10204,7 @@ class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest { layer_tree_frame_sink_ = CreateLayerTreeFrameSink(); host_impl_->SetVisible(true); host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(10, 10)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); } FakeLayerTreeHostImpl* fake_host_impl_; @@ -10851,10 +10761,6 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - // Ensure the default frame selection bounds are empty. - auto* fake_layer_tree_frame_sink = - static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); gfx::Point selection_bottom(5, 5); @@ -10866,19 +10772,12 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { selection.end = selection.start; host_impl_->active_tree()->RegisterSelection(selection); - // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - - gfx::Rect full_frame_damage( - host_impl_->active_tree()->GetDeviceViewport().size()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); // Ensure the selection bounds have propagated to the frame metadata. const viz::Selection<gfx::SelectionBound>& selection_after = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.selection; + metadata.selection; EXPECT_EQ(selection.start.type, selection_after.start.type()); EXPECT_EQ(selection.end.type, selection_after.end.type()); EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom()); @@ -10899,10 +10798,6 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - // Ensure the default frame selection bounds are empty. - auto* fake_layer_tree_frame_sink = - static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); gfx::Point selection_bottom(5, 5); @@ -10918,19 +10813,12 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { selection.end = selection.start; host_impl_->active_tree()->RegisterSelection(selection); - // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - - gfx::Rect full_frame_damage( - host_impl_->active_tree()->GetDeviceViewport().size()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); // Ensure the selection bounds have propagated to the frame metadata. const viz::Selection<gfx::SelectionBound>& selection_after = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.selection; + metadata.selection; EXPECT_EQ(selection.start.type, selection_after.start.type()); EXPECT_EQ(selection.end.type, selection_after.end.type()); EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom()); @@ -11140,7 +11028,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11214,7 +11102,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, WheelUnhandledByBrowserControls) { SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 100)); host_impl_->active_tree()->set_browser_controls_shrink_blink_size(true); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); @@ -11257,7 +11145,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 200)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 200)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11337,7 +11225,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); float initial_scroll_offset = 50; @@ -11417,7 +11305,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11841,7 +11729,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformSetNeedsRedraw) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); const gfx::Transform transform_for_tile_priority; const gfx::Transform draw_transform; @@ -11894,7 +11782,7 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); const gfx::Transform draw_transform; const gfx::Rect draw_viewport1(viewport_size); @@ -11929,7 +11817,7 @@ TEST_F(LayerTreeHostImplTest, FullViewportDamageAfterOnDraw) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(gfx::Point(5, 5), viewport_size); @@ -11940,7 +11828,7 @@ TEST_F(LayerTreeHostImplTest, FullViewportDamageAfterOnDraw) { EXPECT_EQ(draw_viewport, host_impl_->active_tree()->GetDeviceViewport()); host_impl_->SetFullViewportDamage(); - EXPECT_EQ(gfx::Rect(viewport_size), + EXPECT_EQ(host_impl_->active_tree()->internal_device_viewport(), host_impl_->viewport_damage_rect_for_testing()); } @@ -11957,7 +11845,7 @@ TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, host_impl_->active_tree()->BuildPropertyTreesForTesting(); const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(viewport_size); @@ -11985,7 +11873,7 @@ TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, ResourcelessSoftwareDrawSkipsUpdateTiles) { const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreatePendingTree(); scoped_refptr<FakeRasterSource> raster_source( @@ -12024,7 +11912,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); const gfx::Size layer_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportSize(layer_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_size)); // Set up active and pending tree. CreatePendingTree(); @@ -12065,7 +11953,7 @@ TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { ->test_properties() ->children[0]; - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(90, 90)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(90, 90)); host_impl_->active_tree()->UpdateDrawProperties(); EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect()); @@ -12096,7 +11984,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { ->test_properties() ->children[0]; - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->UpdateDrawProperties(); EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect()); @@ -12142,7 +12030,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { test_layer->test_properties()->transform = perspective_transform; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->UpdateDrawProperties(); EffectNode* node = host_impl_->active_tree()->property_trees()->effect_tree.Node( @@ -12350,6 +12238,98 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWhileZoomed) { } } +TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { + LayerTreeSettings settings = DefaultSettings(); + settings.compositor_threaded_scrollbar_scrolling = true; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + + // Setup the viewport. + const gfx::Size viewport_size = gfx::Size(360, 600); + const gfx::Size content_size = gfx::Size(345, 3800); + CreateBasicVirtualViewportLayers(viewport_size, content_size); + LayerImpl* scroll_layer = host_impl_->OuterViewportScrollLayer(); + + // Set up the scrollbar and its dimensions. + LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); + std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar = + PaintedScrollbarLayerImpl::Create(layer_tree_impl, 99, VERTICAL, false, + true); + const gfx::Size scrollbar_size = gfx::Size(15, 600); + scrollbar->SetBounds(scrollbar_size); + scrollbar->test_properties()->position = gfx::PointF(345, 0); + scrollbar->SetScrollElementId(scroll_layer->element_id()); + scrollbar->SetDrawsContent(true); + scrollbar->SetHitTestable(true); + scrollbar->test_properties()->opacity = 1.f; + + // Set up the thumb dimensions. + scrollbar->SetThumbThickness(15); + scrollbar->SetThumbLength(50); + scrollbar->SetTrackStart(15); + scrollbar->SetTrackLength(575); + + // Set up scrollbar arrows. + scrollbar->SetBackButtonRect( + gfx::Rect(gfx::Point(345, 0), gfx::Size(15, 15))); + scrollbar->SetForwardButtonRect( + gfx::Rect(gfx::Point(345, 570), gfx::Size(15, 15))); + + // Add the scrollbar to the outer viewport. + scroll_layer->test_properties()->AddChild(std::move(scrollbar)); + + host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl_->ScrollBegin(BeginState(gfx::Point(350, 18)).get(), + InputHandler::SCROLLBAR); + TestInputHandlerClient input_handler_client; + host_impl_->BindToClient(&input_handler_client); + + // ------------------------- Start frame 0 ------------------------- + base::TimeTicks start_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(200); + viz::BeginFrameArgs begin_frame_args = + viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); + begin_frame_args.frame_time = start_time; + begin_frame_args.sequence_number++; + host_impl_->WillBeginImplFrame(begin_frame_args); + + // MouseDown on the thumb should not produce a scroll. + InputHandlerPointerResult result = + host_impl_->MouseDown(gfx::PointF(350, 18)); + EXPECT_EQ(result.scroll_offset.y(), 0u); + + // The first request for a GSU should be processed as expected. + result = host_impl_->MouseMoveAt(gfx::Point(350, 19)); + EXPECT_GT(result.scroll_offset.y(), 0u); + + // A second request for a GSU within the same frame should be ignored as it + // will cause the thumb drag to become jittery. The reason this happens is + // because when the first GSU is processed, it gets queued in the compositor + // thread event queue. So a second request within the same frame will end up + // calculating an incorrect delta (as ComputeThumbQuadRect would not have + // accounted for the delta in the first GSU that was not yet dispatched). + result = host_impl_->MouseMoveAt(gfx::Point(350, 20)); + EXPECT_EQ(result.scroll_offset.y(), 0u); + host_impl_->DidFinishImplFrame(); + + // ------------------------- Start frame 1 ------------------------- + begin_frame_args.frame_time = + start_time + base::TimeDelta::FromMilliseconds(250); + begin_frame_args.sequence_number++; + host_impl_->WillBeginImplFrame(begin_frame_args); + + // MouseMove for a new frame gets processed as usual. + result = host_impl_->MouseMoveAt(gfx::Point(350, 21)); + EXPECT_GT(result.scroll_offset.y(), 0u); + + // MouseUp is not expected to have a delta. + result = host_impl_->MouseUp(gfx::PointF(350, 21)); + EXPECT_EQ(result.scroll_offset.y(), 0u); + + // Tear down the LayerTreeHostImpl before the InputHandlerClient. + host_impl_->ReleaseLayerTreeFrameSink(); + host_impl_ = nullptr; +} + TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); @@ -12993,7 +12973,7 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(50, 50)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); @@ -13535,27 +13515,34 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { host_impl_->active_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); // SetPageScaleOnActiveTree also updates the factors in property trees. - EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f); + EXPECT_TRUE(active_tree_node->local.IsScale2d()); + EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); + EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); EXPECT_EQ(host_impl_->active_tree()->current_page_scale_factor(), 2.f); TransformNode* pending_tree_node = host_impl_->pending_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); - EXPECT_EQ(pending_tree_node->post_local_scale_factor, 1.f); + EXPECT_TRUE(pending_tree_node->local.IsIdentity()); + EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f); host_impl_->pending_tree()->UpdateDrawProperties(); pending_tree_node = host_impl_->pending_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); - EXPECT_EQ(pending_tree_node->post_local_scale_factor, 2.f); + EXPECT_TRUE(pending_tree_node->local.IsScale2d()); + EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), pending_tree_node->local.Scale2d()); + EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); host_impl_->ActivateSyncTree(); host_impl_->active_tree()->UpdateDrawProperties(); active_tree_node = host_impl_->active_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); - EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f); + EXPECT_TRUE(active_tree_node->local.IsScale2d()); + EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); + EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); } TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { @@ -13591,7 +13578,7 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { } TEST_F(LayerTreeHostImplTest, JitterTest) { - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); CreatePendingTree(); CreateScrollAndContentsLayers(host_impl_->pending_tree(), @@ -13704,7 +13691,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( viewport_size); @@ -13979,7 +13966,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportSize(layer_size); + pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); pending_tree->SetRootLayerForTesting( FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, raster_source)); @@ -14056,7 +14043,7 @@ TEST_F(LayerTreeHostImplTest, RasterColorSpaceSoftware) { TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - host_impl_->active_tree()->SetDeviceViewportSize(layer_bounds); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); std::unique_ptr<LayerImpl> scoped_root = LayerImpl::Create(host_impl_->pending_tree(), 1); @@ -14115,7 +14102,7 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { TEST_F(LayerTreeHostImplTest, RasterTilePrioritizationForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - host_impl_->active_tree()->SetDeviceViewportSize(layer_bounds); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); std::unique_ptr<LayerImpl> scoped_root = LayerImpl::Create(host_impl_->pending_tree(), 1); @@ -14290,6 +14277,151 @@ class TestRenderFrameMetadataObserver : public RenderFrameMetadataObserver { base::Optional<RenderFrameMetadata> last_metadata_; }; +TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { + SetupScrollAndContentsLayers(gfx::Size(100, 100)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); + + { + // Check initial metadata is correct. + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + + EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset); + EXPECT_EQ(1.f, metadata.page_scale_factor); + +#if defined(OS_ANDROID) + EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size); + EXPECT_EQ(0.5f, metadata.min_page_scale_factor); + EXPECT_EQ(4.f, metadata.max_page_scale_factor); + EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); + EXPECT_FALSE(metadata.root_overflow_y_hidden); +#endif + } + + // Scrolling should update metadata immediately. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) + .thread); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); + { + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); + } + host_impl_->ScrollEnd(EndState().get()); + { + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); + } + +#if defined(OS_ANDROID) + // Root "overflow: hidden" properties should be reflected on the outer + // viewport scroll layer. + { + host_impl_->active_tree() + ->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_horizontal = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_FALSE(metadata.root_overflow_y_hidden); + } + + { + host_impl_->active_tree() + ->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_vertical = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_TRUE(metadata.root_overflow_y_hidden); + } + + // Re-enable scrollability and verify that overflows are no longer + // hidden. + { + host_impl_->active_tree() + ->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_horizontal = true; + host_impl_->active_tree() + ->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_vertical = true; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_FALSE(metadata.root_overflow_y_hidden); + } + + // Root "overflow: hidden" properties should also be reflected on the + // inner viewport scroll layer. + { + host_impl_->active_tree() + ->InnerViewportScrollLayer() + ->test_properties() + ->user_scrollable_horizontal = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_FALSE(metadata.root_overflow_y_hidden); + } + + { + host_impl_->active_tree() + ->InnerViewportScrollLayer() + ->test_properties() + ->user_scrollable_vertical = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + EXPECT_TRUE(metadata.root_overflow_y_hidden); + } +#endif + + // Page scale should update metadata correctly (shrinking only the viewport). + host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::TOUCHSCREEN); + host_impl_->PinchGestureBegin(); + host_impl_->PinchGestureUpdate(2.f, gfx::Point()); + host_impl_->PinchGestureEnd(gfx::Point(), true); + host_impl_->ScrollEnd(EndState().get()); + { + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + + EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); + EXPECT_EQ(2.f, metadata.page_scale_factor); + +#if defined(OS_ANDROID) + EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size); + EXPECT_EQ(0.5f, metadata.min_page_scale_factor); + EXPECT_EQ(4.f, metadata.max_page_scale_factor); + EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); +#endif + } + + // Likewise if set from the main thread. + host_impl_->ProcessScrollDeltas(); + host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f); + host_impl_->active_tree()->SetPageScaleOnActiveTree(4.f); + { + RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); + + EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); + EXPECT_EQ(4.f, metadata.page_scale_factor); + +#if defined(OS_ANDROID) + EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size); + EXPECT_EQ(0.5f, metadata.min_page_scale_factor); + EXPECT_EQ(4.f, metadata.max_page_scale_factor); + EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); +#endif + } +} + TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { const int root_layer_id = 1; std::unique_ptr<SolidColorLayerImpl> root = @@ -14424,7 +14556,7 @@ TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) { // Setup surface layers in LayerTreeHostImpl. host_impl_->CreatePendingTree(); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); @@ -14468,7 +14600,7 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) { std::unique_ptr<LayerImpl> overlapping_layer = LayerImpl::Create(host_impl_->active_tree(), 5); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); intermediate_layer->test_properties()->position = gfx::PointF(200, 300); intermediate_layer->SetBounds(gfx::Size(200, 200)); @@ -14583,7 +14715,7 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, PointerEvents) { std::unique_ptr<SurfaceLayerImpl> surface_child2 = SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); @@ -14663,7 +14795,7 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, ComplexPage) { std::unique_ptr<SurfaceLayerImpl> surface_child = SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); surface_child->test_properties()->position = gfx::PointF(0, 0); surface_child->SetBounds(gfx::Size(100, 100)); @@ -14746,7 +14878,7 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, InvalidFrameSinkId) { std::unique_ptr<SurfaceLayerImpl> surface_child1 = SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - host_impl_->active_tree()->SetDeviceViewportSize(gfx::Size(1024, 768)); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); @@ -14876,7 +15008,7 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) { gfx::Size scroll_content_size = gfx::Size(360, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportSize(viewport_size); + host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); root->SetBounds(viewport_size); root->test_properties()->position = gfx::PointF(); @@ -14972,11 +15104,11 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { // Set up a result to have been 'painted'. ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u); - scoped_refptr<PaintWorkletInput> input = + scoped_refptr<const PaintWorkletInput> input = root->GetPaintWorkletRecordMap().begin()->first; int worklet_id = input->WorkletId(); - PaintWorkletJob painted_job(worklet_id, input); + PaintWorkletJob painted_job(worklet_id, input, {}); sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>(); painted_job.SetOutput(record); @@ -14988,7 +15120,8 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { // Finally, 'paint' the content. This should unlock tile preparation and // update the PictureLayerImpl's map. std::move(painter->TakeDoneCallback()).Run(std::move(painted_job_map)); - EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second, record); + EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second.second, + record); EXPECT_TRUE(did_prepare_tiles_); } @@ -15079,11 +15212,11 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, // Set up a result to have been 'painted'. ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u); - scoped_refptr<PaintWorkletInput> input = + scoped_refptr<const PaintWorkletInput> input = root->GetPaintWorkletRecordMap().begin()->first; int worklet_id = input->WorkletId(); - PaintWorkletJob painted_job(worklet_id, input); + PaintWorkletJob painted_job(worklet_id, input, {}); sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>(); painted_job.SetOutput(record); @@ -15097,7 +15230,8 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, // updated, but since the tree was force activated there should be no tile // preparation. std::move(painter->TakeDoneCallback()).Run(std::move(painted_job_map)); - EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second, record); + EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second.second, + record); EXPECT_FALSE(did_prepare_tiles_); } diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index c6036f13f59..379d099def3 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -150,7 +150,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { void BuildTree() override { gfx::Size viewport = gfx::Size(720, 1038); - layer_tree_host()->SetViewportSizeAndScale(viewport, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport), 1.f, viz::LocalSurfaceIdAllocation()); scoped_refptr<Layer> root = ParseTreeFromJson(json_, &fake_content_layer_client_); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 7d5ea2a2d08..6c045aa5ff5 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -151,7 +151,7 @@ class LayerTreeHostBlendingPixelTest PaintImage::GetNextContentId()) .TakePaintImage(), SkMatrix::I(), false); - layer->SetMaskLayer(mask.get()); + layer->SetMaskLayer(mask); } void SetupColorMatrix(scoped_refptr<Layer> layer) { diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index 3ac848ed527..b43b7336343 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -81,13 +81,6 @@ INSTANTIATE_TEST_SUITE_P(, LayerTreeHostFiltersPixelTest, ::testing::ValuesIn(kRendererTypes)); -using LayerTreeHostFiltersPixelTestGL = LayerTreeHostFiltersPixelTest; - -// TODO(crbug.com/948128): Enable these tests for Skia. -INSTANTIATE_TEST_SUITE_P(, - LayerTreeHostFiltersPixelTestGL, - ::testing::Values(LayerTreeTest::RENDERER_GL)); - using LayerTreeHostFiltersPixelTestGPU = LayerTreeHostFiltersPixelTest; LayerTreeTest::RendererType const kRendererTypesGpu[] = { @@ -287,7 +280,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) { base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_outsets.png"))); } -TEST_P(LayerTreeHostFiltersPixelTestGL, BackdropFilterBlurOffAxis) { +TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT); @@ -356,7 +349,8 @@ TEST_P(LayerTreeHostFiltersPixelTestGL, BackdropFilterBlurOffAxis) { RunPixelTest( renderer_type(), background, - base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis.png"))); + base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis_.png")) + .InsertBeforeExtensionASCII(GetRendererSuffix())); } TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBoundsWithChildren) { diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index 1dcc664c201..ba32c9bdd0c 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -94,6 +94,7 @@ class MaskContentLayerClient : public ContentLayerClient { } private: + base::OnceClosure custom_setup_tree_; gfx::Size bounds_; }; @@ -111,7 +112,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); - green->SetMaskLayer(mask.get()); + green->SetMaskLayer(mask); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true); @@ -119,137 +120,72 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png"))); } -class LayerTreeHostLayerListPixelTest : public ParameterizedPixelResourceTest { +class LayerTreeHostMaskPixelTestWithLayerList + : public ParameterizedPixelResourceTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_layer_lists = true; - settings->gpu_rasterization_forced = use_vulkan(); + LayerTreeHostMaskPixelTestWithLayerList() : mask_bounds_(50, 50) { + SetUseLayerLists(); } + + // Setup three layers for testing masks: a white background, a green layer, + // and a mask layer with kDstIn blend mode. + void SetupTree() override { + SetInitialRootBounds(gfx::Size(100, 100)); + ParameterizedPixelResourceTest::SetupTree(); + + Layer* root = layer_tree_host()->root_layer(); + + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); + + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); + CopyProperties(background.get(), green.get()); + auto& isolation_effect = CreateEffectNode(green.get()); + isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; + root->AddChild(green); + + DCHECK(mask_layer_) << "The test should create mask_layer_ before calling " + << "RunPixelResourceTestWithLayerList()"; + mask_layer_->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); + mask_layer_->SetBounds(mask_bounds_); + mask_layer_->SetIsDrawable(true); + CopyProperties(green.get(), mask_layer_.get()); + auto& mask_effect = CreateEffectNode(mask_layer_.get()); + mask_effect.blend_mode = SkBlendMode::kDstIn; + root->AddChild(mask_layer_); + } + + gfx::Size mask_bounds_; + scoped_refptr<Layer> mask_layer_; }; INSTANTIATE_TEST_SUITE_P(PixelResourceTest, - LayerTreeHostLayerListPixelTest, + LayerTreeHostMaskPixelTestWithLayerList, CombineWithLayerMaskTypes(kTestCases)); -TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffect) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 2; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); - - gfx::Size mask_bounds(50, 50); - MaskContentLayerClient client(mask_bounds); - - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); +TEST_P(LayerTreeHostMaskPixelTestWithLayerList, MaskWithEffect) { + MaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); - RunPixelResourceTestWithLayerList( - root_layer, base::FilePath(FILE_PATH_LITERAL("mask_with_effect.png")), - &property_trees); + base::FilePath(FILE_PATH_LITERAL("mask_with_effect.png"))); } // This tests that a solid color empty layer with mask effect works correctly. -TEST_P(LayerTreeHostLayerListPixelTest, SolidColorLayerEmptyMaskWithEffect) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 3; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); - +TEST_P(LayerTreeHostMaskPixelTestWithLayerList, + SolidColorLayerEmptyMaskWithEffect) { // Apply a mask that is empty and solid-color. This should result in // the green layer being entirely clipped out. - gfx::Size mask_bounds(50, 50); - scoped_refptr<SolidColorLayer> mask = + mask_layer_ = CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), SK_ColorTRANSPARENT); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); - RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath( - FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png")), - &property_trees); + RunPixelResourceTestWithLayerList(base::FilePath( + FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png"))); } class SolidColorEmptyMaskContentLayerClient : public ContentLayerClient { @@ -275,304 +211,110 @@ class SolidColorEmptyMaskContentLayerClient : public ContentLayerClient { gfx::Size bounds_; }; -TEST_P(LayerTreeHostLayerListPixelTest, SolidColorEmptyMaskWithEffect) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 3; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); - +TEST_P(LayerTreeHostMaskPixelTestWithLayerList, SolidColorEmptyMaskWithEffect) { // Apply a mask that is empty and solid-color. This should result in // the green layer being entirely clipped out. - gfx::Size mask_bounds(50, 50); - SolidColorEmptyMaskContentLayerClient client(mask_bounds); - - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); + SolidColorEmptyMaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); - RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath( - FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png")), - &property_trees); + RunPixelResourceTestWithLayerList(base::FilePath( + FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png"))); } -// same as SolidColorEmptyMaskWithEffect, except the mask has a render surface. -TEST_P(LayerTreeHostLayerListPixelTest, - SolidColorEmptyMaskWithEffectAndRenderSurface) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 3; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - mask_effect.render_surface_reason = RenderSurfaceReason::kTest; - property_trees.effect_tree.Insert(mask_effect, 2); +// Same as SolidColorEmptyMaskWithEffect, except the mask has a render surface. +class LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface + : public LayerTreeHostMaskPixelTestWithLayerList { + protected: + void SetupTree() override { + LayerTreeHostMaskPixelTestWithLayerList::SetupTree(); - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); + auto* effect = layer_tree_host()->property_trees()->effect_tree.Node( + mask_layer_->effect_tree_index()); + effect->render_surface_reason = RenderSurfaceReason::kTest; + } +}; + +INSTANTIATE_TEST_SUITE_P( + PixelResourceTest, + LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, + CombineWithLayerMaskTypes(kTestCases)); +TEST_P(LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, + Test) { // Apply a mask that is empty and solid-color. This should result in // the green layer being entirely clipped out. - gfx::Size mask_bounds(50, 50); - SolidColorEmptyMaskContentLayerClient client(mask_bounds); + SolidColorEmptyMaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); - - RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath( - FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png")), - &property_trees); + RunPixelResourceTestWithLayerList(base::FilePath( + FILE_PATH_LITERAL("solid_color_empty_mask_with_effect.png"))); } // Tests a situation in which there is no other content in the target // render surface that the mask applies to. In this situation, the mask // should have no effect on the rendered output. -TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectNoContentToMask) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 2; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorRED); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); +class LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask + : public LayerTreeHostMaskPixelTestWithLayerList { + protected: + void SetupTree() override { + LayerTreeHostMaskPixelTestWithLayerList::SetupTree(); + + LayerList layers = layer_tree_host()->root_layer()->children(); + DCHECK_EQ(3u, layers.size()); + // Set background to red. + layers[0]->SetBackgroundColor(SK_ColorRED); + // Remove the green layer. + layers.erase(layers.begin() + 1); + layer_tree_host()->root_layer()->SetChildLayerList(layers); + } +}; - gfx::Size mask_bounds(50, 50); - MaskContentLayerClient client(mask_bounds); +INSTANTIATE_TEST_SUITE_P( + PixelResourceTest, + LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, + CombineWithLayerMaskTypes(kTestCases)); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(0, 0)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); +TEST_P(LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, Test) { + MaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath(FILE_PATH_LITERAL("mask_with_effect_no_content.png")), - &property_trees); + base::FilePath(FILE_PATH_LITERAL("mask_with_effect_no_content.png"))); } -TEST_P(LayerTreeHostLayerListPixelTest, ScaledMaskWithEffect) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 2; - mask_effect.transform_id = 2; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - +class LayerTreeHostMaskPixelTest_ScaledMaskWithEffect + : public LayerTreeHostMaskPixelTestWithLayerList { + protected: // Scale the mask with a non-integral transform. This will trigger the // AA path in the renderer. - TransformTree& transform_tree = property_trees.transform_tree; - auto& transform_node = - *transform_tree.Node(transform_tree.Insert(TransformNode(), 1)); - transform_node.source_node_id = transform_node.parent_id; - transform_node.local = gfx::Transform(); - transform_node.local.Scale(1.5, 1.5); + void SetupTree() override { + LayerTreeHostMaskPixelTestWithLayerList::SetupTree(); - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); + auto& transform = CreateTransformNode(mask_layer_.get()); + transform.local.Scale(1.5, 1.5); + } +}; - gfx::Size mask_bounds(50, 50); - MaskContentLayerClient client(mask_bounds); +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, + CombineWithLayerMaskTypes(kTestCases)); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(2); - root_layer->AddChild(mask); +TEST_P(LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, Test) { + MaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); RunPixelResourceTestWithLayerList( - root_layer, base::FilePath(FILE_PATH_LITERAL("scaled_mask_with_effect_.png")) - .InsertBeforeExtensionASCII(GetRendererSuffix()), - &property_trees); + .InsertBeforeExtensionASCII(GetRendererSuffix())); } -TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectDifferentSize) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 2; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); - - gfx::Size mask_bounds(25, 25); - MaskContentLayerClient client(mask_bounds); - - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); - root_layer->AddChild(mask); +TEST_P(LayerTreeHostMaskPixelTestWithLayerList, MaskWithEffectDifferentSize) { + mask_bounds_ = gfx::Size(25, 25); + MaskContentLayerClient client(mask_bounds_); + mask_layer_ = PictureLayer::Create(&client); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); @@ -580,61 +322,12 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectDifferentSize) { // The mask is half the size of thing it's masking. In layer-list mode, // the mask is not automatically scaled to match the other layer. RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath(FILE_PATH_LITERAL("mask_with_effect_different_size.png")), - &property_trees); + base::FilePath(FILE_PATH_LITERAL("mask_with_effect_different_size.png"))); } -TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) { - PropertyTrees property_trees; - scoped_refptr<Layer> root_layer; - InitializeForLayerListMode(&root_layer, &property_trees); - - EffectNode isolation_effect; - isolation_effect.clip_id = 1; - isolation_effect.stable_id = 2; - isolation_effect.render_surface_reason = RenderSurfaceReason::kTest; - isolation_effect.transform_id = 1; - property_trees.effect_tree.Insert(isolation_effect, 1); - - EffectNode mask_effect; - mask_effect.clip_id = 1; - mask_effect.stable_id = 2; - mask_effect.transform_id = 1; - mask_effect.blend_mode = SkBlendMode::kDstIn; - property_trees.effect_tree.Insert(mask_effect, 2); - - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - background->set_property_tree_sequence_number(property_trees.sequence_number); - background->SetClipTreeIndex(1); - background->SetEffectTreeIndex(1); - background->SetScrollTreeIndex(1); - background->SetTransformTreeIndex(1); - root_layer->AddChild(background); - - scoped_refptr<SolidColorLayer> green = - CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen); - green->set_property_tree_sequence_number(property_trees.sequence_number); - green->SetClipTreeIndex(1); - green->SetEffectTreeIndex(2); - green->SetScrollTreeIndex(1); - green->SetTransformTreeIndex(1); - - root_layer->AddChild(green); - - gfx::Size mask_bounds(50, 50); - MaskContentLayerClient client(mask_bounds); - - scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); - mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); - mask->set_property_tree_sequence_number(property_trees.sequence_number); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetClipTreeIndex(1); - mask->SetEffectTreeIndex(3); - mask->SetScrollTreeIndex(1); - mask->SetTransformTreeIndex(1); +TEST_P(LayerTreeHostMaskPixelTestWithLayerList, ImageMaskWithEffect) { + MaskContentLayerClient client(mask_bounds_); + scoped_refptr<PictureImageLayer> mask_layer = PictureImageLayer::Create(); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200); SkCanvas* canvas = surface->getCanvas(); @@ -643,13 +336,13 @@ TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) { client.PaintContentsToDisplayList( ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); mask_display_list->Raster(canvas); - mask->SetImage(PaintImageBuilder::WithDefault() - .set_id(PaintImage::GetNextId()) - .set_image(surface->makeImageSnapshot(), - PaintImage::GetNextContentId()) - .TakePaintImage(), - SkMatrix::I(), false); - root_layer->AddChild(mask); + mask_layer->SetImage(PaintImageBuilder::WithDefault() + .set_id(PaintImage::GetNextId()) + .set_image(surface->makeImageSnapshot(), + PaintImage::GetNextContentId()) + .TakePaintImage(), + SkMatrix::I(), false); + mask_layer_ = mask_layer; pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); @@ -657,9 +350,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) { // The mask is half the size of thing it's masking. In layer-list mode, // the mask is not automatically scaled to match the other layer. RunPixelResourceTestWithLayerList( - root_layer, - base::FilePath(FILE_PATH_LITERAL("image_mask_with_effect.png")), - &property_trees); + base::FilePath(FILE_PATH_LITERAL("image_mask_with_effect.png"))); } TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { @@ -690,7 +381,7 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK); - green->SetMaskLayer(mask.get()); + green->SetMaskLayer(mask); background->AddChild(green); pixel_comparator_ = @@ -721,7 +412,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); - green->SetMaskLayer(mask.get()); + green->SetMaskLayer(mask); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); @@ -746,7 +437,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerNonExactTextureSize) { mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); mask->set_fixed_tile_size(gfx::Size(173, 135)); - green->SetMaskLayer(mask.get()); + green->SetMaskLayer(mask); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */); @@ -880,7 +571,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); - blur->SetMaskLayer(mask.get()); + blur->SetMaskLayer(mask); CHECK_EQ(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, mask->mask_type()); base::FilePath image_name = @@ -935,7 +626,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); - picture_horizontal->SetMaskLayer(mask.get()); + picture_horizontal->SetMaskLayer(mask); float percentage_pixels_large_error = 0.04f; // 0.04%, ~6px / (128*128) float percentage_pixels_small_error = 0.0f; @@ -1358,7 +1049,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetLayerMaskType(mask_type_); - picture_horizontal->SetMaskLayer(mask.get()); + picture_horizontal->SetMaskLayer(mask); base::FilePath result_path( FILE_PATH_LITERAL("mask_of_backdrop_filter_and_blend_.png")); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index 0da4873f16f..e87aef895c7 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -238,7 +238,9 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidationMultiThread, FullRaster) { using LayerTreeHostTilesTestPartialInvalidationLowBitDepth = LayerTreeHostTilesTestPartialInvalidation; -// TODO(crbug.com/963446): Enable these tests for Vulkan. +// This test doesn't work on Vulkan because on our hardware we can't render to +// RGBA4444 format using either SwiftShader or native Vulkan. See +// crbug.com/987278 for details INSTANTIATE_TEST_SUITE_P( , LayerTreeHostTilesTestPartialInvalidationLowBitDepth, diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 023517fc874..aec7ad3b5db 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -99,7 +99,7 @@ bool LayerSubtreeHasCopyRequest(Layer* layer) { return node->subtree_has_copy_request; } -class LayerTreeHostTest : public LayerTreeTest {}; +using LayerTreeHostTest = LayerTreeTest; class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest { public: @@ -136,8 +136,6 @@ class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest { EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout); @@ -253,8 +251,6 @@ class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest { // SetNeeds{Animate,UpdateLayers,Commit}() will mean a MainFrame is pending. EXPECT_TRUE(layer_tree_host()->RequestedMainFramePendingForTesting()); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestedMainFrame); @@ -272,8 +268,6 @@ class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest { EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout); @@ -536,7 +530,6 @@ class LayerTreeHostContextCacheTest : public LayerTreeHostTest { } void BeginTest() override {} - void AfterTest() override {} protected: class MockContextSupport : public viz::TestContextSupport { @@ -622,6 +615,11 @@ MULTI_THREAD_TEST_F( class LayerTreeHostFreeContextResourcesOnDestroy : public LayerTreeHostContextCacheTest { public: + void InitializeSettings(LayerTreeSettings* settings) override { + // TODO(crbug.com/985009): Fix test with surface sync enabled. + settings->enable_surface_synchronization = false; + } + void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const viz::BeginFrameArgs& args) override { // Ensure that our initialization expectations have completed. @@ -763,9 +761,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { protected: void SetupTree() override { - scoped_refptr<Layer> root = Layer::Create(); - root->SetBounds(gfx::Size(10, 10)); - layer_tree_host()->SetRootLayer(root); + SetInitialRootBounds(gfx::Size(10, 10)); LayerTreeHostTest::SetupTree(); } @@ -799,8 +795,6 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { SetAfterValues(layer_tree_host()->root_layer()); } - void AfterTest() override {} - void VerifyBeforeValues(Layer* layer) { EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); EXPECT_FALSE(layer->hide_layer_and_subtree()); @@ -949,8 +943,6 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest { } } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; scoped_refptr<Layer> child_; @@ -1050,8 +1042,6 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; scoped_refptr<Layer> child_; @@ -1133,8 +1123,6 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { return draw_result; } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; scoped_refptr<Layer> child_; @@ -1145,42 +1133,36 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_layer_lists = true; - } + LayerTreeHostTestLayerListSurfaceDamage() { SetUseLayerLists(); } void SetupTree() override { - root_ = Layer::Create(); - child_a_ = Layer::Create(); - child_b_ = Layer::Create(); - child_c_ = Layer::Create(); - - layer_tree_host()->SetRootLayer(root_); - - root_->AddChild(child_a_); - root_->AddChild(child_b_); - root_->AddChild(child_c_); - - root_->SetBounds(gfx::Size(50, 50)); + SetInitialRootBounds(gfx::Size(50, 50)); + LayerTreeHostTest::SetupTree(); + root_ = layer_tree_host()->root_layer(); + child_a_ = Layer::Create(); child_a_->SetBounds(gfx::Size(10, 20)); - child_a_->SetForceRenderSurfaceForTesting(true); child_a_->SetIsDrawable(true); + CopyProperties(root_, child_a_.get()); + auto& effect_a = CreateEffectNode(child_a_.get()); + effect_a.render_surface_reason = RenderSurfaceReason::kTest; + root_->AddChild(child_a_); + child_b_ = Layer::Create(); child_b_->SetBounds(gfx::Size(20, 10)); - child_b_->SetForceRenderSurfaceForTesting(true); child_b_->SetIsDrawable(true); + CopyProperties(root_, child_b_.get()); + auto& effect_b = CreateEffectNode(child_b_.get()); + effect_b.render_surface_reason = RenderSurfaceReason::kTest; + root_->AddChild(child_b_); + child_c_ = Layer::Create(); child_c_->SetBounds(gfx::Size(15, 15)); - child_c_->SetForceRenderSurfaceForTesting(true); child_c_->SetIsDrawable(true); - - // TODO(pdr): Do not use the property tree builder for testing in layer list - // mode. This will require rewriting this test to manually build property - // trees. - layer_tree_host()->BuildPropertyTreesForTesting(); - - LayerTreeHostTest::SetupTree(); + CopyProperties(root_, child_c_.get()); + auto& effect_c = CreateEffectNode(child_c_.get()); + effect_c.render_surface_reason = RenderSurfaceReason::kTest; + root_->AddChild(child_c_); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1298,10 +1280,8 @@ class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest { return draw_result; } - void AfterTest() override {} - private: - scoped_refptr<Layer> root_; + Layer* root_; scoped_refptr<Layer> child_a_; scoped_refptr<Layer> child_b_; scoped_refptr<Layer> child_c_; @@ -1319,19 +1299,21 @@ class LayerTreeHostTestNoDamageCausesNoInvalidate : public LayerTreeHostTest { protected: void SetupTree() override { - root_ = Layer::Create(); + scoped_refptr<Layer> root = Layer::Create(); + layer_ = Layer::Create(); + root->AddChild(layer_); - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f, viz::LocalSurfaceIdAllocation()); - - layer_tree_host()->SetRootLayer(root_); + layer_tree_host()->SetRootLayer(root); // Translate the root layer past the viewport. gfx::Transform translation; translation.Translate(100, 100); - root_->SetTransform(translation); + layer_->SetTransform(translation); - root_->SetBounds(gfx::Size(50, 50)); + root->SetBounds(gfx::Size(50, 50)); + layer_->SetBounds(gfx::Size(50, 50)); LayerTreeHostTest::SetupTree(); } @@ -1342,7 +1324,7 @@ class LayerTreeHostTestNoDamageCausesNoInvalidate : public LayerTreeHostTest { // This does not damage the frame because the root layer is outside the // viewport. if (layer_tree_host()->SourceFrameNumber() == 2) - root_->SetOpacity(0.9f); + layer_->SetOpacity(0.9f); } DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl, @@ -1382,10 +1364,8 @@ class LayerTreeHostTestNoDamageCausesNoInvalidate : public LayerTreeHostTest { } } - void AfterTest() override {} - private: - scoped_refptr<Layer> root_; + scoped_refptr<Layer> layer_; bool first_frame_invalidate_before_commit_ = false; }; @@ -1418,7 +1398,7 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest { child_ = Layer::Create(); root_->AddChild(child_); - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(100, 100), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(100, 100), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->SetRootLayer(root_); @@ -1506,7 +1486,7 @@ class LayerTreeHostTestPrepareTilesWithoutDraw : public LayerTreeHostTest { child_layer_ = Layer::Create(); layer_tree_host()->root_layer()->AddChild(child_layer_); - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->root_layer()->SetBounds(gfx::Size(50, 50)); @@ -1597,8 +1577,6 @@ class LayerTreeHostTestCantDrawBeforeCommit : public LayerTreeHostTest { EXPECT_TRUE(host_impl->CanDraw()); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCantDrawBeforeCommit); @@ -1620,8 +1598,6 @@ class LayerTreeHostTestCantDrawBeforeCommitActivate : public LayerTreeHostTest { EXPECT_TRUE(host_impl->CanDraw()); EndTest(); } - - void AfterTest() override {} }; // Single thread mode commits directly to the active tree, so CanDraw() @@ -1714,8 +1690,6 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { } } - void AfterTest() override {} - private: int index_; scoped_refptr<Layer> root_; @@ -1724,46 +1698,16 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { SINGLE_THREAD_TEST_F(LayerTreeHostTestPropertyTreesChangedSync); -// Simple base class for tests that just need to mutate the layer tree -// host and observe results without any impl thread, multi-layer, or -// multi-frame antics. -class LayerTreeHostTestLayerListsTest : public LayerTreeHostTest { - public: - explicit LayerTreeHostTestLayerListsTest(bool use_layer_lists) - : use_layer_lists_(use_layer_lists) {} - - protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_layer_lists = use_layer_lists_; - } - - void SetupTree() override { - root_ = Layer::Create(); - layer_tree_host()->SetRootLayer(root_); - LayerTreeHostTest::SetupTree(); - } - - void AfterTest() override {} - - scoped_refptr<Layer> root_; - - private: - bool use_layer_lists_; -}; - class LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists - : public LayerTreeHostTestLayerListsTest { - public: - LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists() - : LayerTreeHostTestLayerListsTest(false) {} - + : public LayerTreeHostTest { protected: void BeginTest() override { - EXPECT_EQ(1.0f, root_->opacity()); - layer_tree_host()->SetElementOpacityMutated(root_->element_id(), + Layer* root = layer_tree_host()->root_layer(); + EXPECT_EQ(1.0f, root->opacity()); + layer_tree_host()->SetElementOpacityMutated(root->element_id(), ElementListType::ACTIVE, 0.3f); // When not using layer lists, opacity is stored on the layer. - EXPECT_EQ(0.3f, root_->opacity()); + EXPECT_EQ(0.3f, root->opacity()); EndTest(); } }; @@ -1772,40 +1716,31 @@ SINGLE_THREAD_TEST_F( LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists); class LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists - : public LayerTreeHostTestLayerListsTest { + : public LayerTreeHostTest { public: - LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists() - : LayerTreeHostTestLayerListsTest(true) {} + LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists() { + SetUseLayerLists(); + } protected: void BeginTest() override { - // Insert a dummy effect node to observe its mutation. This would - // normally have been created by PaintArtifactCompositor. - int effect_node_id = - layer_tree_host()->property_trees()->effect_tree.Insert( - EffectNode(), EffectTree::kInvalidNodeId); - layer_tree_host() - ->property_trees() - ->element_id_to_effect_node_index[root_->element_id()] = effect_node_id; - - EXPECT_EQ(1.0f, root_->opacity()); - EXPECT_EQ(1.0f, - layer_tree_host() - ->property_trees() - ->effect_tree.FindNodeFromElementId(root_->element_id()) - ->opacity); - - layer_tree_host()->SetElementOpacityMutated(root_->element_id(), + Layer* root = layer_tree_host()->root_layer(); + EXPECT_EQ(1.0f, root->opacity()); + EXPECT_EQ(1.0f, layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root->element_id()) + ->opacity); + + layer_tree_host()->SetElementOpacityMutated(root->element_id(), ElementListType::ACTIVE, 0.3f); // When using layer lists, we don't have to store the opacity on the layer. - EXPECT_EQ(1.0f, root_->opacity()); + EXPECT_EQ(1.0f, root->opacity()); // The opacity should have been set directly on the effect node instead. - EXPECT_EQ(0.3f, - layer_tree_host() - ->property_trees() - ->effect_tree.FindNodeFromElementId(root_->element_id()) - ->opacity); + EXPECT_EQ(0.3f, layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root->element_id()) + ->opacity); EndTest(); } }; @@ -1813,20 +1748,22 @@ class LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists); class LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists - : public LayerTreeHostTestLayerListsTest { - public: - LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists() - : LayerTreeHostTestLayerListsTest(false) {} - + : public LayerTreeHostTest { protected: + void InitializeSettings(LayerTreeSettings* settings) override { + // TODO(crbug.com/985009): Fix test with surface sync enabled. + settings->enable_surface_synchronization = false; + } + void BeginTest() override { - EXPECT_EQ(gfx::Transform(), root_->transform()); + Layer* root = layer_tree_host()->root_layer(); + EXPECT_EQ(gfx::Transform(), root->transform()); gfx::Transform expected_transform; expected_transform.Translate(42, 42); layer_tree_host()->SetElementTransformMutated( - root_->element_id(), ElementListType::ACTIVE, expected_transform); + root->element_id(), ElementListType::ACTIVE, expected_transform); // When not using layer lists, transform is stored on the layer. - EXPECT_EQ(expected_transform, root_->transform()); + EXPECT_EQ(expected_transform, root->transform()); EndTest(); } }; @@ -1835,44 +1772,36 @@ SINGLE_THREAD_TEST_F( LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists); class LayerTreeHostTestAnimationTransformMutatedUsingLayerLists - : public LayerTreeHostTestLayerListsTest { + : public LayerTreeHostTest { public: - LayerTreeHostTestAnimationTransformMutatedUsingLayerLists() - : LayerTreeHostTestLayerListsTest(true) {} + LayerTreeHostTestAnimationTransformMutatedUsingLayerLists() { + SetUseLayerLists(); + } protected: void BeginTest() override { - // Insert a dummy transform node to observe its mutation. This would - // normally have been created by PaintArtifactCompositor. - int transform_node_id = - layer_tree_host()->property_trees()->transform_tree.Insert( - TransformNode(), TransformTree::kInvalidNodeId); - layer_tree_host() - ->property_trees() - ->element_id_to_transform_node_index[root_->element_id()] = - transform_node_id; - - EXPECT_EQ(gfx::Transform(), root_->transform()); + Layer* root = layer_tree_host()->root_layer(); + EXPECT_EQ(gfx::Transform(), root->transform()); EXPECT_EQ(gfx::Transform(), layer_tree_host() ->property_trees() - ->transform_tree.FindNodeFromElementId(root_->element_id()) + ->transform_tree.FindNodeFromElementId(root->element_id()) ->local); gfx::Transform expected_transform; expected_transform.Translate(42, 42); layer_tree_host()->SetElementTransformMutated( - root_->element_id(), ElementListType::ACTIVE, expected_transform); + root->element_id(), ElementListType::ACTIVE, expected_transform); // When using layer lists, we don't have to store the transform on the // layer. - EXPECT_EQ(gfx::Transform(), root_->transform()); + EXPECT_EQ(gfx::Transform(), root->transform()); // The transform should have been set directly on the transform node // instead. EXPECT_EQ(expected_transform, layer_tree_host() ->property_trees() - ->transform_tree.FindNodeFromElementId(root_->element_id()) + ->transform_tree.FindNodeFromElementId(root->element_id()) ->local); EndTest(); } @@ -1881,21 +1810,18 @@ class LayerTreeHostTestAnimationTransformMutatedUsingLayerLists SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationTransformMutatedUsingLayerLists); class LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists - : public LayerTreeHostTestLayerListsTest { - public: - LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists() - : LayerTreeHostTestLayerListsTest(false) {} - + : public LayerTreeHostTest { protected: void BeginTest() override { + Layer* root = layer_tree_host()->root_layer(); FilterOperations filters; - EXPECT_EQ(FilterOperations(), root_->filters()); + EXPECT_EQ(FilterOperations(), root->filters()); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); layer_tree_host()->SetElementFilterMutated( - root_->element_id(), ElementListType::ACTIVE, filters); + root->element_id(), ElementListType::ACTIVE, filters); // When not using layer lists, filters are just stored directly on the // layer. - EXPECT_EQ(filters, root_->filters()); + EXPECT_EQ(filters, root->filters()); EndTest(); } }; @@ -1903,41 +1829,34 @@ class LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists); class LayerTreeHostTestAnimationFilterMutatedUsingLayerLists - : public LayerTreeHostTestLayerListsTest { + : public LayerTreeHostTest { public: - LayerTreeHostTestAnimationFilterMutatedUsingLayerLists() - : LayerTreeHostTestLayerListsTest(true) {} + LayerTreeHostTestAnimationFilterMutatedUsingLayerLists() { + SetUseLayerLists(); + } protected: void BeginTest() override { - // Insert a dummy effect node to observe its mutation. This would - // normally have been created by PaintArtifactCompositor. - int effect_node_id = - layer_tree_host()->property_trees()->effect_tree.Insert( - EffectNode(), EffectTree::kInvalidNodeId); - layer_tree_host() - ->property_trees() - ->element_id_to_effect_node_index[root_->element_id()] = effect_node_id; - - EXPECT_EQ(FilterOperations(), root_->filters()); + Layer* root = layer_tree_host()->root_layer(); + EXPECT_EQ(FilterOperations(), root->filters()); EXPECT_EQ(FilterOperations(), layer_tree_host() ->property_trees() - ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->effect_tree.FindNodeFromElementId(root->element_id()) ->filters); FilterOperations filters; filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); layer_tree_host()->SetElementFilterMutated( - root_->element_id(), ElementListType::ACTIVE, filters); + root->element_id(), ElementListType::ACTIVE, filters); // When using layer lists, we don't have to store the filters on the layer. - EXPECT_EQ(FilterOperations(), root_->filters()); + EXPECT_EQ(FilterOperations(), root->filters()); // The filter should have been set directly on the effect node instead. EXPECT_EQ(filters, layer_tree_host() ->property_trees() - ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->effect_tree.FindNodeFromElementId(root->element_id()) ->filters); EndTest(); } @@ -2042,8 +1961,6 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { } } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; FilterOperations blur_filter_; @@ -2056,8 +1973,14 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestEffectTreeSync); class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { protected: void SetupTree() override { - root_ = Layer::Create(); - layer_tree_host()->SetRootLayer(root_); + scoped_refptr<Layer> root = Layer::Create(); + layer_ = Layer::Create(); + // Force a transform node for the layer. + gfx::Transform rotate5; + rotate5.Rotate(5.f); + layer_->SetTransform(rotate5); + root->AddChild(layer_); + layer_tree_host()->SetRootLayer(root); LayerTreeHostTest::SetupTree(); } @@ -2066,7 +1989,7 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { void DidCommit() override { TransformTree& transform_tree = layer_tree_host()->property_trees()->transform_tree; - TransformNode* node = transform_tree.Node(root_->transform_tree_index()); + TransformNode* node = transform_tree.Node(layer_->transform_tree_index()); gfx::Transform rotate10; rotate10.Rotate(10.f); switch (layer_tree_host()->SourceFrameNumber()) { @@ -2090,17 +2013,16 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { TransformTree& transform_tree = impl->sync_tree()->property_trees()->transform_tree; - const LayerImpl* root_layer = impl->sync_tree()->root_layer_for_testing(); + const LayerImpl* layer = impl->sync_tree()->LayerById(layer_->id()); const TransformNode* node = - transform_tree.Node(root_layer->transform_tree_index()); + transform_tree.Node(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()->SetTransformMutated(root_layer->element_id(), - rotate20); + impl->sync_tree()->SetTransformMutated(layer->element_id(), rotate20); PostSetNeedsCommitToMainThread(); break; case 1: @@ -2109,8 +2031,7 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { break; case 2: EXPECT_EQ(node->local, rotate20); - impl->sync_tree()->SetTransformMutated(root_layer->element_id(), - rotate20); + impl->sync_tree()->SetTransformMutated(layer->element_id(), rotate20); PostSetNeedsCommitToMainThread(); break; case 3: @@ -2123,10 +2044,8 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { } } - void AfterTest() override {} - private: - scoped_refptr<Layer> root_; + scoped_refptr<Layer> layer_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeSync); @@ -2198,8 +2117,6 @@ class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest { } } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; scoped_refptr<Layer> child_; @@ -2238,7 +2155,7 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { child_layer_->SetBounds(gfx::Size(10, 10)); mask_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); mask_layer_->SetBounds(gfx::Size(10, 10)); - child_layer_->SetMaskLayer(mask_layer_.get()); + child_layer_->SetMaskLayer(mask_layer_); root->AddChild(child_layer_); layer_tree_host()->SetRootLayer(root); LayerTreeHostTest::SetupTree(); @@ -2259,7 +2176,7 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { EXPECT_EQ(child_layer_->update_count(), 0); layer_tree_host()->root_layer()->RemoveAllChildren(); - layer_tree_host()->root_layer()->SetMaskLayer(mask_layer_.get()); + layer_tree_host()->root_layer()->SetMaskLayer(mask_layer_); break; } } @@ -2281,8 +2198,6 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<UpdateCountingLayer> mask_layer_; scoped_refptr<UpdateCountingLayer> child_layer_; @@ -2339,7 +2254,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { root_layer_->SetIsDrawable(true); root_layer_->SetBounds(bounds_); layer_tree_host()->SetRootLayer(root_layer_); - layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds_), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); client_.set_bounds(root_layer_->bounds()); @@ -2395,20 +2310,23 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { void BeginTest() override { client_.set_fill_with_nonsolid_color(true); - root_layer_ = FakePictureLayer::Create(&client_); - root_layer_->SetIsDrawable(true); + scoped_refptr<Layer> root = Layer::Create(); + layer_ = FakePictureLayer::Create(&client_); + root->AddChild(layer_); + layer_->SetIsDrawable(true); gfx::Transform transform; // Translate the layer out of the viewport to force it to not update its // tile size via PushProperties. transform.Translate(10000.0, 10000.0); - root_layer_->SetTransform(transform); - root_layer_->SetBounds(bounds_); - layer_tree_host()->SetRootLayer(root_layer_); - layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f, - viz::LocalSurfaceIdAllocation()); + layer_->SetTransform(transform); + root->SetBounds(bounds_); + layer_->SetBounds(bounds_); + layer_tree_host()->SetRootLayer(root); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(bounds_), 1.f, GetCurrentLocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); - client_.set_bounds(root_layer_->bounds()); + client_.set_bounds(layer_->bounds()); } void InitializeSettings(LayerTreeSettings* settings) override { @@ -2419,12 +2337,12 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { if (num_draws_ == 2) { auto* pending_tree = host_impl->pending_tree(); auto* pending_layer_impl = static_cast<FakePictureLayerImpl*>( - pending_tree->root_layer_for_testing()); + pending_tree->LayerById(layer_->id())); EXPECT_NE(pending_layer_impl, nullptr); auto* active_tree = host_impl->pending_tree(); auto* active_layer_impl = static_cast<FakePictureLayerImpl*>( - active_tree->root_layer_for_testing()); + active_tree->LayerById(layer_->id())); EXPECT_NE(pending_layer_impl, nullptr); auto* active_tiling_set = active_layer_impl->picture_layer_tiling_set(); @@ -2440,8 +2358,9 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { void DidCommitAndDrawFrame() override { // On the second commit, resize the viewport. if (num_draws_ == 1) { - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(400, 64), 1.f, viz::LocalSurfaceIdAllocation()); + GenerateNewLocalSurfaceId(); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(400, 64), 1.f, GetCurrentLocalSurfaceIdAllocation()); } if (num_draws_ < 2) { layer_tree_host()->SetNeedsRedrawRect(invalid_rect_); @@ -2452,14 +2371,12 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { } } - void AfterTest() override {} - private: int num_draws_; const gfx::Size bounds_; const gfx::Rect invalid_rect_; FakeContentLayerClient client_; - scoped_refptr<FakePictureLayer> root_layer_; + scoped_refptr<FakePictureLayer> layer_; }; // As there's no pending tree in single-threaded case, this test should run @@ -2546,8 +2463,8 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate // Changing the device scale factor causes a commit. It also changes // the content bounds of |scrollbar_|, which should not generate // a second commit as a result. - layer_tree_host()->SetViewportSizeAndScale( - layer_tree_host()->device_viewport_size(), 4.f, + layer_tree_host()->SetViewportRectAndScale( + layer_tree_host()->device_viewport_rect(), 4.f, layer_tree_host()->local_surface_id_allocation_from_parent()); break; default: @@ -2557,8 +2474,6 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; @@ -2587,8 +2502,8 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest { void DidCommit() override { if (layer_tree_host()->SourceFrameNumber() == 1) { - layer_tree_host()->SetViewportSizeAndScale( - layer_tree_host()->device_viewport_size(), 4.f, + layer_tree_host()->SetViewportRectAndScale( + layer_tree_host()->device_viewport_rect(), 4.f, layer_tree_host()->local_surface_id_allocation_from_parent()); } } @@ -2623,8 +2538,6 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest { return draw_result; } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; @@ -2744,8 +2657,6 @@ class LayerTreeHostTestRasterColorSpaceChange : public LayerTreeHostTest { } } - void AfterTest() override {} - private: gfx::ColorSpace space1_; gfx::ColorSpace space2_; @@ -2767,7 +2678,7 @@ class LayerTreeHostTestSetNeedsCommitWithForcedRedraw root_layer_->SetIsDrawable(true); root_layer_->SetBounds(bounds_); layer_tree_host()->SetRootLayer(root_layer_); - layer_tree_host()->SetViewportSizeAndScale(bounds_, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds_), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); client_.set_bounds(root_layer_->bounds()); @@ -2933,8 +2844,6 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_layer_; @@ -3039,8 +2948,6 @@ class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; @@ -3056,7 +2963,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest { LayerTreeHostTestCommit() = default; void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->set_background_color(SK_ColorGRAY); layer_tree_host()->SetEventListenerProperties( @@ -3088,8 +2995,6 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest { EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); @@ -3104,7 +3009,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails : frame_count_with_pending_tree_(0) {} void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->set_background_color(SK_ColorGRAY); @@ -3140,8 +3045,6 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails EXPECT_GT(frame_count_with_pending_tree_, 1); } - void AfterTest() override {} - private: int frame_count_with_pending_tree_; base::TimeTicks first_frame_time_; @@ -3158,7 +3061,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(20, 20), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->set_background_color(SK_ColorGRAY); @@ -3192,8 +3095,6 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { EXPECT_EQ(0, frame_); } - void AfterTest() override {} - private: int frame_; base::TimeTicks first_frame_time_; @@ -3220,8 +3121,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { 2 * root_layer->bounds().height())); scroll_layer_->SetScrollOffset(gfx::ScrollOffset()); - CreateVirtualViewportLayers(root_layer, scroll_layer_, root_layer->bounds(), - root_layer->bounds(), layer_tree_host()); + SetupViewport(root_layer, scroll_layer_, root_layer->bounds()); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); client_.set_bounds(root_layer->bounds()); @@ -3268,8 +3168,6 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<Layer> scroll_layer_; }; @@ -3290,7 +3188,6 @@ class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); pinch->SetScrollable(gfx::Size(200, 200)); - pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -3372,9 +3269,10 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers root_layer_ = FakePictureLayer::Create(&client_); child_layer_ = FakePictureLayer::Create(&client_); - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(60, 60), 1.5f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(60, 60), 1.5f, viz::LocalSurfaceIdAllocation()); - EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); + EXPECT_EQ(gfx::Size(60, 60), + layer_tree_host()->device_viewport_rect().size()); root_layer_->AddChild(child_layer_); @@ -3449,8 +3347,6 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_layer_; @@ -3465,7 +3361,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { : num_commit_complete_(0), num_draw_layers_(0) {} void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); @@ -3582,30 +3478,20 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferMainFrameUpdate); class LayerTreeHostInvalidLocalSurfaceIdDefersCommit : public LayerTreeHostTestDeferMainFrameUpdate { public: - LayerTreeHostInvalidLocalSurfaceIdDefersCommit() = default; - void InitializeSettings(LayerTreeSettings* settings) override { - // With surface synchronization turned on, commits are deferred until a - // LocalSurfaceId has been assigned. The set up code sets the size of the - // LayerTreeHost (using SetViewportSizeAndScale()), without providing a - // LocalSurfaceId. So, commits should be deferred until we set an id later - // during the test (in AllowCommits() override below). - settings->enable_surface_synchronization = true; + LayerTreeHostInvalidLocalSurfaceIdDefersCommit() { + SkipAllocateInitialLocalSurfaceId(); } - void BeginTest() override { PostSetNeedsCommitToMainThread(); } void AllowCommits() override { - allocator_.GenerateId(); + GenerateNewLocalSurfaceId(); PostSetLocalSurfaceIdAllocationToMainThread( - allocator_.GetCurrentLocalSurfaceIdAllocation()); + GetCurrentLocalSurfaceIdAllocation()); } bool IsCommitAllowed() const override { - return allocator_.GetCurrentLocalSurfaceIdAllocation().IsValid(); + return GetCurrentLocalSurfaceIdAllocation().IsValid(); } - - private: - viz::ParentLocalSurfaceIdAllocator allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostInvalidLocalSurfaceIdDefersCommit); @@ -3613,9 +3499,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostInvalidLocalSurfaceIdDefersCommit); // 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. -// TODO(schenney): This should be renamed back to -// LayerTreeHostTestDeferCommitInsideBeginMainFrame when we re-create -// the concept of defer commit when not defering main frame updates. class LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame : public LayerTreeHostTest { public: @@ -3656,10 +3539,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F( // This verifies that we can abort a commit inside the main frame, and // we will finish the commit once it is allowed. -// TODO(schenney): This should be renamed back to -// LayerTreeHostTestDeferCommitInsideBeginMainFrameWithCommitAfter when -// we re-create the concept of defer commit when not defering main frame -// updates. class LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter : public LayerTreeHostTest { public: @@ -4017,8 +3896,6 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest { } } - void AfterTest() override {} - private: FakeContentLayerClient client_; int num_tiles_rastered_; @@ -4042,8 +3919,6 @@ class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled FROM_HERE, base::BindOnce(&LayerTreeHostTest::EndTest, base::Unretained(this))); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F( @@ -4192,8 +4067,6 @@ class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; }; @@ -4218,7 +4091,7 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { // Round 2 done. EXPECT_EQ(1, frame_); layer_tree_host()->SetNeedsRedrawRect( - gfx::Rect(layer_tree_host()->device_viewport_size())); + layer_tree_host()->device_viewport_rect()); break; } } @@ -4240,8 +4113,6 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { } } - void AfterTest() override {} - protected: int frame_; }; @@ -4320,8 +4191,6 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { } } - void AfterTest() override {} - private: // Must clear all resources before exiting. void ClearResources() { @@ -4478,8 +4347,9 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { ++expected_push_properties_grandchild_; break; case 10: - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(20, 20), 1.f, viz::LocalSurfaceIdAllocation()); + GenerateNewLocalSurfaceId(); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(20, 20), 1.f, GetCurrentLocalSurfaceIdAllocation()); // No layers need commit. break; case 11: @@ -4526,8 +4396,6 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { ++expected_push_properties_leaf_layer_; } - void AfterTest() override {} - int num_commits_; FakeContentLayerClient client_; scoped_refptr<PushPropertiesCountingLayer> root_; @@ -4792,8 +4660,6 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed } } - void AfterTest() override {} - scoped_refptr<Layer> root_; scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; }; @@ -4851,8 +4717,6 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { } } - void AfterTest() override {} - scoped_refptr<PushPropertiesCountingLayer> root_; scoped_refptr<PushPropertiesCountingLayer> child_; }; @@ -4888,8 +4752,6 @@ class LayerTreeHostTestCasePushPropertiesThreeGrandChildren client_.set_bounds(root_->bounds()); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<PushPropertiesCountingLayer> root_; scoped_refptr<PushPropertiesCountingLayer> child_; @@ -5477,8 +5339,6 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { } } - void AfterTest() override {} - scoped_refptr<Layer> root_layer_; scoped_refptr<SolidColorLayer> parent_layer_; scoped_refptr<SolidColorLayer> child_layer_; @@ -5500,7 +5360,7 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { void BeginTest() override { // The viewport is empty, but we still need to update layers on the main // thread. - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(0, 0), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(0, 0), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); } @@ -5512,8 +5372,6 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_layer_; }; @@ -5542,7 +5400,6 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); inner_viewport_scroll_layer->SetScrollable( inner_viewport_container_layer->bounds()); - inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); root_layer_->AddChild(inner_viewport_container_layer); inner_viewport_container_layer->AddChild(overscroll_elasticity_layer); @@ -5609,8 +5466,6 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; @@ -5838,7 +5693,7 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest { layer_->SetBounds(gfx::Size(10, 10)); layer_tree_host()->SetRootLayer(layer_); gfx::Size bounds(100, 100); - layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); } @@ -5911,8 +5766,6 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest { } } - void AfterTest() override {} - private: int num_swaps_ = 0; scoped_refptr<Layer> layer_; @@ -5935,7 +5788,7 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest { layer_->SetBounds(gfx::Size(10, 10)); layer_tree_host()->SetRootLayer(layer_); gfx::Size bounds(100, 100); - layer_tree_host()->SetViewportSizeAndScale(bounds, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); } @@ -6093,8 +5946,6 @@ class LayerTreeHostTestDeferSwapPromiseForVisibility EndTest(); } - void AfterTest() override {} - TestSwapPromiseResult swap_promise_result_; bool sent_queue_request_ = false; }; @@ -6179,8 +6030,6 @@ class LayerTreeHostTestSwapPromiseDuringCommit : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - TestSwapPromiseResult swap_promise_result_[2]; }; @@ -6235,8 +6084,6 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); @@ -6279,8 +6126,6 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources EndTest(); } - void AfterTest() override {} - std::unique_ptr<FakeScopedUIResource> ui_resource_; }; @@ -6335,8 +6180,6 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - FakeContentLayerClient layer_client_; FakePictureLayer* layer_; FakeRecordingSource* recording_source_; @@ -6386,8 +6229,6 @@ class LayerTreeHostTestEmptyLayerGpuRasterization : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - FakeContentLayerClient layer_client_; FakePictureLayer* layer_; FakeRecordingSource* recording_source_; @@ -6477,8 +6318,6 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(host_impl->use_gpu_rasterization()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); @@ -6537,8 +6376,6 @@ class LayerTreeHostTestGpuRasterizationReenabled EndTest(); } - void AfterTest() override {} - int num_commits_ = 0; bool expected_use_msaa_ = true; }; @@ -6592,8 +6429,6 @@ class LayerTreeHostTestGpuRasterizationNonAASticky EndTest(); } - void AfterTest() override {} - int num_commits_ = 0; bool expected_use_msaa_ = true; }; @@ -6660,8 +6495,6 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - FakeContentLayerClient layer_client_; FakePictureLayer* layer_; FakeRecordingSource* recording_source_; @@ -6895,18 +6728,17 @@ class LayerTreeHostTestRenderSurfaceEffectTreeIndex : public LayerTreeHostTest { case 2: // Setting an empty viewport causes draws to get skipped, so the active // tree won't update draw properties. - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(), 1.f, GetCurrentLocalSurfaceIdAllocation()); child_->SetForceRenderSurfaceForTesting(false); break; case 3: - layer_tree_host()->SetViewportSizeAndScale( - root_->bounds(), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(root_->bounds()), 1.f, + GetCurrentLocalSurfaceIdAllocation()); } } - void AfterTest() override {} - private: scoped_refptr<Layer> root_; scoped_refptr<Layer> child_; @@ -7073,7 +6905,6 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); pinch->SetScrollable(gfx::Size(500, 500)); - pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -7238,8 +7069,6 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { EXPECT_NE(4, frame_) << tile->contents_scale_key(); } - void AfterTest() override {} - FakeContentLayerClient client_; int frame_; bool posted_; @@ -7311,7 +7140,6 @@ class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { EndTest(); return draw_result; } - void AfterTest() override {} FakeContentLayerClient client_; }; @@ -7339,7 +7167,7 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { layer_tree_host()->SetRootLayer(root); LayerTreeHostTest::SetupTree(); - layer_tree_host()->SetViewportSizeAndScale(viewport_size_, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport_size_), 1.f, viz::LocalSurfaceIdAllocation()); client_.set_bounds(root->bounds()); } @@ -7354,8 +7182,6 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { return draw_result; } - void AfterTest() override {} - private: FakeContentLayerClient client_; gfx::Size viewport_size_; @@ -7383,7 +7209,6 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); pinch->SetScrollable(gfx::Size(500, 500)); - pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -7565,7 +7390,7 @@ class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest { } void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(16, 16), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(16, 16), 1.f, viz::LocalSurfaceIdAllocation()); PostSetNeedsCommitToMainThread(); } @@ -7640,8 +7465,6 @@ class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { ++scheduled_prepare_tiles_count_; } - void AfterTest() override {} - protected: FakeContentLayerClient client_; int scheduled_prepare_tiles_count_; @@ -7733,8 +7556,6 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { } } - void AfterTest() override {} - private: scoped_refptr<Layer> root; scoped_refptr<Layer> child; @@ -7765,7 +7586,6 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { page_scale->AddChild(inner_viewport_scroll); inner_viewport_scroll->AddChild(page_scale_grandchild); - inner_viewport_scroll->SetIsContainerForFixedPositionLayers(true); layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); @@ -7800,8 +7620,6 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { EndTest(); } - void AfterTest() override {} - std::vector<int> affected_by_page_scale_; std::vector<int> not_affected_by_page_scale_; }; @@ -7818,8 +7636,6 @@ class LayerTreeHostTestDestroyWhileInitializingOutputSurface // the correct thread. EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostTestDestroyWhileInitializingOutputSurface); @@ -7857,8 +7673,6 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest { EXPECT_EQ(2.0f, frame.metadata.device_scale_factor); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor); @@ -7892,39 +7706,24 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTime); // Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink. class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->enable_surface_synchronization = true; - } - - void BeginTest() override { - allocator_.GenerateId(); - expected_local_surface_id_allocation_ = - allocator_.GetCurrentLocalSurfaceIdAllocation(); - PostSetLocalSurfaceIdAllocationToMainThread( - expected_local_surface_id_allocation_); - } + void BeginTest() override {} 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_allocation_, + GetCurrentLocalSurfaceIdAllocation(), host_impl->active_tree()->local_surface_id_allocation_from_parent()); return draw_result; } void DisplayReceivedLocalSurfaceIdOnThread( const viz::LocalSurfaceId& local_surface_id) override { - EXPECT_EQ(expected_local_surface_id_allocation_.local_surface_id(), + EXPECT_EQ(GetCurrentLocalSurfaceIdAllocation().local_surface_id(), local_surface_id); EndTest(); } - - void AfterTest() override {} - - viz::LocalSurfaceIdAllocation expected_local_surface_id_allocation_; - viz::ParentLocalSurfaceIdAllocator allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId); @@ -7932,18 +7731,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId); // viz::LocalSurfaceIds that only involve the child sequence number. class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->enable_surface_synchronization = true; - } - void BeginTest() override { - allocator_.GenerateId(); - expected_local_surface_id_allocation_ = - allocator_.GetCurrentLocalSurfaceIdAllocation(); EXPECT_TRUE(child_allocator_.UpdateFromParent( - allocator_.GetCurrentLocalSurfaceIdAllocation())); - PostSetLocalSurfaceIdAllocationToMainThread( - expected_local_surface_id_allocation_); + GetCurrentLocalSurfaceIdAllocation())); } DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, @@ -7952,7 +7742,7 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest { EXPECT_EQ(DRAW_SUCCESS, draw_result); // We should not be picking up the newer |child_local_surface_id_|. EXPECT_EQ( - expected_local_surface_id_allocation_, + GetCurrentLocalSurfaceIdAllocation(), host_impl->active_tree()->local_surface_id_allocation_from_parent()); // This initial test setup triggers a commit and subsequent draw. Upon the @@ -7968,7 +7758,7 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest { child_allocator_.GenerateId(); child_local_surface_id_allocation_ = child_allocator_.GetCurrentLocalSurfaceIdAllocation(); - EXPECT_NE(expected_local_surface_id_allocation_, + EXPECT_NE(GetCurrentLocalSurfaceIdAllocation(), child_local_surface_id_allocation_); PostSetLocalSurfaceIdAllocationToMainThread( child_local_surface_id_allocation_); @@ -7979,16 +7769,12 @@ class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest { void DisplayReceivedLocalSurfaceIdOnThread( const viz::LocalSurfaceId& local_surface_id) override { - EXPECT_EQ(expected_local_surface_id_allocation_.local_surface_id(), + EXPECT_EQ(GetCurrentLocalSurfaceIdAllocation().local_surface_id(), local_surface_id); EndTest(); } - void AfterTest() override {} - - viz::LocalSurfaceIdAllocation expected_local_surface_id_allocation_; viz::LocalSurfaceIdAllocation child_local_surface_id_allocation_; - viz::ParentLocalSurfaceIdAllocator allocator_; viz::ChildLocalSurfaceIdAllocator child_allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceIdSkipChildNum); @@ -7997,16 +7783,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceIdSkipChildNum); // to LayerTreeFrameSink. class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - settings->enable_surface_synchronization = true; - } - void BeginTest() override { - allocator_.GenerateId(); - expected_parent_local_surface_id_allocation_ = - allocator_.GetCurrentLocalSurfaceIdAllocation(); - PostSetLocalSurfaceIdAllocationToMainThread( - expected_parent_local_surface_id_allocation_); PostRequestNewLocalSurfaceIdToMainThread(); } @@ -8015,7 +7792,7 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest { DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); EXPECT_EQ( - expected_parent_local_surface_id_allocation_, + GetCurrentLocalSurfaceIdAllocation(), host_impl->active_tree()->local_surface_id_allocation_from_parent()); return draw_result; } @@ -8023,7 +7800,7 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest { void DisplayReceivedLocalSurfaceIdOnThread( const viz::LocalSurfaceId& local_surface_id) override { const viz::LocalSurfaceId& expected_parent_local_surface_id = - expected_parent_local_surface_id_allocation_.local_surface_id(); + GetCurrentLocalSurfaceIdAllocation().local_surface_id(); viz::LocalSurfaceId child_local_surface_id( expected_parent_local_surface_id.parent_sequence_number(), expected_parent_local_surface_id.child_sequence_number() + 1, @@ -8039,11 +7816,6 @@ class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest { host_impl->active_tree()->new_local_surface_id_request_for_testing()); EndTest(); } - - void AfterTest() override {} - - viz::LocalSurfaceIdAllocation expected_parent_local_surface_id_allocation_; - viz::ParentLocalSurfaceIdAllocator allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestNewLocalSurfaceId); @@ -8087,7 +7859,7 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest { layer_tree_host()->SetRootLayer(root); LayerTreeHostTest::SetupTree(); - layer_tree_host()->SetViewportSizeAndScale(viewport_size_, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport_size_), 1.f, viz::LocalSurfaceIdAllocation()); client_.set_bounds(root->bounds()); } @@ -8113,8 +7885,6 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest { void DidCommit() override { EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient client_; const gfx::Size viewport_size_; @@ -8145,19 +7915,12 @@ class LayerTreeHostTestSubmitFrameMetadata : public LayerTreeHostTest { EXPECT_EQ(drawn_viewport_, frame.render_pass_list.back()->output_rect); EXPECT_EQ(0.5f, frame.metadata.min_page_scale_factor); - -#if defined(OS_ANDROID) - EXPECT_EQ(4.f, frame.metadata.max_page_scale_factor); -#endif - EXPECT_EQ(0u, frame.resource_list.size()); EXPECT_EQ(1u, frame.render_pass_list.size()); EndTest(); } - void AfterTest() override {} - int num_swaps_ = 0; gfx::Rect drawn_viewport_; }; @@ -8228,8 +7991,6 @@ class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - std::vector<viz::ResourceId> resources_; }; @@ -8334,8 +8095,6 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - private: bool first_ = true; bool one_commit_done_ = false; @@ -8371,8 +8130,6 @@ class LayerTreeHostTestQueueImageDecodeNonLazy : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - private: bool first_ = true; SkBitmap bitmap_; @@ -8382,26 +8139,18 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecodeNonLazy); class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest { public: + LayerTreeHostTestHudLayerWithLayerLists() { SetUseLayerLists(); } + 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. - // TODO(pdr): Do not use the property tree builder for testing in layer list - // mode. This will require rewriting this test to manually build property - // trees. - layer_tree_host()->BuildPropertyTreesForTesting(); - - // The HUD layer should not have been setup by the property tree building. + void BeginTest() override { + // The HUD layer should not have been setup. DCHECK_EQ(layer_tree_host()->hud_layer(), nullptr); + PostSetNeedsCommitToMainThread(); } - void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); } void DidCommit() override { @@ -8413,8 +8162,6 @@ class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest { 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); @@ -8492,8 +8239,6 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { received_ack_ = false; } - void AfterTest() override {} - private: bool received_ack_ = false; }; @@ -8709,8 +8454,6 @@ class LayerTreeHostTestImageDecodingHints : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient content_layer_client_; }; @@ -8775,8 +8518,6 @@ class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest { EndTest(); } - void AfterTest() override {} - private: const GURL url_; const ukm::SourceId ukm_source_id_; @@ -8812,7 +8553,7 @@ class DontUpdateLayersWithEmptyBounds : public LayerTreeTest { mask_client_.set_bounds(gfx::Size(9, 9)); mask_->SetBounds(gfx::Size(9, 9)); - child_->SetMaskLayer(mask_.get()); + child_->SetMaskLayer(mask_); root->AddChild(child_); layer_tree_host()->SetRootLayer(std::move(root)); LayerTreeTest::SetupTree(); @@ -8852,8 +8593,6 @@ class DontUpdateLayersWithEmptyBounds : public LayerTreeTest { } } - void AfterTest() override {} - scoped_refptr<FakePictureLayer> child_; scoped_refptr<FakePictureLayer> mask_; FakeContentLayerClient root_client_; @@ -8869,28 +8608,18 @@ class LayerTreeHostTestNewLocalSurfaceIdForcesDraw : public LayerTreeHostTest { public: LayerTreeHostTestNewLocalSurfaceIdForcesDraw() {} - void InitializeSettings(LayerTreeSettings* settings) override { - settings->enable_surface_synchronization = true; - } - void BeginTest() override { - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); - allocator_.GenerateId(); - local_surface_id_allocation_ = - allocator_.GetCurrentLocalSurfaceIdAllocation(); - PostSetLocalSurfaceIdAllocationToMainThread(local_surface_id_allocation_); } void DidReceiveCompositorFrameAck() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - allocator_.GenerateId(); - local_surface_id_allocation_ = - allocator_.GetCurrentLocalSurfaceIdAllocation(); + GenerateNewLocalSurfaceId(); PostSetLocalSurfaceIdAllocationToMainThread( - local_surface_id_allocation_); + GetCurrentLocalSurfaceIdAllocation()); break; case 2: EndTest(); @@ -8899,10 +8628,6 @@ class LayerTreeHostTestNewLocalSurfaceIdForcesDraw : public LayerTreeHostTest { NOTREACHED(); } } - - void AfterTest() override {} - viz::LocalSurfaceIdAllocation local_surface_id_allocation_; - viz::ParentLocalSurfaceIdAllocator allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNewLocalSurfaceIdForcesDraw); @@ -8933,8 +8658,6 @@ class DidReceiveCompositorFrameAckNotSentWhenNotNeeded } } - void AfterTest() override {} - private: bool received_first_frame_ = false; }; @@ -8978,7 +8701,7 @@ class LayerTreeHostTestRequestForceSendMetadata // Just set up a basic frame which can be repeatedly re-drawn. layer_tree_host()->SetRenderFrameObserver( std::make_unique<ForwardingRenderFrameMetadataObserver>(this)); - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(10, 10), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f, viz::LocalSurfaceIdAllocation()); layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); @@ -9035,7 +8758,6 @@ class LayerTreeHostTestPartialTileDamage : public LayerTreeHostTest { : partial_damage_(20, 20, 45, 60), layer_size_(512, 512) {} void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} void InitializeSettings(LayerTreeSettings* settings) override { settings->default_tile_size = gfx::Size(256, 256); @@ -9089,5 +8811,52 @@ class LayerTreeHostTestPartialTileDamage : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestPartialTileDamage); +// Make sure that a change in top controls shown ratio causes an update to the +// pending tree's viewports. +class LayerTreeHostTopControlsDeltaTriggersViewportUpdate + : public LayerTreeHostTest { + public: + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void SetupTree() override { + LayerTreeHostTest::SetupTree(); + Layer* root_layer = layer_tree_host()->root_layer(); + // Set up scrollable root. + root_layer->SetBounds(gfx::Size(100, 100)); + SetupViewport(root_layer, gfx::Size(50, 50), root_layer->bounds()); + // Set browser controls to be partially shown. + layer_tree_host()->SetBrowserControlsHeight(kTopControlsHeight, 0.0f, + true /* shrink */); + layer_tree_host()->SetBrowserControlsShownRatio(kTopControlsShownRatio); + } + + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { + // Before commit the inner_viewport_container_bounds_delta() value should + // not reflect the partially shown top controls. + float bounds_delta = impl->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y(); + EXPECT_EQ(bounds_delta, 0.0f); + } + + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + // After commit the inner_viewport_container_bounds_delta() value should + // reflect the partially shown top controls. + float bounds_delta = impl->pending_tree() + ->property_trees() + ->inner_viewport_container_bounds_delta() + .y(); + EXPECT_EQ(bounds_delta, + kTopControlsHeight - kTopControlsHeight * kTopControlsShownRatio); + EndTest(); + } + + static constexpr float kTopControlsHeight = 10.0f; + static constexpr float kTopControlsShownRatio = 0.3f; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTopControlsDeltaTriggersViewportUpdate); + } // 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 d5a0aa983c0..56bd3ff896d 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -124,8 +124,6 @@ class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested num_commits_++; } - void AfterTest() override {} - private: int num_commits_; }; @@ -155,8 +153,6 @@ class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback EndTest(); } - void AfterTest() override {} - private: int num_begin_frames_; }; @@ -245,8 +241,6 @@ class LayerTreeHostAnimationTestNoDamageAnimation finished_animating_ = true; } - void AfterTest() override {} - private: bool started_animating_; bool finished_animating_; @@ -287,8 +281,6 @@ class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; } - void AfterTest() override {} - private: bool started_animating_; }; @@ -331,8 +323,6 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted layer_tree_host()->SetNeedsCommit(); } - void AfterTest() override {} - private: bool started_animating_; }; @@ -402,8 +392,6 @@ class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> picture_; bool first_animation_frame_ = true; @@ -494,8 +482,6 @@ class LayerTreeHostAnimationTestAnimationFinishedEvents animation_->RemoveKeyframeModel(keyframe_model->id()); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -585,8 +571,6 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation base::TimeTicks monotonic_time) override { EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -832,8 +816,6 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> scroll_layer_; @@ -893,8 +875,6 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> scroll_layer_; @@ -1001,8 +981,6 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted } } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> scroll_layer_; @@ -1323,6 +1301,14 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers() : frame_count_with_pending_tree_(0) {} + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + layer_ = Layer::Create(); + layer_->SetBounds(gfx::Size(4, 4)); + layer_tree_host()->root_layer()->AddChild(layer_); + layer_tree_host()->SetElementIdsForTesting(); + } + void BeginTest() override { AttachAnimationsToTimeline(); PostSetNeedsCommitToMainThread(); @@ -1330,18 +1316,18 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers void DidCommit() override { if (layer_tree_host()->SourceFrameNumber() == 1) { - animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); + animation_->AttachElement(layer_->element_id()); AddAnimatedTransformToAnimation(animation_.get(), 4, 1, 1); } else if (layer_tree_host()->SourceFrameNumber() == 2) { AddOpacityTransitionToAnimation(animation_.get(), 1, 0.f, 0.5f, true); - scoped_refptr<Layer> layer = Layer::Create(); - layer_tree_host()->root_layer()->AddChild(layer); + scoped_refptr<Layer> child_layer = Layer::Create(); + layer_->AddChild(child_layer); layer_tree_host()->SetElementIdsForTesting(); - layer->SetBounds(gfx::Size(4, 4)); + child_layer->SetBounds(gfx::Size(4, 4)); - animation_child_->AttachElement(layer->element_id()); + animation_child_->AttachElement(child_layer->element_id()); animation_child_->set_animation_delegate(this); AddOpacityTransitionToAnimation(animation_child_.get(), 1, 0.f, 0.5f, true); @@ -1409,9 +1395,8 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers EndTest(); } - void AfterTest() override {} - private: + scoped_refptr<Layer> layer_; int frame_count_with_pending_tree_; }; @@ -1488,8 +1473,6 @@ class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<Layer> layer_; }; @@ -1589,8 +1572,6 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded } } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; }; @@ -1606,11 +1587,14 @@ class LayerTreeHostAnimationTestAddKeyframeModelAfterAnimating layer_ = Layer::Create(); layer_->SetBounds(gfx::Size(4, 4)); layer_tree_host()->root_layer()->AddChild(layer_); + child_layer_ = Layer::Create(); + child_layer_->SetBounds(gfx::Size(4, 4)); + layer_->AddChild(child_layer_); AttachAnimationsToTimeline(); - animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); - animation_child_->AttachElement(layer_->element_id()); + animation_->AttachElement(layer_->element_id()); + animation_child_->AttachElement(child_layer_->element_id()); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -1665,10 +1649,9 @@ class LayerTreeHostAnimationTestAddKeyframeModelAfterAnimating EndTest(); } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; + scoped_refptr<Layer> child_layer_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -1770,8 +1753,6 @@ class LayerTreeHostAnimationTestRemoveKeyframeModel } } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; @@ -1883,8 +1864,6 @@ class LayerTreeHostAnimationTestIsAnimating } } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; @@ -1955,8 +1934,6 @@ class LayerTreeHostAnimationTestAnimationFinishesDuringCommit } } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; @@ -2035,8 +2012,6 @@ class LayerTreeHostAnimationTestImplSideInvalidation } } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; @@ -2071,8 +2046,6 @@ class LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit } } - void AfterTest() override {} - protected: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; @@ -2295,9 +2268,14 @@ class LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation public: void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); + layer_ = Layer::Create(); + layer_->SetBounds(gfx::Size(4, 4)); + layer_tree_host()->root_layer()->AddChild(layer_); + AttachAnimationsToTimeline(); + timeline_->DetachAnimation(animation_child_.get()); - animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); + animation_->AttachElement(layer_->element_id()); TransformOperations start; start.AppendTranslate(5.f, 5.f, 0.f); @@ -2312,7 +2290,7 @@ class LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation PropertyTrees* property_trees = host_impl->sync_tree()->property_trees(); TransformNode* node = property_trees->transform_tree.Node(host_impl->sync_tree() - ->root_layer_for_testing() + ->LayerById(layer_->id()) ->transform_tree_index()); gfx::Transform translate; translate.Translate(5, 5); @@ -2334,8 +2312,7 @@ class LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation timeline_->DetachAnimation(animation_.get()); animation_ = nullptr; timeline_->AttachAnimation(animation_child_.get()); - animation_child_->AttachElement( - layer_tree_host()->root_layer()->element_id()); + animation_child_->AttachElement(layer_->element_id()); AddAnimatedTransformToAnimation(animation_child_.get(), 1.0, 10, 10); KeyframeModel* keyframe_model = animation_child_->GetKeyframeModel(TargetProperty::TRANSFORM); @@ -2345,7 +2322,8 @@ class LayerTreeHostAnimationTestChangeSingleKeyframeEffectAnimation } } - void AfterTest() override {} + private: + scoped_refptr<Layer> layer_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -2470,8 +2448,6 @@ class LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit EndTest(); } - void AfterTest() override {} - private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc index 1b6d70d9527..7cfeddec75b 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc @@ -188,7 +188,6 @@ class LayerTreeHostCaptureContentTestTwoLayers // OnSetupSecondaryLayTransform(). void SetupTransform(const gfx::Vector2dF& translate) { TransformNode transform_node; - transform_node.source_node_id = 0; transform_node.local.Translate(translate); transform_node.id = layer_tree_host()->property_trees()->transform_tree.Insert( diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index dfdecdb3ef6..28655847535 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -27,7 +27,6 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest { layer_tree_host()->SetSourceURL(ukm_source_id_, url_); PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} void VerifyUkmAndEndTest(LayerTreeHostImpl* impl) { auto* recorder = static_cast<ukm::TestUkmRecorder*>( diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index b658d15f6fe..55bb0a7b7af 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -388,8 +388,6 @@ class LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink } void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -448,8 +446,6 @@ class LayerTreeHostClientTakeAwayLayerTreeFrameSink layer_tree_host()->SetVisible(true); } - void AfterTest() override {} - int setos_counter_; }; @@ -478,8 +474,6 @@ class MultipleCompositeDoesNotCreateLayerTreeFrameSink void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); } - void AfterTest() override {} - int request_count_; }; @@ -534,8 +528,6 @@ class FailedCreateDoesNotCreateExtraLayerTreeFrameSink has_failed_ = true; } - void AfterTest() override {} - int num_requests_; bool has_failed_; }; @@ -577,8 +569,6 @@ class LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink EndTest(); } - void AfterTest() override {} - bool creating_output_; }; @@ -610,8 +600,6 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite void ScheduleComposite() override { EXPECT_FALSE(in_composite_); } - void AfterTest() override {} - bool in_composite_; }; @@ -776,8 +764,6 @@ class LayerTreeHostContextTestLostContextAndEvictTextures void DidInitializeLayerTreeFrameSink() override {} - void AfterTest() override {} - protected: bool lose_after_evict_; FakeContentLayerClient client_; @@ -883,8 +869,6 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { } } - void AfterTest() override {} - private: int num_commits_; @@ -952,7 +936,7 @@ class LayerTreeHostContextTestDontUseLostResources PictureLayer::Create(&client_); layer_with_mask->SetBounds(gfx::Size(10, 10)); layer_with_mask->SetIsDrawable(true); - layer_with_mask->SetMaskLayer(mask.get()); + layer_with_mask->SetMaskLayer(mask); root->AddChild(layer_with_mask); scoped_refptr<VideoLayer> video_color = @@ -1099,8 +1083,6 @@ class LayerTreeHostContextTestImplSidePainting PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} - void DidInitializeLayerTreeFrameSink() override { EndTest(); } private: @@ -1123,8 +1105,6 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} - void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); @@ -1158,7 +1138,6 @@ class UIResourceLostTest : public LayerTreeHostContextTest { public: UIResourceLostTest() : time_step_(0) {} void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void AfterTest() override {} // This is called on the main thread after each commit and // DidActivateTreeOnThread, with the value of time_step_ at the time @@ -1615,8 +1594,6 @@ class UIResourceFreedIfLostWhileExported : public LayerTreeHostContextTest { EndTest(); } - void AfterTest() override {} - std::unique_ptr<FakeScopedUIResource> ui_resource_; }; @@ -1672,8 +1649,6 @@ class TileResourceFreedIfLostWhileExported : public LayerTreeHostContextTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; size_t num_textures_ = 0; }; @@ -1743,8 +1718,6 @@ class SoftwareTileResourceFreedIfLostWhileExported : public LayerTreeTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; viz::ResourceId exported_resource_id_ = 0; }; @@ -1799,8 +1772,6 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame void DidCommitAndDrawFrame() override { EndTest(); } - void AfterTest() override {} - std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_; bool deferred_ = false; bool lost_ = true; diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index 3f335e7d9d5..2545887eddb 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -253,8 +253,6 @@ class LayerTreeHostCopyRequestCompletionCausesCommit EXPECT_FALSE(result->IsEmpty()); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> layer_; @@ -322,8 +320,8 @@ class LayerTreeHostCopyRequestTestLayerDestroyed EXPECT_EQ(1, callback_count_); // Prevent drawing so we can't make a copy of the impl_destroyed layer. - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; case 2: // Flush the message loops and make sure the callbacks run. @@ -358,8 +356,6 @@ class LayerTreeHostCopyRequestTestLayerDestroyed ++callback_count_; } - void AfterTest() override {} - int callback_count_; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; @@ -466,8 +462,6 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree } } - void AfterTest() override {} - int callback_count_; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; @@ -649,8 +643,6 @@ class LayerTreeHostCopyRequestTestClippedOut EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> parent_layer_; @@ -712,8 +704,6 @@ class LayerTreeHostCopyRequestTestScaledLayer EndTest(); } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<Layer> root_; scoped_refptr<Layer> copy_layer_; @@ -761,7 +751,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw PostSetNeedsCommitToMainThread(); // Prevent drawing. - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(0, 0), 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(0, 0), 1.f, viz::LocalSurfaceIdAllocation()); AddCopyRequest(copy_layer_.get()); @@ -777,8 +767,9 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw void DidCommit() override { if (layer_tree_host()->SourceFrameNumber() == 1) { // Allow drawing. - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(root_->bounds()), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(root_->bounds()), 1.f, + GetCurrentLocalSurfaceIdAllocation()); AddCopyRequest(copy_layer_.get()); } @@ -949,8 +940,6 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage } } - void AfterTest() override {} - scoped_refptr<viz::TestContextProvider> display_context_provider_; int num_swaps_ = 0; size_t num_shared_images_without_readback_ = 0; @@ -1166,8 +1155,9 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation()); + // Stop drawing. + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; } case 2: @@ -1178,9 +1168,9 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy case 3: EXPECT_EQ(1, callback_count_); // Allow us to draw now. - layer_tree_host()->SetViewportSizeAndScale( - layer_tree_host()->root_layer()->bounds(), 1.f, - viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(layer_tree_host()->root_layer()->bounds()), 1.f, + GetCurrentLocalSurfaceIdAllocation()); break; case 4: EXPECT_EQ(1, callback_count_); @@ -1189,8 +1179,6 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy } } - void AfterTest() override {} - int callback_count_; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; @@ -1256,8 +1244,8 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; } case 2: @@ -1407,8 +1395,6 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest EndTest(); } - void AfterTest() override {} - scoped_refptr<FakePictureLayer> child_; FakeContentLayerClient client_; int num_draws_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 809985aa5f2..945d4e9c32e 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -45,7 +45,7 @@ class LayerTreeHostDamageTestSetNeedsRedraw switch (layer_tree_host()->SourceFrameNumber()) { case 1: layer_tree_host()->SetNeedsRedrawRect( - gfx::Rect(layer_tree_host()->device_viewport_size())); + layer_tree_host()->device_viewport_rect()); break; } } @@ -79,16 +79,14 @@ class LayerTreeHostDamageTestSetNeedsRedraw return draw_result; } - void AfterTest() override {} - int draw_count_; FakeContentLayerClient client_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetNeedsRedraw); -// LayerTreeHost::SetViewportSizeAndScale should damage the whole viewport. -class LayerTreeHostDamageTestSetViewportSizeAndScale +// LayerTreeHost::SetViewportRectAndScale should damage the whole viewport. +class LayerTreeHostDamageTestSetViewportRectAndScale : public LayerTreeHostDamageTest { void SetupTree() override { // Viewport is 10x10. @@ -108,8 +106,8 @@ class LayerTreeHostDamageTestSetViewportSizeAndScale void DidCommitAndDrawFrame() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(15, 15), 1.f, viz::LocalSurfaceIdAllocation()); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(15, 15), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; } } @@ -143,13 +141,11 @@ class LayerTreeHostDamageTestSetViewportSizeAndScale return draw_result; } - void AfterTest() override {} - int draw_count_; FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetViewportSizeAndScale); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetViewportRectAndScale); class LayerTreeHostDamageTestNoDamageDoesNotSwap : public LayerTreeHostDamageTest { @@ -216,7 +212,7 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap case 2: // Cause visible damage. content_->SetNeedsDisplayRect( - gfx::Rect(layer_tree_host()->device_viewport_size())); + layer_tree_host()->device_viewport_rect()); break; case 3: // Cause non-visible damage. @@ -323,8 +319,6 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; scoped_refptr<FakePictureLayer> child_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc index 3870aba8671..3a2edb4e411 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc @@ -40,7 +40,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin scoped_refptr<FakePictureLayer> mask_layer = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording_source)); - content_layer->SetMaskLayer(mask_layer.get()); + content_layer->SetMaskLayer(mask_layer); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -57,9 +57,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin 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()); + SetupViewport(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50)); layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true); outer_viewport_scroll_layer->AddChild(content_layer); @@ -96,8 +94,6 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin return draw_result; } - void AfterTest() override {} - int mask_layer_id_; FakeContentLayerClient client_; }; @@ -138,7 +134,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { scoped_refptr<FakePictureLayer> mask_layer = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording_source)); - content_layer->SetMaskLayer(mask_layer.get()); + content_layer->SetMaskLayer(mask_layer); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -202,8 +198,6 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { return draw_result; } - void AfterTest() override {} - int mask_layer_id_; FakeContentLayerClient client_; }; @@ -245,7 +239,7 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale scoped_refptr<FakePictureLayer> mask_layer = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording_source)); - content_layer->SetMaskLayer(mask_layer.get()); + content_layer->SetMaskLayer(mask_layer); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -323,8 +317,6 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale return draw_result; } - void AfterTest() override {} - int mask_layer_id_; FakeContentLayerClient client_; }; @@ -364,7 +356,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { scoped_refptr<FakePictureLayer> mask_layer = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording_source)); - content_layer->SetMaskLayer(mask_layer.get()); + content_layer->SetMaskLayer(mask_layer); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -431,14 +423,14 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: gfx::Size double_root_size(200, 200); - layer_tree_host()->SetViewportSizeAndScale( - double_root_size, 2.f, viz::LocalSurfaceIdAllocation()); + GenerateNewLocalSurfaceId(); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(double_root_size), 2.f, + GetCurrentLocalSurfaceIdAllocation()); break; } } - void AfterTest() override {} - FakeContentLayerClient client_; }; @@ -468,7 +460,7 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { scoped_refptr<FakePictureLayer> mask_layer = FakePictureLayer::CreateWithRecordingSource( &client_, std::move(recording_source)); - content_layer->SetMaskLayer(mask_layer.get()); + content_layer->SetMaskLayer(mask_layer); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -514,8 +506,6 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { return draw_result; } - void AfterTest() override {} - int mask_layer_id_; FakeContentLayerClient client_; }; diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index 41e9c4c0283..244eb6f2861 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -67,8 +67,6 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer EndTest(); } - void AfterTest() override {} - private: scoped_refptr<Layer> child_; }; @@ -122,8 +120,6 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface EndTest(); } - void AfterTest() override {} - private: scoped_refptr<Layer> child_; }; @@ -155,7 +151,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); mask->SetBounds(gfx::Size(30, 40)); mask->SetIsDrawable(true); - child_->SetMaskLayer(mask.get()); + child_->SetMaskLayer(mask); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -193,8 +189,6 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> child_; @@ -228,7 +222,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); mask->SetBounds(gfx::Size(30, 40)); mask->SetIsDrawable(true); - child_->SetMaskLayer(mask.get()); + child_->SetMaskLayer(mask); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 11)); @@ -258,8 +252,6 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient client_; scoped_refptr<Layer> child_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index 8c103dfc473..445a2630c50 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -136,8 +136,6 @@ class LayerTreeHostPictureTestTwinLayer EndTest(); } - void AfterTest() override {} - int activates_ = 0; int picture_id1_; @@ -194,16 +192,15 @@ class LayerTreeHostPictureTestResizeViewportWithGpuRaster // Change the picture layer's size along with the viewport, so it will // consider picking a new tile size. picture_->SetBounds(gfx::Size(768, 1056)); - layer_tree_host()->SetViewportSizeAndScale( - gfx::Size(768, 1056), 1.f, viz::LocalSurfaceIdAllocation()); + GenerateNewLocalSurfaceId(); + layer_tree_host()->SetViewportRectAndScale( + gfx::Rect(768, 1056), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; case 2: EndTest(); } } - void AfterTest() override {} - gfx::Size tile_size_; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> picture_; @@ -311,8 +308,6 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree EndTest(); } - void AfterTest() override {} - int frame_; bool did_post_commit_; FakeContentLayerClient client_; @@ -398,8 +393,6 @@ class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest { } } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<Layer> child_; scoped_refptr<FakePictureLayer> picture_; @@ -418,7 +411,6 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale pinch_ = Layer::Create(); pinch_->SetBounds(gfx::Size(500, 500)); pinch_->SetScrollable(root_clip->bounds()); - pinch_->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch_); root_clip->AddChild(page_scale_layer); @@ -564,8 +556,6 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale } } - void AfterTest() override {} - FakeContentLayerClient client_; scoped_refptr<Layer> pinch_; scoped_refptr<FakePictureLayer> picture_; @@ -577,7 +567,8 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale // Multi-thread only because in single thread you can't pinch zoom on the // compositor thread. -MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale); +// TODO(https://crbug.com/997866): Flaky on several platforms. +// MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale); class LayerTreeHostPictureTestForceRecalculateScales : public LayerTreeHostPictureTest { @@ -585,18 +576,21 @@ class LayerTreeHostPictureTestForceRecalculateScales gfx::Size size(100, 100); scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(size); + top_layer_ = Layer::Create(); + top_layer_->SetBounds(size); + root->AddChild(top_layer_); will_change_layer_ = FakePictureLayer::Create(&client_); will_change_layer_->SetHasWillChangeTransformHint(true); will_change_layer_->SetBounds(size); - root->AddChild(will_change_layer_); + top_layer_->AddChild(will_change_layer_); normal_layer_ = FakePictureLayer::Create(&client_); normal_layer_->SetBounds(size); - root->AddChild(normal_layer_); + top_layer_->AddChild(normal_layer_); layer_tree_host()->SetRootLayer(root); - layer_tree_host()->SetViewportSizeAndScale(size, 1.f, + layer_tree_host()->SetViewportRectAndScale(gfx::Rect(size), 1.f, viz::LocalSurfaceIdAllocation()); client_.set_fill_with_nonsolid_color(true); @@ -626,7 +620,7 @@ class LayerTreeHostPictureTestForceRecalculateScales MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( - &LayerTreeHostPictureTestForceRecalculateScales::ScaleRootUp, + &LayerTreeHostPictureTestForceRecalculateScales::ScaleUp, base::Unretained(this))); break; case 1: @@ -643,7 +637,7 @@ class LayerTreeHostPictureTestForceRecalculateScales MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&LayerTreeHostPictureTestForceRecalculateScales:: - ScaleRootUpAndRecalculateScales, + ScaleUpAndRecalculateScales, base::Unretained(this))); break; case 2: @@ -661,21 +655,20 @@ class LayerTreeHostPictureTestForceRecalculateScales } } - void ScaleRootUp() { + void ScaleUp() { gfx::Transform transform; transform.Scale(2, 2); - layer_tree_host()->root_layer()->SetTransform(transform); + top_layer_->SetTransform(transform); } - void ScaleRootUpAndRecalculateScales() { + void ScaleUpAndRecalculateScales() { gfx::Transform transform; transform.Scale(4, 4); - layer_tree_host()->root_layer()->SetTransform(transform); + top_layer_->SetTransform(transform); layer_tree_host()->SetNeedsRecalculateRasterScales(); } - void AfterTest() override {} - + scoped_refptr<Layer> top_layer_; scoped_refptr<FakePictureLayer> will_change_layer_; scoped_refptr<FakePictureLayer> normal_layer_; }; diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 399b68f06be..457b2d1e9b1 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -68,8 +68,6 @@ class LayerTreeHostProxyTestSetNeedsCommit : public LayerTreeHostProxyTest { GetProxyMain()->current_pipeline_stage()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsCommit); @@ -84,6 +82,11 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { LayerTreeHostProxyTestSetNeedsAnimate& operator=( const LayerTreeHostProxyTestSetNeedsAnimate&) = delete; + void InitializeSettings(LayerTreeSettings* settings) override { + // TODO(crbug.com/985009): Fix test with surface sync enabled. + settings->enable_surface_synchronization = false; + } + void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -105,8 +108,6 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { EXPECT_EQ(0, update_check_layer()->update_count()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsAnimate); @@ -143,8 +144,6 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayers EXPECT_EQ(1, update_check_layer()->update_count()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsUpdateLayers); @@ -161,6 +160,11 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating&) = delete; + void InitializeSettings(LayerTreeSettings* settings) override { + // TODO(crbug.com/985009): Fix test with surface sync enabled. + settings->enable_surface_synchronization = false; + } + void BeginTest() override { proxy()->SetNeedsAnimate(); } void WillBeginMainFrame() override { @@ -190,8 +194,6 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating EXPECT_EQ(1, update_check_layer()->update_count()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating); @@ -207,6 +209,11 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating LayerTreeHostProxyTestSetNeedsCommitWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsCommitWhileAnimating&) = delete; + void InitializeSettings(LayerTreeSettings* settings) override { + // TODO(crbug.com/985009): Fix test with surface sync enabled. + settings->enable_surface_synchronization = false; + } + void BeginTest() override { proxy()->SetNeedsAnimate(); } void WillBeginMainFrame() override { @@ -236,8 +243,6 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating EXPECT_EQ(1, update_check_layer()->update_count()); EndTest(); } - - void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsCommitWhileAnimating); @@ -322,8 +327,6 @@ class LayerTreeHostProxyTestCommitWaitsForActivation impl->BlockNotifyReadyToActivateForTesting(false); } - void AfterTest() override {} - private: base::Lock activate_blocked_lock_; bool activate_blocked_ = false; @@ -430,8 +433,6 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA impl->BlockNotifyReadyToActivateForTesting(false); } - void AfterTest() override {} - private: base::Lock activate_blocked_lock_; bool activate_blocked_ = false; @@ -469,8 +470,6 @@ class LayerTreeHostProxyTestImplFrameCausesAnimatePending default: { NOTREACHED(); } } } - - void AfterTest() override {} }; SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestImplFrameCausesAnimatePending); @@ -517,8 +516,6 @@ class LayerTreeHostProxyTestNeedsCommitFromImpl EXPECT_FALSE(proxy()->CommitRequested()); EndTest(); } - - void AfterTest() override {} }; SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestNeedsCommitFromImpl); @@ -554,8 +551,6 @@ class LayerTreeHostProxyTestDelayedCommitDueToVisibility void DidCommit() override { EndTest(); } - void AfterTest() override {} - private: bool set_invisible_once_ = false; }; diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index 8ebf210f056..451a33763d6 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -83,9 +83,7 @@ class LayerTreeHostScrollTest : public LayerTreeTest { gfx::Size scroll_layer_bounds(root_layer->bounds().width() + 100, root_layer->bounds().height() + 100); - CreateVirtualViewportLayers(root_layer, root_layer->bounds(), - root_layer->bounds(), scroll_layer_bounds, - layer_tree_host()); + SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds); } }; @@ -494,8 +492,6 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { scroll_layer->ScrollBy(scroll_amount_); } - void AfterTest() override {} - private: gfx::Vector2dF scroll_amount_; }; @@ -548,8 +544,6 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { scroll_layer->ScrollBy(scroll_amount_); } - void AfterTest() override {} - private: gfx::Vector2dF scroll_amount_; }; @@ -566,9 +560,9 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { void SetupTree() override { SetInitialDeviceScaleFactor(device_scale_factor_); - - scoped_refptr<Layer> root_layer = Layer::Create(); - root_layer->SetBounds(gfx::Size(10, 10)); + SetInitialRootBounds(gfx::Size(10, 10)); + LayerTreeHostScrollTest::SetupTree(); + Layer* root_layer = layer_tree_host()->root_layer(); root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); root_scroll_layer_->SetElementId( @@ -577,9 +571,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { root_scroll_layer_->SetPosition(gfx::PointF()); root_scroll_layer_->SetIsDrawable(true); - CreateVirtualViewportLayers(root_layer.get(), root_scroll_layer_, - root_layer->bounds(), root_layer->bounds(), - layer_tree_host()); + SetupViewport(root_layer, root_scroll_layer_, root_layer->bounds()); child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); child_layer_->set_did_scroll_callback( @@ -616,9 +608,6 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } expected_scroll_layer_->SetScrollOffset(initial_offset_); - - layer_tree_host()->SetRootLayer(root_layer); - LayerTreeTest::SetupTree(); fake_content_layer_client_.set_bounds(root_layer->bounds()); layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( @@ -1105,8 +1094,6 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { } } - void AfterTest() override {} - private: gfx::ScrollOffset initial_scroll_; gfx::Vector2dF impl_thread_scroll_; @@ -1121,69 +1108,86 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset public: LayerTreeHostScrollTestScrollZeroMaxScrollOffset() = default; + void InitializeSettings(LayerTreeSettings* settings) override { + settings->use_layer_lists = true; + } + + void SetupTree() override { + LayerTreeHostScrollTest::SetupTree(); + + // Add a sub-scroller to test TryScroll against. The outer viewport scroll + // will be latched to for scrolling even if it doesn't have any scroll + // extent in the given direction to support overscroll actions. + scroller_ = Layer::Create(); + scroller_->SetIsDrawable(true); + scroller_->SetHitTestable(true); + scroller_->SetScrollable(layer_tree_host()->root_layer()->bounds()); + scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id())); + CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(), + scroller_.get()); + CreateTransformNode(scroller_.get()); + CreateScrollNode(scroller_.get()); + layer_tree_host()->outer_viewport_scroll_layer()->AddChild(scroller_.get()); + } + void BeginTest() override { - outer_viewport_container_layer_id_ = - layer_tree_host()->outer_viewport_container_layer()->id(); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* root = layer_tree_host()->root_layer(); - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + ScrollTree& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; + ScrollNode* scroll_node = scroll_tree.Node(scroller_->scroll_tree_index()); switch (layer_tree_host()->SourceFrameNumber()) { case 0: - scroll_layer->SetScrollable(root->bounds()); - scroll_layer->SetHitTestable(true); // Set max_scroll_offset = (100, 100). - scroll_layer->SetBounds(gfx::Size(root->bounds().width() + 100, - root->bounds().height() + 100)); + scroll_node->bounds = scroll_node->container_bounds; + scroll_node->bounds.Enlarge(100, 100); break; case 1: // Set max_scroll_offset = (0, 0). - scroll_layer->SetBounds(root->bounds()); + scroll_node->bounds = scroll_node->container_bounds; break; case 2: - // Set max_scroll_offset = (-100, -100). - scroll_layer->SetBounds(gfx::Size()); + // Set max_scroll_offset = (-1, -1). + scroll_node->bounds = gfx::Size(); break; } } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); - ScrollTree& scroll_tree = impl->active_tree()->property_trees()->scroll_tree; - ScrollNode* scroll_node = - scroll_tree.Node(scroll_layer->scroll_tree_index()); + ScrollNode* scroll_node = scroll_tree.Node(scroller_->scroll_tree_index()); InputHandler::ScrollStatus status = impl->TryScroll(gfx::PointF(0.0f, 1.0f), scroll_tree, scroll_node); switch (impl->active_tree()->source_frame_number()) { case 0: - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread) + << "In Frame 0"; EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, - status.main_thread_scrolling_reasons); + status.main_thread_scrolling_reasons) + << "In Frame 0"; PostSetNeedsCommitToMainThread(); break; case 1: - EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread) << "In Frame 1"; EXPECT_EQ(MainThreadScrollingReason::kNotScrollable, - status.main_thread_scrolling_reasons); + status.main_thread_scrolling_reasons) + << "In Frame 1"; PostSetNeedsCommitToMainThread(); break; case 2: - EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread); + EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread) << "In Frame 2"; EXPECT_EQ(MainThreadScrollingReason::kNotScrollable, - status.main_thread_scrolling_reasons); + status.main_thread_scrolling_reasons) + << "In Frame 2"; EndTest(); break; } } - void AfterTest() override {} - private: - int outer_viewport_container_layer_id_; + scoped_refptr<Layer> scroller_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -1224,8 +1228,6 @@ class LayerTreeHostScrollTestScrollNonDrawnLayer EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollNonDrawnLayer); @@ -1269,8 +1271,6 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent status.main_thread_scrolling_reasons); EndTest(); } - - void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -1340,9 +1340,7 @@ class LayerTreeHostScrollTestLayerStructureChange Layer* root_layer = layer_tree_host()->root_layer(); root_layer->SetBounds(gfx::Size(10, 10)); - CreateVirtualViewportLayers(root_layer, root_layer->bounds(), - root_layer->bounds(), root_layer->bounds(), - layer_tree_host()); + SetupViewport(root_layer, root_layer->bounds(), root_layer->bounds()); Layer* outer_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); @@ -1381,8 +1379,6 @@ class LayerTreeHostScrollTestLayerStructureChange } } - void AfterTest() override {} - virtual void DidScroll(Layer* layer) { if (scroll_destroy_whole_tree_) { layer_tree_host()->RegisterViewportLayers(ViewportLayers()); @@ -2040,8 +2036,6 @@ class LayerTreeHostScrollTestPropertyTreeUpdate } } - void AfterTest() override {} - private: gfx::ScrollOffset initial_scroll_; gfx::ScrollOffset second_scroll_; @@ -2231,145 +2225,48 @@ class LayerTreeHostScrollTestImplSideInvalidation MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplSideInvalidation); -// Version of LayerTreeHostScrollTest that uses layer lists which means the -// property trees and layer list are explicitly specified instead of running -// the cc property tree builder. -class LayerListLayerTreeHostScrollTest : public LayerTreeHostScrollTest { +class NonScrollingNonFastScrollableRegion : public LayerTreeHostScrollTest { public: - // The id of the root property tree nodes. - static constexpr int kRootNodeId = 1; - - LayerListLayerTreeHostScrollTest() { SetUseLayerList(); } - - void SetupTree() override { - // Setup the root transform, effect, clip, and scroll property tree nodes. - auto& transform_tree = layer_tree_host()->property_trees()->transform_tree; - auto& root_transform_node = *transform_tree.Node( - transform_tree.Insert(TransformNode(), kRealRootNodeId)); - DCHECK_EQ(root_transform_node.id, kRootNodeId); - root_transform_node.source_node_id = root_transform_node.parent_id; - transform_tree.set_needs_update(true); - - auto& effect_tree = layer_tree_host()->property_trees()->effect_tree; - auto& root_effect_node = - *effect_tree.Node(effect_tree.Insert(EffectNode(), kRealRootNodeId)); - DCHECK_EQ(root_effect_node.id, kRootNodeId); - root_effect_node.stable_id = 1; - root_effect_node.transform_id = kRealRootNodeId; - root_effect_node.clip_id = kRealRootNodeId; - root_effect_node.render_surface_reason = RenderSurfaceReason::kRoot; - effect_tree.set_needs_update(true); - - auto& clip_tree = layer_tree_host()->property_trees()->clip_tree; - auto& root_clip_node = - *clip_tree.Node(clip_tree.Insert(ClipNode(), kRealRootNodeId)); - DCHECK_EQ(root_clip_node.id, kRootNodeId); - root_clip_node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; - root_clip_node.clip = gfx::RectF(gfx::SizeF(800, 600)); - root_clip_node.transform_id = kRealRootNodeId; - clip_tree.set_needs_update(true); - - auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; - auto& root_scroll_node = - *scroll_tree.Node(scroll_tree.Insert(ScrollNode(), kRealRootNodeId)); - DCHECK_EQ(root_scroll_node.id, kRootNodeId); - root_scroll_node.transform_id = kRealRootNodeId; - scroll_tree.set_needs_update(true); - - // Setup the root Layer which should be used to attach the layer list. - root_ = Layer::Create(); - root_->SetBounds(gfx::Size(800, 600)); - root_->SetIsDrawable(true); - root_->SetHitTestable(true); - root_->SetTransformTreeIndex(root_transform_node.id); - root_->SetEffectTreeIndex(root_effect_node.id); - root_->SetScrollTreeIndex(root_scroll_node.id); - root_->SetClipTreeIndex(root_clip_node.id); - layer_tree_host()->SetRootLayer(root_); - - layer_tree_host()->SetViewportSizeAndScale(gfx::Size(800, 600), 1.f, - viz::LocalSurfaceIdAllocation()); - - layer_tree_host()->property_trees()->sequence_number = - root_->property_tree_sequence_number(); - - root_->SetNeedsCommit(); - } - - Layer* root() const { return root_.get(); } - - private: - // The compositor is hard-coded to use 0 for the root nodes (always non-null). - static constexpr int kRealRootNodeId = 0; - - scoped_refptr<Layer> root_; -}; + NonScrollingNonFastScrollableRegion() { SetUseLayerLists(); } -class NonScrollingNonFastScrollableRegion - : public LayerListLayerTreeHostScrollTest { - public: // Setup 3 Layers: // 1) bottom_ which has a non-fast region in the bottom-right. // 2) middle_scrollable_ which is scrollable. // 3) top_ which has a non-fast region in the top-left and is offset by // |middle_scrollable_|'s scroll offset. void SetupTree() override { - LayerListLayerTreeHostScrollTest::SetupTree(); - - fake_content_layer_client_.set_bounds(root()->bounds()); - - std::vector<scoped_refptr<Layer>> layer_list; + SetInitialRootBounds(gfx::Size(800, 600)); + LayerTreeHostScrollTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + fake_content_layer_client_.set_bounds(root->bounds()); bottom_ = FakePictureLayer::Create(&fake_content_layer_client_); bottom_->SetElementId(LayerIdToElementIdForTesting(bottom_->id())); bottom_->SetBounds(gfx::Size(100, 100)); bottom_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50))); bottom_->SetHitTestable(true); - bottom_->SetTransformTreeIndex(kRootNodeId); - bottom_->SetEffectTreeIndex(kRootNodeId); - bottom_->SetScrollTreeIndex(kRootNodeId); - bottom_->SetClipTreeIndex(kRootNodeId); - bottom_->set_property_tree_sequence_number( - root()->property_tree_sequence_number()); - layer_list.push_back(bottom_); - - auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; - auto& scroll_node = - *scroll_tree.Node(scroll_tree.Insert(ScrollNode(), kRootNodeId)); - scroll_node.transform_id = kRootNodeId; + CopyProperties(root, bottom_.get()); + root->AddChild(bottom_); + middle_scrollable_ = FakePictureLayer::Create(&fake_content_layer_client_); middle_scrollable_->SetElementId( LayerIdToElementIdForTesting(middle_scrollable_->id())); - scroll_node.element_id = middle_scrollable_->element_id(); - scroll_node.scrollable = true; - scroll_node.bounds = gfx::Size(100, 200); - scroll_node.container_bounds = gfx::Size(100, 100); middle_scrollable_->SetBounds(gfx::Size(100, 100)); middle_scrollable_->SetIsDrawable(true); middle_scrollable_->SetScrollable(gfx::Size(100, 200)); middle_scrollable_->SetHitTestable(true); - middle_scrollable_->SetTransformTreeIndex(kRootNodeId); - middle_scrollable_->SetEffectTreeIndex(kRootNodeId); - middle_scrollable_->SetScrollTreeIndex(scroll_node.id); - middle_scrollable_->SetClipTreeIndex(kRootNodeId); - middle_scrollable_->set_property_tree_sequence_number( - root()->property_tree_sequence_number()); - layer_list.push_back(middle_scrollable_); + CopyProperties(bottom_.get(), middle_scrollable_.get()); + CreateTransformNode(middle_scrollable_.get()); + CreateScrollNode(middle_scrollable_.get()); + root->AddChild(middle_scrollable_); top_ = FakePictureLayer::Create(&fake_content_layer_client_); top_->SetElementId(LayerIdToElementIdForTesting(top_->id())); top_->SetBounds(gfx::Size(100, 100)); top_->SetNonFastScrollableRegion(Region(gfx::Rect(0, 0, 50, 50))); top_->SetHitTestable(true); - top_->SetTransformTreeIndex(kRootNodeId); - top_->SetEffectTreeIndex(kRootNodeId); - top_->SetScrollTreeIndex(scroll_node.id); - top_->SetClipTreeIndex(kRootNodeId); - top_->set_property_tree_sequence_number( - root()->property_tree_sequence_number()); - - layer_list.push_back(top_); - root()->SetChildLayerList(std::move(layer_list)); + CopyProperties(middle_scrollable_.get(), top_.get()); + root->AddChild(top_); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -2404,8 +2301,6 @@ class NonScrollingNonFastScrollableRegion EndTest(); } - void AfterTest() override {} - private: FakeContentLayerClient fake_content_layer_client_; scoped_refptr<Layer> bottom_; diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index fe75edcd991..1bb42de1429 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -55,6 +55,50 @@ #include "ui/gfx/geometry/vector2d_conversions.h" namespace cc { +namespace { +// Small helper class that saves the current viewport location as the user sees +// it and resets to the same location. +class ViewportAnchor { + public: + ViewportAnchor(ScrollNode* inner_scroll, + LayerImpl* outer_scroll, + LayerTreeImpl* tree_impl) + : inner_(inner_scroll), outer_(outer_scroll), tree_impl_(tree_impl) { + viewport_in_content_coordinates_ = + scroll_tree().current_scroll_offset(inner_->element_id); + + if (outer_) + viewport_in_content_coordinates_ += outer_->CurrentScrollOffset(); + } + + void ResetViewportToAnchoredPosition() { + DCHECK(outer_); + + scroll_tree().ClampScrollToMaxScrollOffset(inner_, tree_impl_); + outer_->ClampScrollToMaxScrollOffset(); + + gfx::ScrollOffset viewport_location = + scroll_tree().current_scroll_offset(inner_->element_id) + + outer_->CurrentScrollOffset(); + + gfx::Vector2dF delta = + viewport_in_content_coordinates_.DeltaFrom(viewport_location); + + delta = scroll_tree().ScrollBy(inner_, delta, tree_impl_); + outer_->ScrollBy(delta); + } + + private: + ScrollTree& scroll_tree() { + return tree_impl_->property_trees()->scroll_tree; + } + + ScrollNode* inner_; + LayerImpl* outer_; + LayerTreeImpl* tree_impl_; + gfx::ScrollOffset viewport_in_content_coordinates_; +}; +} // namespace void LayerTreeLifecycle::AdvanceTo(LifecycleState next_state) { switch (next_state) { @@ -344,6 +388,96 @@ void LayerTreeImpl::InvalidateRegionForImages( invalidated_count)); } +void LayerTreeImpl::UpdateViewportContainerSizes() { + if (!InnerViewportScrollNode()) + return; + + ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollLayer(), + this); + + // Top/bottom controls always share the same shown ratio. + float controls_shown_ratio = + top_controls_shown_ratio_->Current(IsActiveTree()); + float top_controls_layout_height = + browser_controls_shrink_blink_size() ? top_controls_height() : 0.f; + float top_content_offset = top_controls_height_ > 0 + ? top_controls_height_ * controls_shown_ratio + : 0.0f; + float delta_from_top_controls = + top_controls_layout_height - top_content_offset; + float bottom_controls_layout_height = + browser_controls_shrink_blink_size() ? bottom_controls_height() : 0.f; + float bottom_content_offset = + bottom_controls_height_ > 0 + ? bottom_controls_height_ * controls_shown_ratio + : 0.0f; + delta_from_top_controls += + bottom_controls_layout_height - bottom_content_offset; + + // Adjust the viewport layers by shrinking/expanding the container to account + // for changes in the size (e.g. browser controls) since the last resize from + // Blink. + auto* property_trees = this->property_trees(); + gfx::Vector2dF bounds_delta(0.f, delta_from_top_controls); + if (property_trees->inner_viewport_container_bounds_delta() == bounds_delta) + return; + + property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta); + + ClipNode* inner_clip_node = property_trees->clip_tree.Node( + InnerViewportScrollLayer()->clip_tree_index()); + inner_clip_node->clip.set_height( + InnerViewportScrollNode()->container_bounds.height() + bounds_delta.y()); + + // Adjust the outer viewport container as well, since adjusting only the + // inner may cause its bounds to exceed those of the outer, causing scroll + // clamping. + if (OuterViewportScrollNode()) { + gfx::Vector2dF scaled_bounds_delta = + gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor()); + + property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta); + property_trees->SetInnerViewportScrollBoundsDelta(scaled_bounds_delta); + + ClipNode* outer_clip_node = property_trees->clip_tree.Node( + OuterViewportScrollLayer()->clip_tree_index()); + + float adjusted_container_height = + OuterViewportScrollNode()->container_bounds.height() + + scaled_bounds_delta.y(); + outer_clip_node->clip.set_height(adjusted_container_height); + + // Expand all clips between the outer viewport and the inner viewport. + auto* outer_ancestor = property_trees->clip_tree.parent(outer_clip_node); + while (outer_ancestor && outer_ancestor != inner_clip_node) { + outer_ancestor->clip.Union(outer_clip_node->clip); + outer_ancestor = property_trees->clip_tree.parent(outer_ancestor); + } + + anchor.ResetViewportToAnchoredPosition(); + } + + property_trees->clip_tree.set_needs_update(true); + property_trees->full_tree_damaged = true; + set_needs_update_draw_properties(); + + // Viewport scrollbar positions are determined using the viewport bounds + // delta. + SetScrollbarGeometriesNeedUpdate(); + set_needs_update_draw_properties(); + + // For pre-BlinkGenPropertyTrees mode, we need to ensure the layers are + // appropriately updated. + if (!settings().use_layer_lists) { + if (OuterViewportContainerLayer()) + OuterViewportContainerLayer()->NoteLayerPropertyChanged(); + if (InnerViewportScrollLayer()) + InnerViewportScrollLayer()->NoteLayerPropertyChanged(); + if (OuterViewportScrollLayer()) + OuterViewportScrollLayer()->NoteLayerPropertyChanged(); + } +} + bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const { return layer_list_.empty() ? false : layer_list_[0] == layer; } @@ -398,7 +532,6 @@ void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { property_trees->effect_tree.PushCopyRequestsTo(&property_trees_.effect_tree); property_trees_.is_main_thread = false; property_trees_.is_active = IsActiveTree(); - property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); // The value of some effect node properties (like is_drawn) depends on // whether we are on the active tree or not. So, we need to update the // effect tree. @@ -485,8 +618,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->set_painted_device_scale_factor(painted_device_scale_factor()); target_tree->SetDeviceScaleFactor(device_scale_factor()); - target_tree->SetDeviceViewportSize(device_viewport_size_); - target_tree->SetViewportVisibleRect(viewport_visible_rect_); + target_tree->SetDeviceViewportRect(device_viewport_rect_); if (TakeNewLocalSurfaceIdRequest()) target_tree->RequestNewLocalSurfaceId(); @@ -892,23 +1024,9 @@ void LayerTreeImpl::UpdatePageScaleNode() { return; } - // When the page scale layer is also the root layer (this happens in the UI - // compositor), the node should also store the combined scale factor and not - // just the page scale factor. - // TODO(crbug.com/909750): Implement this behavior without PageScaleLayer, - // e.g. when we switch the UI compositor to create property trees. - float device_scale_factor_for_page_scale_layer = 1.f; - gfx::Transform device_transform_for_page_scale_layer; - if (IsRootLayer(PageScaleLayer())) { - DCHECK(!settings().use_layer_lists); - device_transform_for_page_scale_layer = host_impl_->DrawTransform(); - device_scale_factor_for_page_scale_layer = device_scale_factor(); - } - + DCHECK(!IsRootLayer(PageScaleLayer())); draw_property_utils::UpdatePageScaleFactor( - property_trees(), PageScaleTransformNode(), current_page_scale_factor(), - device_scale_factor_for_page_scale_layer, - device_transform_for_page_scale_layer); + property_trees(), PageScaleTransformNode(), current_page_scale_factor()); } void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) { @@ -971,8 +1089,7 @@ void LayerTreeImpl::set_browser_controls_shrink_blink_size(bool shrink) { return; browser_controls_shrink_blink_size_ = shrink; - if (IsActiveTree()) - host_impl_->UpdateViewportContainerSizes(); + UpdateViewportContainerSizes(); } void LayerTreeImpl::SetTopControlsHeight(float top_controls_height) { @@ -980,8 +1097,7 @@ void LayerTreeImpl::SetTopControlsHeight(float top_controls_height) { return; top_controls_height_ = top_controls_height; - if (IsActiveTree()) - host_impl_->UpdateViewportContainerSizes(); + UpdateViewportContainerSizes(); } void LayerTreeImpl::SetBottomControlsHeight(float bottom_controls_height) { @@ -989,8 +1105,7 @@ void LayerTreeImpl::SetBottomControlsHeight(float bottom_controls_height) { return; bottom_controls_height_ = bottom_controls_height; - if (IsActiveTree()) - host_impl_->UpdateViewportContainerSizes(); + UpdateViewportContainerSizes(); } void LayerTreeImpl::set_overscroll_behavior( @@ -1023,7 +1138,10 @@ void LayerTreeImpl::PushBrowserControls(const float* top_controls_shown_ratio) { if (top_controls_shown_ratio) { DCHECK(!IsActiveTree() || !host_impl_->pending_tree()); - top_controls_shown_ratio_->PushMainToPending(*top_controls_shown_ratio); + bool changed_pending = + top_controls_shown_ratio_->PushMainToPending(*top_controls_shown_ratio); + if (!IsActiveTree() && changed_pending) + UpdateViewportContainerSizes(); } if (IsActiveTree()) { bool changed_active = top_controls_shown_ratio_->PushPendingToActive(); @@ -1097,38 +1215,27 @@ bool LayerTreeImpl::TakeNewLocalSurfaceIdRequest() { return new_local_surface_id_request; } -void LayerTreeImpl::SetDeviceViewportSize( - const gfx::Size& device_viewport_size) { - if (device_viewport_size == device_viewport_size_) +void LayerTreeImpl::SetDeviceViewportRect( + const gfx::Rect& device_viewport_rect) { + if (device_viewport_rect == device_viewport_rect_) return; - device_viewport_size_ = device_viewport_size; + device_viewport_rect_ = device_viewport_rect; set_needs_update_draw_properties(); if (!IsActiveTree()) return; - host_impl_->UpdateViewportContainerSizes(); + UpdateViewportContainerSizes(); host_impl_->OnCanDrawStateChangedForTree(); host_impl_->SetViewportDamage(GetDeviceViewport()); } -void LayerTreeImpl::SetViewportVisibleRect(const gfx::Rect& visible_rect) { - if (visible_rect == viewport_visible_rect_) - return; - - viewport_visible_rect_ = visible_rect; - - set_needs_update_draw_properties(); - if (IsActiveTree()) - host_impl_->SetViewportDamage(GetDeviceViewport()); -} - gfx::Rect LayerTreeImpl::GetDeviceViewport() const { // TODO(fsamuel): We should plumb |external_viewport| similar to the - // way we plumb |device_viewport_size_|. + // way we plumb |device_viewport_rect_|. const gfx::Rect& external_viewport = host_impl_->external_viewport(); if (external_viewport.IsEmpty()) - return gfx::Rect(device_viewport_size_); + return device_viewport_rect_; return external_viewport; } @@ -1282,7 +1389,7 @@ bool LayerTreeImpl::UpdateDrawProperties( // calculations except when this function is explicitly passed a flag asking // us to skip it. LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - layer_list_[0], GetDeviceViewport().size(), host_impl_->DrawTransform(), + layer_list_[0], GetDeviceViewport(), host_impl_->DrawTransform(), device_scale_factor(), current_page_scale_factor(), PageScaleLayer(), InnerViewportScrollLayer(), OuterViewportScrollLayer(), elastic_overscroll()->Current(IsActiveTree()), @@ -1301,7 +1408,7 @@ bool LayerTreeImpl::UpdateDrawProperties( } } - { + if (settings().enable_occlusion) { TRACE_EVENT2("cc,benchmark", "LayerTreeImpl::UpdateDrawProperties::Occlusion", "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); @@ -1358,6 +1465,10 @@ bool LayerTreeImpl::UpdateDrawProperties( unoccluded_screen_space_region_ = occlusion_tracker.ComputeVisibleRegionInScreen(this); + } else { + // No occlusion, entire root content rect is unoccluded. + unoccluded_screen_space_region_ = + Region(RootRenderSurface()->content_rect()); } // Resourceless draw do not need tiles and should not affect existing tile @@ -1411,7 +1522,6 @@ void LayerTreeImpl::BuildLayerListAndPropertyTreesForTesting() { void LayerTreeImpl::BuildPropertyTreesForTesting() { SetElementIdsForTesting(); property_trees_.needs_rebuild = true; - property_trees_.transform_tree.set_source_to_parent_updates_allowed(true); PropertyTreeBuilder::BuildPropertyTrees( layer_list_[0], PageScaleLayer(), InnerViewportScrollLayer(), OuterViewportScrollLayer(), OverscrollElasticityElementId(), @@ -1419,7 +1529,6 @@ void LayerTreeImpl::BuildPropertyTreesForTesting() { current_page_scale_factor(), device_scale_factor(), gfx::Rect(GetDeviceViewport().size()), host_impl_->DrawTransform(), &property_trees_); - property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); host_impl_->UpdateElements(GetElementTypeForAnimation()); } @@ -2027,8 +2136,7 @@ static bool PointIsClippedByAncestorClipNode( layer->layer_tree_impl()->property_trees(); const ClipTree& clip_tree = property_trees->clip_tree; const TransformTree& transform_tree = property_trees->transform_tree; - const ClipNode* clip_node = clip_tree.Node(1); - gfx::Rect clip = gfx::ToEnclosingRect(clip_node->clip); + gfx::Rect clip = gfx::ToEnclosingRect(clip_tree.Node(1)->clip); if (!PointHitsRect(screen_space_point, gfx::Transform(), clip, nullptr)) return true; @@ -2036,7 +2144,7 @@ static bool PointIsClippedByAncestorClipNode( clip_node->id > ClipTree::kViewportNodeId; clip_node = clip_tree.parent(clip_node)) { if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { - gfx::Rect clip = gfx::ToEnclosingRect(clip_node->clip); + clip = gfx::ToEnclosingRect(clip_node->clip); gfx::Transform screen_space_transform = transform_tree.ToScreen(clip_node->transform_id); diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 5efd40a6f8f..666701c4360 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -20,6 +20,7 @@ #include "cc/input/overscroll_behavior.h" #include "cc/layers/layer_impl.h" #include "cc/layers/layer_list_iterator.h" +#include "cc/paint/discardable_image_map.h" #include "cc/resources/ui_resource_client.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h" @@ -357,11 +358,7 @@ class CC_EXPORT LayerTreeImpl { return new_local_surface_id_request_; } - void SetDeviceViewportSize(const gfx::Size& device_viewport_size); - void SetViewportVisibleRect(const gfx::Rect& visible_rect); - const gfx::Rect& viewport_visible_rect() const { - return viewport_visible_rect_; - } + void SetDeviceViewportRect(const gfx::Rect& device_viewport_rect); // TODO(fsamuel): The reason this is not a trivial accessor is because it // may return an external viewport specified in LayerTreeHostImpl. In the @@ -369,6 +366,10 @@ class CC_EXPORT LayerTreeImpl { // trees and we shouldn't need to reach out to LayerTreeHostImpl. gfx::Rect GetDeviceViewport() const; + // This accessor is the same as above, except it only ever returns the + // internal (i.e. not external) device viewport. + gfx::Rect internal_device_viewport() { return device_viewport_rect_; } + void SetRasterColorSpace(int raster_color_space_id, const gfx::ColorSpace& raster_color_space); // OOPIFs need to know the page scale factor used in the main frame, but it @@ -657,6 +658,8 @@ class CC_EXPORT LayerTreeImpl { void InvalidateRegionForImages( const PaintImageIdFlatSet& images_to_invalidate); + void UpdateViewportContainerSizes(); + LayerTreeLifecycle& lifecycle() { return lifecycle_; } std::string LayerListAsJson() const; @@ -664,6 +667,10 @@ class CC_EXPORT LayerTreeImpl { // of layers, only a list. std::string LayerTreeAsJson() const; + AnimatedPaintWorkletTracker& paint_worklet_tracker() { + return host_impl_->paint_worklet_tracker(); + } + protected: float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, @@ -715,12 +722,9 @@ class CC_EXPORT LayerTreeImpl { viz::LocalSurfaceIdAllocation local_surface_id_allocation_from_parent_; bool new_local_surface_id_request_ = false; - gfx::Size device_viewport_size_; - - // Viewport clip rect passed in from the main thrad, in physical pixels. - // This is used for out-of-process iframes whose size exceeds the window - // in order to prevent full raster. - gfx::Rect viewport_visible_rect_; + // Contains the physical rect of the device viewport, to be used in + // determining what needs to be drawn. + gfx::Rect device_viewport_rect_; scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 11d6bbc38d7..4b2a48a7594 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -19,87 +19,81 @@ namespace cc { namespace { -class LayerTreeImplTest : public testing::Test { +class LayerTreeImplTest : public LayerTestCommon::LayerImplTest, + public testing::Test { public: explicit LayerTreeImplTest( - const LayerTreeSettings& settings = LayerTreeSettings()) - : impl_test_(settings) {} + const LayerTreeSettings& settings = LayerListSettings()) + : LayerImplTest(settings) {} - FakeLayerTreeHostImpl& host_impl() const { return *impl_test_.host_impl(); } + void SetUp() override { + root_layer()->SetBounds(gfx::Size(100, 100)); + SetupRootProperties(root_layer()); + UpdateDrawProperties(host_impl().active_tree()); + } - LayerImpl* root_layer() { return impl_test_.root_layer_for_testing(); } + FakeLayerTreeHostImpl& host_impl() const { + return *LayerImplTest::host_impl(); + } + LayerImpl* root_layer() { return root_layer_for_testing(); } const RenderSurfaceList& GetRenderSurfaceList() const { return host_impl().active_tree()->GetRenderSurfaceList(); } - 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()); - - render_surface_list_impl_.clear(); - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_list_impl_); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - } - - int HitTestSimpleTree(int root_id, - int left_child_id, - int right_child_id, - int root_sorting_context, - int left_child_sorting_context, - int right_child_sorting_context, - float root_depth, - float left_child_depth, - float right_child_depth) { - host_impl().active_tree()->SetRootLayerForTesting(nullptr); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl().active_tree(), root_id); - std::unique_ptr<LayerImpl> left_child = - LayerImpl::Create(host_impl().active_tree(), left_child_id); - std::unique_ptr<LayerImpl> right_child = - LayerImpl::Create(host_impl().active_tree(), right_child_id); + LayerImpl* HitTestSimpleTree(int top_sorting_context, + int left_child_sorting_context, + int right_child_sorting_context, + float top_depth, + float left_child_depth, + float right_child_depth) { + top_ = AddLayer<LayerImpl>(); + left_child_ = AddLayer<LayerImpl>(); + right_child_ = AddLayer<LayerImpl>(); gfx::Size bounds(100, 100); { gfx::Transform translate_z; - translate_z.Translate3d(0, 0, root_depth); - root->test_properties()->transform = translate_z; - root->test_properties()->sorting_context_id = root_sorting_context; - root->SetBounds(bounds); - root->SetDrawsContent(true); - root->SetHitTestable(true); + translate_z.Translate3d(0, 0, top_depth); + top_->SetBounds(bounds); + top_->SetDrawsContent(true); + top_->SetHitTestable(true); + + CopyProperties(root_layer(), top_); + auto& transform_node = CreateTransformNode(top_); + transform_node.local = translate_z; + transform_node.sorting_context_id = top_sorting_context; } { gfx::Transform translate_z; translate_z.Translate3d(0, 0, left_child_depth); - left_child->test_properties()->transform = translate_z; - left_child->test_properties()->sorting_context_id = - left_child_sorting_context; - left_child->SetBounds(bounds); - left_child->SetDrawsContent(true); - left_child->SetHitTestable(true); - left_child->test_properties()->should_flatten_transform = false; + left_child_->SetBounds(bounds); + left_child_->SetDrawsContent(true); + left_child_->SetHitTestable(true); + + CopyProperties(top_, left_child_); + auto& transform_node = CreateTransformNode(left_child_); + transform_node.local = translate_z; + transform_node.sorting_context_id = left_child_sorting_context; + transform_node.flattens_inherited_transform = false; } { gfx::Transform translate_z; translate_z.Translate3d(0, 0, right_child_depth); - right_child->test_properties()->transform = translate_z; - right_child->test_properties()->sorting_context_id = - right_child_sorting_context; - right_child->SetBounds(bounds); - right_child->SetDrawsContent(true); - right_child->SetHitTestable(true); + right_child_->SetBounds(bounds); + right_child_->SetDrawsContent(true); + right_child_->SetHitTestable(true); + + CopyProperties(top_, right_child_); + auto& transform_node = CreateTransformNode(right_child_); + transform_node.local = translate_z; + transform_node.sorting_context_id = right_child_sorting_context; } - root->test_properties()->AddChild(std::move(left_child)); - root->test_properties()->AddChild(std::move(right_child)); + root_layer()->SetBounds(top_->bounds()); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(top_->bounds())); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + UpdateDrawProperties(host_impl().active_tree()); CHECK_EQ(1u, GetRenderSurfaceList().size()); gfx::PointF test_point = gfx::PointF(1.f, 1.f); @@ -107,14 +101,23 @@ class LayerTreeImplTest : public testing::Test { host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); CHECK(result_layer); - return result_layer->id(); + return result_layer; } + // These layers are created by HitTestSimpleTree(). + LayerImpl* top_ = nullptr; + LayerImpl* left_child_ = nullptr; + LayerImpl* right_child_ = nullptr; + private: - LayerTestCommon::LayerImplTest impl_test_; RenderSurfaceList render_surface_list_impl_; }; +class LayerTreeImplTestWithLayerLists : public LayerTreeImplTest { + public: + LayerTreeImplTestWithLayerLists() : LayerTreeImplTest(LayerListSettings()) {} +}; + TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { gfx::Size bounds(100, 100); LayerImpl* root = root_layer(); @@ -122,8 +125,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { root->SetDrawsContent(true); root->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -145,13 +148,13 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); test_point = gfx::PointF(99.f, 99.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); } TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) { @@ -162,15 +165,15 @@ TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) { root->SetDrawsContent(true); root->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); EXPECT_EQ( gfx::RectF(gfx::SizeF(bounds)), host_impl().active_tree()->property_trees()->clip_tree.ViewportClip()); EXPECT_EQ(gfx::Rect(bounds), root->visible_layer_rect()); gfx::Size new_bounds(50, 50); - host_impl().active_tree()->SetDeviceViewportSize(new_bounds); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(new_bounds)); gfx::PointF test_point(51.f, 51.f); host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); EXPECT_EQ( @@ -186,16 +189,15 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { root->SetHitTestable(true); // Create hud and add it as a child of root. - std::unique_ptr<HeadsUpDisplayLayerImpl> hud = - HeadsUpDisplayLayerImpl::Create(host_impl().active_tree(), 11111); + auto* hud = AddLayer<HeadsUpDisplayLayerImpl>(); hud->SetBounds(gfx::Size(200, 200)); hud->SetDrawsContent(true); hud->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(hud->bounds()); - host_impl().active_tree()->set_hud_layer(hud.get()); - root->test_properties()->AddChild(std::move(hud)); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(hud->bounds())); + host_impl().active_tree()->set_hud_layer(hud); + CopyProperties(root, hud); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -218,13 +220,13 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); test_point = gfx::PointF(99.f, 99.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { @@ -236,17 +238,20 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { ASSERT_FALSE(uninvertible_transform.IsInvertible()); LayerImpl* root = root_layer(); - root->test_properties()->transform = uninvertible_transform; - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* layer = AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->SetDrawsContent(true); + layer->SetHitTestable(true); + root->SetBounds(layer->bounds()); + CopyProperties(root, layer); + CreateTransformNode(layer).local = uninvertible_transform; + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); - ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); - ASSERT_FALSE(root_layer()->ScreenSpaceTransform().IsInvertible()); + ASSERT_FALSE(layer->ScreenSpaceTransform().IsInvertible()); // Hit testing any point should not hit the layer. If the invertible matrix is // accidentally ignored and treated like an identity, then the hit testing @@ -290,19 +295,16 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { // This layer is positioned, and hit testing should correctly know where the // layer is located. - { - std::unique_ptr<LayerImpl> test_layer = - LayerImpl::Create(host_impl().active_tree(), 12345); - test_layer->test_properties()->position = gfx::PointF(50.f, 50.f); - test_layer->SetBounds(gfx::Size(100, 100)); - test_layer->SetDrawsContent(true); - test_layer->SetHitTestable(true); - root_layer()->test_properties()->AddChild(std::move(test_layer)); - } + LayerImpl* test_layer = AddLayer<LayerImpl>(); + test_layer->SetBounds(gfx::Size(100, 100)); + test_layer->SetDrawsContent(true); + test_layer->SetHitTestable(true); + CopyProperties(root_layer(), test_layer); + test_layer->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 50.f)); - LayerImpl* test_layer = root_layer()->test_properties()->children[0]; - host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect( + gfx::Rect(test_layer->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -326,29 +328,33 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(test_layer->id(), result_layer->id()); + EXPECT_EQ(test_layer, result_layer); test_point = gfx::PointF(99.f, 99.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(test_layer->id(), result_layer->id()); + EXPECT_EQ(test_layer, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) { + LayerImpl* root = root_layer(); + gfx::Transform rotation45_degrees_about_center; rotation45_degrees_about_center.Translate(50.0, 50.0); rotation45_degrees_about_center.RotateAboutZAxis(45.0); rotation45_degrees_about_center.Translate(-50.0, -50.0); - LayerImpl* root = root_layer(); - root->test_properties()->transform = rotation45_degrees_about_center; - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); + LayerImpl* layer = AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->SetDrawsContent(true); + layer->SetHitTestable(true); + root->SetBounds(layer->bounds()); + CopyProperties(root, layer); + CreateTransformNode(layer).local = rotation45_degrees_about_center; - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -372,7 +378,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(layer, result_layer); // Hit testing the corners that would overlap the unclipped layer, but are // outside the clipped region. @@ -395,37 +401,34 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) { gfx::Transform translation; translation.Translate(100, 100); - std::unique_ptr<LayerImpl> render_surface = - LayerImpl::Create(host_impl().active_tree(), 2); - render_surface->test_properties()->transform = translation; + LayerImpl* render_surface = AddLayer<LayerImpl>(); render_surface->SetBounds(gfx::Size(100, 100)); - render_surface->test_properties()->force_render_surface = true; + CopyProperties(root, render_surface); + CreateTransformNode(render_surface).local = translation; + CreateEffectNode(render_surface).render_surface_reason = + RenderSurfaceReason::kTest; gfx::Transform scale_matrix; scale_matrix.Scale(2, 2); - std::unique_ptr<LayerImpl> scale = - LayerImpl::Create(host_impl().active_tree(), 3); - scale->test_properties()->transform = scale_matrix; + LayerImpl* scale = AddLayer<LayerImpl>(); scale->SetBounds(gfx::Size(50, 50)); + CopyProperties(render_surface, scale); + CreateTransformNode(scale).local = scale_matrix; - std::unique_ptr<LayerImpl> clip = - LayerImpl::Create(host_impl().active_tree(), 4); + LayerImpl* clip = AddLayer<LayerImpl>(); clip->SetBounds(gfx::Size(25, 25)); clip->SetMasksToBounds(true); + CopyProperties(scale, clip); + CreateClipNode(clip); - std::unique_ptr<LayerImpl> test = - LayerImpl::Create(host_impl().active_tree(), 5); + LayerImpl* test = AddLayer<LayerImpl>(); test->SetBounds(gfx::Size(100, 100)); test->SetDrawsContent(true); test->SetHitTestable(true); + CopyProperties(clip, test); - clip->test_properties()->AddChild(std::move(test)); - scale->test_properties()->AddChild(std::move(clip)); - render_surface->test_properties()->AddChild(std::move(scale)); - root->test_properties()->AddChild(std::move(render_surface)); - - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); gfx::PointF test_point(160.f, 160.f); LayerImpl* result_layer = @@ -436,7 +439,7 @@ TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(5, result_layer->id()); + EXPECT_EQ(test, result_layer); } TEST_F(LayerTreeImplTest, HitTestingSiblings) { @@ -444,36 +447,38 @@ TEST_F(LayerTreeImplTest, HitTestingSiblings) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl().active_tree(), 2); + LayerImpl* child1 = AddLayer<LayerImpl>(); child1->SetBounds(gfx::Size(25, 25)); child1->SetMasksToBounds(true); child1->SetDrawsContent(true); child1->SetHitTestable(true); + CopyProperties(root, child1); + CreateClipNode(child1); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl().active_tree(), 3); + LayerImpl* child2 = AddLayer<LayerImpl>(); child2->SetBounds(gfx::Size(75, 75)); child2->SetMasksToBounds(true); child2->SetDrawsContent(true); child2->SetHitTestable(true); + CopyProperties(root, child2); + CreateClipNode(child2); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); gfx::PointF test_point(50.f, 50.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { - // perspective_projection_about_center * translation_by_z is designed so that - // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50). + LayerImpl* root = root_layer(); + + // perspective_projection_about_center * translation_by_z is designed so + // that the 100 x 100 layer becomes 50 x 50, and remains centered at (50, + // 50). gfx::Transform perspective_projection_about_center; perspective_projection_about_center.Translate(50.0, 50.0); perspective_projection_about_center.ApplyPerspectiveDepth(1.0); @@ -481,15 +486,17 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { gfx::Transform translation_by_z; translation_by_z.Translate3d(0.0, 0.0, -1.0); - LayerImpl* root = root_layer(); - root->test_properties()->transform = + LayerImpl* layer = AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->SetDrawsContent(true); + layer->SetHitTestable(true); + root->SetBounds(layer->bounds()); + CopyProperties(root, layer); + CreateTransformNode(layer).local = (perspective_projection_about_center * translation_by_z); - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -512,14 +519,12 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { test_point = gfx::PointF(26.f, 26.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(layer, result_layer); test_point = gfx::PointF(74.f, 74.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(layer, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { @@ -528,33 +533,30 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { // case. LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - { - std::unique_ptr<LayerImpl> clipping_layer = - LayerImpl::Create(host_impl().active_tree(), 123); - // this layer is positioned, and hit testing should correctly know where the - // layer is located. - clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f); - clipping_layer->SetBounds(gfx::Size(50, 50)); - clipping_layer->SetMasksToBounds(true); - - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 456); - child->test_properties()->position = gfx::PointF(-50.f, -50.f); - child->SetBounds(gfx::Size(300, 300)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - clipping_layer->test_properties()->AddChild(std::move(child)); - root->test_properties()->AddChild(std::move(clipping_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* clipping_layer = AddLayer<LayerImpl>(); + // this layer is positioned, and hit testing should correctly know where the + // layer is located. + clipping_layer->SetBounds(gfx::Size(50, 50)); + clipping_layer->SetMasksToBounds(true); + CopyProperties(root, clipping_layer); + clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f)); + CreateClipNode(clipping_layer); + + LayerImpl* child = AddLayer<LayerImpl>(); + child->SetBounds(gfx::Size(300, 300)); + child->SetDrawsContent(true); + child->SetHitTestable(true); + CopyProperties(clipping_layer, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(-50.f, -50.f)); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); - LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); - EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); // Hit testing for a point outside the layer should return a null pointer. // Despite the child layer being very large, it should be clipped to the root @@ -575,14 +577,12 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { test_point = gfx::PointF(26.f, 26.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); test_point = gfx::PointF(74.f, 74.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { @@ -600,54 +600,50 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { root->SetBounds(gfx::Size(100, 100)); root->SetMasksToBounds(true); + CreateClipNode(root); + // 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. - { - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 456); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl().active_tree(), 789); - std::unique_ptr<LayerImpl> rotated_leaf = - LayerImpl::Create(host_impl().active_tree(), 2468); - - child->test_properties()->position = gfx::PointF(10.f, 10.f); - child->SetBounds(gfx::Size(80, 80)); - child->SetMasksToBounds(true); - - gfx::Transform rotation45_degrees_about_corner; - rotation45_degrees_about_corner.RotateAboutZAxis(45.0); - - // This is positioned with respect to its parent which is already at - // position (10, 10). - // The size is to ensure it covers at least sqrt(2) * 100. - grand_child->SetBounds(gfx::Size(200, 200)); - grand_child->test_properties()->transform = rotation45_degrees_about_corner; - grand_child->SetMasksToBounds(true); - - // Rotates about the center of the layer - gfx::Transform rotated_leaf_transform; - rotated_leaf_transform.Translate( - -10.0, -10.0); // cancel out the grand_parent's position - rotated_leaf_transform.RotateAboutZAxis( - -45.0); // cancel out the corner 45-degree rotation of the parent. - rotated_leaf_transform.Translate(50.0, 50.0); - rotated_leaf_transform.RotateAboutZAxis(45.0); - rotated_leaf_transform.Translate(-50.0, -50.0); - rotated_leaf->SetBounds(gfx::Size(100, 100)); - rotated_leaf->test_properties()->transform = rotated_leaf_transform; - rotated_leaf->SetDrawsContent(true); - rotated_leaf->SetHitTestable(true); - - grand_child->test_properties()->AddChild(std::move(rotated_leaf)); - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - - ExecuteCalculateDrawProperties(root); - } - - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* child = AddLayer<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); + LayerImpl* rotated_leaf = AddLayer<LayerImpl>(); + + child->SetBounds(gfx::Size(80, 80)); + child->SetMasksToBounds(true); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + CreateClipNode(child); + + gfx::Transform rotation45_degrees_about_corner; + rotation45_degrees_about_corner.RotateAboutZAxis(45.0); + + // This is positioned with respect to its parent which is already at + // position (10, 10). + // The size is to ensure it covers at least sqrt(2) * 100. + grand_child->SetBounds(gfx::Size(200, 200)); + grand_child->SetMasksToBounds(true); + CopyProperties(child, grand_child); + CreateTransformNode(grand_child).local = rotation45_degrees_about_corner; + CreateClipNode(grand_child); + + // Rotates about the center of the layer + gfx::Transform rotated_leaf_transform; + rotated_leaf_transform.Translate( + -10.0, -10.0); // cancel out the grand_parent's position + rotated_leaf_transform.RotateAboutZAxis( + -45.0); // cancel out the corner 45-degree rotation of the parent. + rotated_leaf_transform.Translate(50.0, 50.0); + rotated_leaf_transform.RotateAboutZAxis(45.0); + rotated_leaf_transform.Translate(-50.0, -50.0); + rotated_leaf->SetBounds(gfx::Size(100, 100)); + rotated_leaf->SetDrawsContent(true); + rotated_leaf->SetHitTestable(true); + CopyProperties(grand_child, rotated_leaf); + CreateTransformNode(rotated_leaf).local = rotated_leaf_transform; + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // (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); @@ -659,8 +655,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { test_point = gfx::PointF(25.f, 75.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2468, result_layer->id()); + EXPECT_EQ(rotated_leaf, result_layer); // (4, 50) is inside the unclipped layer, but that corner of the layer should // be clipped away by the grandparent and should not get hit. If hit testing @@ -676,8 +671,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { test_point = gfx::PointF(11.f, 50.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2468, result_layer->id()); + EXPECT_EQ(rotated_leaf, result_layer); // Around the middle, just to the right and up, would have hit the layer // except that that area should be clipped away by the parent. @@ -691,8 +685,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { test_point = gfx::PointF(49.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2468, result_layer->id()); + EXPECT_EQ(rotated_leaf, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { @@ -701,39 +694,34 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - { - std::unique_ptr<LayerImpl> intermediate_layer = - LayerImpl::Create(host_impl().active_tree(), 123); - // this layer is positioned, and hit testing should correctly know where the - // layer is located. - intermediate_layer->test_properties()->position = gfx::PointF(10.f, 10.f); - intermediate_layer->SetBounds(gfx::Size(50, 50)); - // Sanity check the intermediate layer should not clip. - ASSERT_FALSE(intermediate_layer->masks_to_bounds()); - ASSERT_FALSE(intermediate_layer->test_properties()->mask_layer); - - // The child of the intermediate_layer is translated so that it does not - // overlap intermediate_layer at all. If child is incorrectly clipped, we - // would not be able to hit it successfully. - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 456); - child->test_properties()->position = - gfx::PointF(60.f, 60.f); // 70, 70 in screen spae - child->SetBounds(gfx::Size(20, 20)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - intermediate_layer->test_properties()->AddChild(std::move(child)); - root->test_properties()->AddChild(std::move(intermediate_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* intermediate_layer = AddLayer<LayerImpl>(); + intermediate_layer->SetBounds(gfx::Size(50, 50)); + // Sanity check the intermediate layer should not clip. + ASSERT_FALSE(intermediate_layer->masks_to_bounds()); + ASSERT_FALSE(intermediate_layer->test_properties()->mask_layer); + CopyProperties(root, intermediate_layer); + // this layer is positioned, and hit testing should correctly know where the + // layer is located. + intermediate_layer->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + + // The child of the intermediate_layer is translated so that it does not + // overlap intermediate_layer at all. If child is incorrectly clipped, we + // would not be able to hit it successfully. + LayerImpl* child = AddLayer<LayerImpl>(); + child->SetBounds(gfx::Size(20, 20)); + child->SetDrawsContent(true); + child->SetHitTestable(true); + CopyProperties(intermediate_layer, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(70.f, 70.f)); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); - LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); - EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); // Hit testing for a point outside the layer should return a null pointer. gfx::PointF test_point(69.f, 69.f); @@ -750,14 +738,12 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { test_point = gfx::PointF(71.f, 71.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); test_point = gfx::PointF(89.f, 89.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); } TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { @@ -765,51 +751,40 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - { - // child 1 and child2 are initialized to overlap between x=50 and x=60. - // grand_child is set to overlap both child1 and child2 between y=50 and - // y=60. The expected stacking order is: (front) child2, (second) - // grand_child, (third) child1, and (back) the root layer behind all other - // layers. - - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl().active_tree(), 3); - std::unique_ptr<LayerImpl> grand_child1 = - LayerImpl::Create(host_impl().active_tree(), 4); - - child1->test_properties()->position = gfx::PointF(10.f, 10.f); - child1->SetBounds(gfx::Size(50, 50)); - child1->SetDrawsContent(true); - child1->SetHitTestable(true); - - child2->test_properties()->position = gfx::PointF(50.f, 10.f); - child2->SetBounds(gfx::Size(50, 50)); - child2->SetDrawsContent(true); - child2->SetHitTestable(true); - - // Remember that grand_child is positioned with respect to its parent (i.e. - // child1). In screen space, the intended position is (10, 50), with size - // 100 x 50. - grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f); - grand_child1->SetBounds(gfx::Size(100, 50)); - grand_child1->SetDrawsContent(true); - grand_child1->SetHitTestable(true); - - child1->test_properties()->AddChild(std::move(grand_child1)); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - - ExecuteCalculateDrawProperties(root); - } - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grand_child1 = child1->test_properties()->children[0]; + // child1 and child2 are initialized to overlap between x=50 and x=60. + // grand_child is set to overlap both child1 and child2 between y=50 and + // y=60. The expected stacking order is: (front) child2, (second) + // grand_child, (third) child1, and (back) the root layer behind all other + // layers. - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + child1->SetBounds(gfx::Size(50, 50)); + child1->SetDrawsContent(true); + child1->SetHitTestable(true); + CopyProperties(root, child1); + child1->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + + // Remember that grand_child is positioned with respect to its parent (i.e. + // child1). In screen space, the intended position is (10, 50), with size + // 100 x 50. + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + grand_child1->SetBounds(gfx::Size(100, 50)); + grand_child1->SetDrawsContent(true); + grand_child1->SetHitTestable(true); + CopyProperties(child1, grand_child1); + grand_child1->SetOffsetToTransformParent( + gfx::Vector2dF(0.f, 40.f) + child1->offset_to_transform_parent()); + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(50, 50)); + child2->SetDrawsContent(true); + child2->SetHitTestable(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 10.f)); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -829,83 +804,72 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { gfx::PointF test_point = gfx::PointF(1.f, 1.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(1, result_layer->id()); + EXPECT_EQ(root, result_layer); // At (15, 15), child1 and root are the only layers. child1 is expected to be // on top. test_point = gfx::PointF(15.f, 15.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2, result_layer->id()); + EXPECT_EQ(child1, result_layer); // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. test_point = gfx::PointF(51.f, 20.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on // top. test_point = gfx::PointF(80.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (51, 51), all layers overlap each other. child2 is expected to be on top // of all other layers. test_point = gfx::PointF(51.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to // be on top. test_point = gfx::PointF(20.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(4, result_layer->id()); + EXPECT_EQ(grand_child1, result_layer); } TEST_F(LayerTreeImplTest, HitTestingSameSortingContextTied) { - int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3, - /* sorting_contexts */ 10, 10, 10, - /* depths */ 0, 0, 0); + LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10, + /* depths */ 0, 0, 0); // 3 is the last in tree order, and so should be on top. - EXPECT_EQ(3, hit_layer_id); + EXPECT_EQ(right_child_, hit_layer); } TEST_F(LayerTreeImplTest, HitTestingSameSortingContextChildWins) { - int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3, - /* sorting_contexts */ 10, 10, 10, - /* depths */ 0, 1, 0); - EXPECT_EQ(2, hit_layer_id); + LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10, + /* depths */ 0, 1, 0); + EXPECT_EQ(left_child_, hit_layer); } TEST_F(LayerTreeImplTest, HitTestingWithoutSortingContext) { - int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3, - /* sorting_contexts */ 0, 0, 0, - /* depths */ 0, 1, 0); - EXPECT_EQ(3, hit_layer_id); + LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 0, 0, 0, + /* depths */ 0, 1, 0); + EXPECT_EQ(right_child_, hit_layer); } TEST_F(LayerTreeImplTest, HitTestingDistinctSortingContext) { - int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3, - /* sorting_contexts */ 10, 11, 12, - /* depths */ 0, 1, 0); - EXPECT_EQ(3, hit_layer_id); + LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 11, 12, + /* depths */ 0, 1, 0); + EXPECT_EQ(right_child_, hit_layer); } TEST_F(LayerTreeImplTest, HitTestingSameSortingContextParentWins) { - int hit_layer_id = HitTestSimpleTree(/* ids */ 1, 2, 3, - /* sorting_contexts */ 10, 10, 10, - /* depths */ 0, -1, -1); - EXPECT_EQ(1, hit_layer_id); + LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10, + /* depths */ 0, -1, -1); + EXPECT_EQ(top_, hit_layer); } TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { @@ -913,59 +877,52 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - root->test_properties()->should_flatten_transform = false; - root->test_properties()->sorting_context_id = 1; - { - // child 1 and child2 are initialized to overlap between x=50 and x=60. - // grand_child is set to overlap both child1 and child2 between y=50 and - // y=60. The expected stacking order is: (front) child2, (second) - // grand_child, (third) child1, and (back) the root layer behind all other - // layers. - - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl().active_tree(), 3); - std::unique_ptr<LayerImpl> grand_child1 = - LayerImpl::Create(host_impl().active_tree(), 4); - - child1->test_properties()->position = gfx::PointF(10.f, 10.f); - child1->SetBounds(gfx::Size(50, 50)); - child1->SetDrawsContent(true); - child1->SetHitTestable(true); - child1->test_properties()->should_flatten_transform = false; - child1->test_properties()->sorting_context_id = 1; - - child2->test_properties()->position = gfx::PointF(50.f, 10.f); - child2->SetBounds(gfx::Size(50, 50)); - gfx::Transform translate_z; - translate_z.Translate3d(0, 0, 10.f); - child2->test_properties()->transform = translate_z; - child2->SetDrawsContent(true); - child2->SetHitTestable(true); - child2->test_properties()->should_flatten_transform = false; - child2->test_properties()->sorting_context_id = 1; - - // Remember that grand_child is positioned with respect to its parent (i.e. - // child1). In screen space, the intended position is (10, 50), with size - // 100 x 50. - grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f); - grand_child1->SetBounds(gfx::Size(100, 50)); - grand_child1->SetDrawsContent(true); - grand_child1->SetHitTestable(true); - grand_child1->test_properties()->should_flatten_transform = false; - - child1->test_properties()->AddChild(std::move(grand_child1)); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - } + GetTransformNode(root)->flattens_inherited_transform = false; + GetTransformNode(root)->sorting_context_id = 1; - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grand_child1 = child1->test_properties()->children[0]; + // child 1 and child2 are initialized to overlap between x=50 and x=60. + // grand_child is set to overlap both child1 and child2 between y=50 and + // y=60. The expected stacking order is: (front) child2, (second) + // grand_child, (third) child1, and (back) the root layer behind all other + // layers. - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + child1->SetBounds(gfx::Size(50, 50)); + child1->SetDrawsContent(true); + child1->SetHitTestable(true); + CopyProperties(root, child1); + auto& child1_transform_node = CreateTransformNode(child1); + child1_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f); + child1_transform_node.flattens_inherited_transform = false; + child1_transform_node.sorting_context_id = 1; + + // Remember that grand_child is positioned with respect to its parent (i.e. + // child1). In screen space, the intended position is (10, 50), with size + // 100 x 50. + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + grand_child1->SetBounds(gfx::Size(100, 50)); + grand_child1->SetDrawsContent(true); + grand_child1->SetHitTestable(true); + CopyProperties(child1, grand_child1); + auto& grand_child1_transform_node = CreateTransformNode(grand_child1); + grand_child1_transform_node.post_translation = gfx::Vector2dF(0.f, 40.f); + grand_child1_transform_node.flattens_inherited_transform = false; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(50, 50)); + gfx::Transform translate_z; + translate_z.Translate3d(0, 0, 10.f); + child2->SetDrawsContent(true); + child2->SetHitTestable(true); + CopyProperties(root, child2); + auto& child2_transform_node = CreateTransformNode(child2); + child2_transform_node.local = translate_z; + child2_transform_node.post_translation = gfx::Vector2dF(50.f, 10.f); + child2_transform_node.flattens_inherited_transform = false; + child2_transform_node.sorting_context_id = 1; + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -978,142 +935,84 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { gfx::PointF test_point = gfx::PointF(1.f, 1.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(1, result_layer->id()); + EXPECT_EQ(root, result_layer); // At (15, 15), child1 and root are the only layers. child1 is expected to be // on top. test_point = gfx::PointF(15.f, 15.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2, result_layer->id()); + EXPECT_EQ(child1, result_layer); // At (51, 20), child1 and child2 overlap. child2 is expected to be on top, // as it was transformed to the foreground. test_point = gfx::PointF(51.f, 20.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (80, 51), child2 and grand_child1 overlap. child2 is expected to // be on top, as it was transformed to the foreground. test_point = gfx::PointF(80.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (51, 51), child1, child2 and grand_child1 overlap. child2 is expected to // be on top, as it was transformed to the foreground. test_point = gfx::PointF(51.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to // be on top, as it descends from child1. test_point = gfx::PointF(20.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(4, result_layer->id()); + EXPECT_EQ(grand_child1, result_layer); } -TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { +TEST_F(LayerTreeImplTestWithLayerLists, HitTestingRespectsClipParents) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - { - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl().active_tree(), 4); - - child->test_properties()->position = gfx::PointF(10.f, 10.f); - child->SetBounds(gfx::Size(1, 1)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetMasksToBounds(true); - - grand_child->test_properties()->position = gfx::PointF(0.f, 40.f); - grand_child->SetBounds(gfx::Size(100, 50)); - grand_child->SetDrawsContent(true); - grand_child->SetHitTestable(true); - grand_child->test_properties()->force_render_surface = true; - - // This should let |grand_child| "escape" |child|'s clip. - grand_child->test_properties()->clip_parent = root; - std::unique_ptr<std::set<LayerImpl*>> clip_children( - new std::set<LayerImpl*>); - clip_children->insert(grand_child.get()); - root->test_properties()->clip_children = std::move(clip_children); - - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* child = AddChildToRoot<LayerImpl>(); + child->SetBounds(gfx::Size(1, 1)); + child->SetDrawsContent(true); + child->SetHitTestable(true); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + CreateClipNode(child); + + LayerImpl* scroll_child = AddChildToRoot<LayerImpl>(); + scroll_child->SetBounds(gfx::Size(200, 200)); + scroll_child->SetDrawsContent(true); + scroll_child->SetHitTestable(true); + CopyProperties(root, scroll_child); + scroll_child->SetClipTreeIndex(child->clip_tree_index()); + + LayerImpl* grand_child = AddChildToRoot<LayerImpl>(); + grand_child->SetBounds(gfx::Size(200, 200)); + grand_child->SetDrawsContent(true); + grand_child->SetHitTestable(true); + CopyProperties(scroll_child, grand_child); + CreateEffectNode(grand_child).render_surface_reason = + RenderSurfaceReason::kTest; + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); gfx::PointF test_point(12.f, 52.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(4, result_layer->id()); + // The |test_point| should have been clipped away by |child|, so the only + // thing that should be hit is |root|. + EXPECT_EQ(root, result_layer); } -TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) { - LayerImpl* root = root_layer(); - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); - { - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> scroll_child = - LayerImpl::Create(host_impl().active_tree(), 3); - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl().active_tree(), 4); - - child->test_properties()->position = gfx::PointF(10.f, 10.f); - child->SetBounds(gfx::Size(1, 1)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetMasksToBounds(true); - - scroll_child->SetBounds(gfx::Size(200, 200)); - scroll_child->SetDrawsContent(true); - scroll_child->SetHitTestable(true); - - // This should cause scroll child and its descendants to be affected by - // |child|'s clip. - scroll_child->test_properties()->scroll_parent = child.get(); - - grand_child->SetBounds(gfx::Size(200, 200)); - grand_child->SetDrawsContent(true); - grand_child->SetHitTestable(true); - grand_child->test_properties()->force_render_surface = true; - - scroll_child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(scroll_child)); - root->test_properties()->AddChild(std::move(child)); - } - - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - - gfx::PointF test_point(12.f, 52.f); - LayerImpl* result_layer = - host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - // The |test_point| should have been clipped away by |child|, the scroll - // parent, so the only thing that should be hit is |root|. - ASSERT_TRUE(result_layer); - ASSERT_EQ(1, result_layer->id()); -} TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { // // The geometry is set up similarly to the previous case, but @@ -1123,54 +1022,44 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - { - // child 1 and child2 are initialized to overlap between x=50 and x=60. - // grand_child is set to overlap both child1 and child2 between y=50 and - // y=60. The expected stacking order is: (front) child2, (second) - // grand_child, (third) child1, and (back) the root layer behind all other - // layers. - - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl().active_tree(), 3); - std::unique_ptr<LayerImpl> grand_child1 = - LayerImpl::Create(host_impl().active_tree(), 4); - - child1->test_properties()->position = gfx::PointF(10.f, 10.f); - child1->SetBounds(gfx::Size(50, 50)); - child1->SetDrawsContent(true); - child1->SetHitTestable(true); - child1->test_properties()->force_render_surface = true; - - child2->test_properties()->position = gfx::PointF(50.f, 10.f); - child2->SetBounds(gfx::Size(50, 50)); - child2->SetDrawsContent(true); - child2->SetHitTestable(true); - child2->test_properties()->force_render_surface = true; - - // Remember that grand_child is positioned with respect to its parent (i.e. - // child1). In screen space, the intended position is (10, 50), with size - // 100 x 50. - grand_child1->test_properties()->position = gfx::PointF(0.f, 40.f); - grand_child1->SetBounds(gfx::Size(100, 50)); - grand_child1->SetDrawsContent(true); - grand_child1->SetHitTestable(true); - grand_child1->test_properties()->force_render_surface = true; - - child1->test_properties()->AddChild(std::move(grand_child1)); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - - ExecuteCalculateDrawProperties(root); - } - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grand_child1 = child1->test_properties()->children[0]; + // child 1 and child2 are initialized to overlap between x=50 and x=60. + // grand_child is set to overlap both child1 and child2 between y=50 and + // y=60. The expected stacking order is: (front) child2, (second) + // grand_child, (third) child1, and (back) the root layer behind all other + // layers. - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* child1 = AddLayer<LayerImpl>(); + child1->SetBounds(gfx::Size(50, 50)); + child1->SetDrawsContent(true); + child1->SetHitTestable(true); + CopyProperties(root, child1); + CreateTransformNode(child1).post_translation = gfx::Vector2dF(10.f, 10.f); + CreateEffectNode(child1).render_surface_reason = RenderSurfaceReason::kTest; + + // Remember that grand_child is positioned with respect to its parent (i.e. + // child1). In screen space, the intended position is (10, 50), with size + // 100 x 50. + LayerImpl* grand_child1 = AddLayer<LayerImpl>(); + grand_child1->SetBounds(gfx::Size(100, 50)); + grand_child1->SetDrawsContent(true); + grand_child1->SetHitTestable(true); + CopyProperties(child1, grand_child1); + CreateTransformNode(grand_child1).post_translation = + gfx::Vector2dF(0.f, 40.f); + CreateEffectNode(grand_child1).render_surface_reason = + RenderSurfaceReason::kTest; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(50, 50)); + child2->SetDrawsContent(true); + child2->SetHitTestable(true); + CopyProperties(root, child2); + CreateTransformNode(child2).post_translation = gfx::Vector2dF(50.f, 10.f); + CreateEffectNode(child2).render_surface_reason = RenderSurfaceReason::kTest; + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -1197,47 +1086,41 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { gfx::PointF test_point(1.f, 1.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(1, result_layer->id()); + EXPECT_EQ(root, result_layer); // At (15, 15), child1 and root are the only layers. child1 is expected to be // on top. test_point = gfx::PointF(15.f, 15.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(2, result_layer->id()); + EXPECT_EQ(child1, result_layer); // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. test_point = gfx::PointF(51.f, 20.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on // top. test_point = gfx::PointF(80.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (51, 51), all layers overlap each other. child2 is expected to be on top // of all other layers. test_point = gfx::PointF(51.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(3, result_layer->id()); + EXPECT_EQ(child2, result_layer); // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to // be on top. test_point = gfx::PointF(20.f, 51.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(4, result_layer->id()); + EXPECT_EQ(grand_child1, result_layer); } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { @@ -1249,8 +1132,8 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { root->SetDrawsContent(true); root->SetHitTestable(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -1298,19 +1181,19 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); test_point = gfx::PointF(59.f, 59.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(root->id(), result_layer->id()); + EXPECT_EQ(root, result_layer); } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForUninvertibleTransform) { + LayerImpl* root = root_layer(); + gfx::Transform uninvertible_transform; uninvertible_transform.matrix().set(0, 0, 0.0); uninvertible_transform.matrix().set(1, 1, 0.0); @@ -1321,20 +1204,21 @@ TEST_F(LayerTreeImplTest, TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); - LayerImpl* root = root_layer(); - root->test_properties()->transform = uninvertible_transform; - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); - root->SetTouchActionRegion(touch_action_region); + LayerImpl* layer = AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->SetDrawsContent(true); + layer->SetHitTestable(true); + layer->SetTouchActionRegion(touch_action_region); + root->SetBounds(layer->bounds()); + CopyProperties(root, layer); + CreateTransformNode(layer).local = uninvertible_transform; - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); - ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); - ASSERT_FALSE(root->ScreenSpaceTransform().IsInvertible()); + ASSERT_FALSE(layer->ScreenSpaceTransform().IsInvertible()); // Hit checking any point should not hit the touch handler region on the // layer. If the invertible matrix is accidentally ignored and treated like an @@ -1390,20 +1274,17 @@ TEST_F(LayerTreeImplTest, // This layer is positioned, and hit testing should correctly know where the // layer is located. - { - std::unique_ptr<LayerImpl> test_layer = - LayerImpl::Create(host_impl().active_tree(), 12345); - test_layer->test_properties()->position = gfx::PointF(50.f, 50.f); - test_layer->SetBounds(gfx::Size(100, 100)); - test_layer->SetDrawsContent(true); - test_layer->SetHitTestable(true); - test_layer->SetTouchActionRegion(touch_action_region); - root_layer()->test_properties()->AddChild(std::move(test_layer)); - } - - LayerImpl* test_layer = root_layer()->test_properties()->children[0]; - host_impl().active_tree()->SetDeviceViewportSize(test_layer->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* test_layer = AddLayer<LayerImpl>(); + test_layer->SetBounds(gfx::Size(100, 100)); + test_layer->SetDrawsContent(true); + test_layer->SetHitTestable(true); + test_layer->SetTouchActionRegion(touch_action_region); + CopyProperties(root_layer(), test_layer); + test_layer->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 50.f)); + + host_impl().active_tree()->SetDeviceViewportRect( + gfx::Rect(test_layer->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -1438,15 +1319,13 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(test_layer->id(), result_layer->id()); + EXPECT_EQ(test_layer, result_layer); test_point = gfx::PointF(99.f, 99.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(test_layer->id(), result_layer->id()); + EXPECT_EQ(test_layer, result_layer); } TEST_F(LayerTreeImplTest, @@ -1458,41 +1337,41 @@ TEST_F(LayerTreeImplTest, // Set the bounds of the root layer big enough to fit the child when scaled. LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - { - TouchActionRegion touch_action_region; - touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); - std::unique_ptr<LayerImpl> test_layer = - LayerImpl::Create(host_impl().active_tree(), 12345); - test_layer->test_properties()->position = gfx::PointF(25.f, 25.f); - test_layer->SetBounds(gfx::Size(50, 50)); - test_layer->SetDrawsContent(true); - test_layer->SetHitTestable(true); - test_layer->SetTouchActionRegion(touch_action_region); - root->test_properties()->AddChild(std::move(test_layer)); - } + + LayerImpl* page_scale_layer = AddLayer<LayerImpl>(); + CopyProperties(root, page_scale_layer); + CreateTransformNode(page_scale_layer); + + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); + LayerImpl* test_layer = AddLayer<LayerImpl>(); + test_layer->SetBounds(gfx::Size(50, 50)); + test_layer->SetDrawsContent(true); + test_layer->SetHitTestable(true); + test_layer->SetTouchActionRegion(touch_action_region); + CopyProperties(page_scale_layer, test_layer); + test_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f)); float device_scale_factor = 3.f; float page_scale_factor = 5.f; float max_page_scale_factor = 10.f; gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( root->bounds(), device_scale_factor * page_scale_factor); - host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root); + host_impl().active_tree()->SetDeviceViewportRect( + gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = 1; - viewport_ids.inner_viewport_scroll = 1; + viewport_ids.page_scale = page_scale_layer->id(); host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. // The visible content rect for test_layer is actually 100x100, even though // its layout size is 50x50, positioned at 25x25. - LayerImpl* test_layer = root->test_properties()->children[0]; ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); @@ -1552,8 +1431,7 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(12345, result_layer->id()); + EXPECT_EQ(test_layer, result_layer); test_point = gfx::PointF(64.f, 64.f); test_point = @@ -1561,14 +1439,13 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(12345, result_layer->id()); + EXPECT_EQ(test_layer, result_layer); // Check update of page scale factor on the active tree when page scale layer // is also the root layer. page_scale_factor *= 1.5f; host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - EXPECT_EQ(root, host_impl().active_tree()->PageScaleLayer()); + EXPECT_EQ(page_scale_layer, host_impl().active_tree()->PageScaleLayer()); test_point = gfx::PointF(35.f, 35.f); test_point = @@ -1576,8 +1453,7 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(12345, result_layer->id()); + EXPECT_EQ(test_layer, result_layer); test_point = gfx::PointF(64.f, 64.f); test_point = @@ -1585,8 +1461,7 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(12345, result_layer->id()); + EXPECT_EQ(test_layer, result_layer); } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { @@ -1595,37 +1470,36 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { // case. LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - { - std::unique_ptr<LayerImpl> clipping_layer = - LayerImpl::Create(host_impl().active_tree(), 123); - // this layer is positioned, and hit testing should correctly know where the - // layer is located. - clipping_layer->test_properties()->position = gfx::PointF(25.f, 25.f); - clipping_layer->SetBounds(gfx::Size(50, 50)); - clipping_layer->SetMasksToBounds(true); - - TouchActionRegion touch_action_region; - touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); - - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 456); - child->test_properties()->position = gfx::PointF(-50.f, -50.f); - child->SetBounds(gfx::Size(300, 300)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetTouchActionRegion(touch_action_region); - clipping_layer->test_properties()->AddChild(std::move(child)); - root->test_properties()->AddChild(std::move(clipping_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* clipping_layer = AddLayer<LayerImpl>(); + // this layer is positioned, and hit testing should correctly know where + // the layer is located. + clipping_layer->SetBounds(gfx::Size(50, 50)); + clipping_layer->SetMasksToBounds(true); + clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f)); + CopyProperties(root, clipping_layer); + CreateClipNode(clipping_layer); + + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); + + LayerImpl* child = AddLayer<LayerImpl>(); + child->SetBounds(gfx::Size(300, 300)); + child->SetDrawsContent(true); + child->SetHitTestable(true); + child->SetTouchActionRegion(touch_action_region); + CopyProperties(clipping_layer, child); + child->SetOffsetToTransformParent( + gfx::Vector2dF(-50.f, -50.f) + + clipping_layer->offset_to_transform_parent()); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); - LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); - EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); // Hit checking for a point outside the layer should return a null pointer. // Despite the child layer being very large, it should be clipped to the root @@ -1656,15 +1530,13 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); test_point = gfx::PointF(34.f, 34.f); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); } TEST_F(LayerTreeImplTest, @@ -1676,51 +1548,47 @@ TEST_F(LayerTreeImplTest, // Set the bounds of the root layer big enough to fit the child when scaled. LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - std::unique_ptr<LayerImpl> surface = - LayerImpl::Create(host_impl().active_tree(), 2); + + LayerImpl* surface = AddLayer<LayerImpl>(); surface->SetBounds(gfx::Size(100, 100)); - surface->test_properties()->force_render_surface = true; - { - std::unique_ptr<LayerImpl> clipping_layer = - LayerImpl::Create(host_impl().active_tree(), 123); - // This layer is positioned, and hit testing should correctly know where the - // layer is located. - clipping_layer->test_properties()->position = gfx::PointF(25.f, 20.f); - clipping_layer->SetBounds(gfx::Size(50, 50)); - clipping_layer->SetMasksToBounds(true); - - TouchActionRegion touch_action_region; - touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 300, 300)); - - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), 456); - child->test_properties()->position = gfx::PointF(-50.f, -50.f); - child->SetBounds(gfx::Size(300, 300)); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetTouchActionRegion(touch_action_region); - clipping_layer->test_properties()->AddChild(std::move(child)); - surface->test_properties()->AddChild(std::move(clipping_layer)); - root->test_properties()->AddChild(std::move(surface)); - } + CopyProperties(root, surface); + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; + + LayerImpl* clipping_layer = AddLayer<LayerImpl>(); + // This layer is positioned, and hit testing should correctly know where + // the layer is located. + clipping_layer->SetBounds(gfx::Size(50, 50)); + clipping_layer->SetMasksToBounds(true); + CopyProperties(surface, clipping_layer); + clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 20.f)); + CreateClipNode(clipping_layer); + + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 300, 300)); + + LayerImpl* child = AddLayer<LayerImpl>(); + child->SetBounds(gfx::Size(300, 300)); + child->SetDrawsContent(true); + child->SetHitTestable(true); + child->SetTouchActionRegion(touch_action_region); + CopyProperties(clipping_layer, child); + child->SetOffsetToTransformParent( + gfx::Vector2dF(-50.f, -50.f) + + clipping_layer->offset_to_transform_parent()); float device_scale_factor = 3.f; float page_scale_factor = 1.f; float max_page_scale_factor = 1.f; gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( root->bounds(), device_scale_factor * page_scale_factor); - host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root); + host_impl().active_tree()->SetDeviceViewportRect( + gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = 1; - viewport_ids.inner_viewport_scroll = 1; - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(2u, GetRenderSurfaceList().size()); @@ -1744,47 +1612,39 @@ TEST_F(LayerTreeImplTest, result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(456, result_layer->id()); + EXPECT_EQ(child, result_layer); } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - { - std::unique_ptr<LayerImpl> touch_layer = - LayerImpl::Create(host_impl().active_tree(), 123); - // this layer is positioned, and hit testing should correctly know where the - // layer is located. - touch_layer->SetBounds(gfx::Size(50, 50)); - touch_layer->SetDrawsContent(true); - touch_layer->SetHitTestable(true); - TouchActionRegion touch_action_region; - touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50)); - touch_layer->SetTouchActionRegion(touch_action_region); - root->test_properties()->AddChild(std::move(touch_layer)); - } - - { - std::unique_ptr<LayerImpl> notouch_layer = - LayerImpl::Create(host_impl().active_tree(), 1234); - // this layer is positioned, and hit testing should correctly know where the - // layer is located. - notouch_layer->test_properties()->position = gfx::PointF(0, 25); - notouch_layer->SetBounds(gfx::Size(50, 50)); - notouch_layer->SetDrawsContent(true); - notouch_layer->SetHitTestable(true); - root->test_properties()->AddChild(std::move(notouch_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* touch_layer = AddLayer<LayerImpl>(); + // this layer is positioned, and hit testing should correctly know where + // the layer is located. + touch_layer->SetBounds(gfx::Size(50, 50)); + touch_layer->SetDrawsContent(true); + touch_layer->SetHitTestable(true); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50)); + touch_layer->SetTouchActionRegion(touch_action_region); + CopyProperties(root, touch_layer); + + LayerImpl* notouch_layer = AddLayer<LayerImpl>(); + // this layer is positioned, and hit testing should correctly know where + // the layer is located. + notouch_layer->SetBounds(gfx::Size(50, 50)); + notouch_layer->SetDrawsContent(true); + notouch_layer->SetHitTestable(true); + CopyProperties(root, notouch_layer); + notouch_layer->SetOffsetToTransformParent(gfx::Vector2dF(0, 25)); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); - LayerImpl* touch_layer = host_impl().active_tree()->LayerById(123); - LayerImpl* notouch_layer = host_impl().active_tree()->LayerById(1234); EXPECT_TRUE(touch_layer->contributes_to_drawn_render_surface()); EXPECT_TRUE(notouch_layer->contributes_to_drawn_render_surface()); @@ -1797,7 +1657,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { // behind it. EXPECT_TRUE(result_layer); - host_impl().active_tree()->LayerById(1234)->SetContentsOpaque(true); + notouch_layer->SetContentsOpaque(true); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); @@ -1812,8 +1672,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(123, result_layer->id()); + EXPECT_EQ(touch_layer, result_layer); test_point = gfx::PointF(35.f, 65.f); result_layer = @@ -1827,21 +1686,19 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - { - TouchActionRegion touch_action_region; - touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); - std::unique_ptr<LayerImpl> test_layer = - LayerImpl::Create(host_impl().active_tree(), 12345); - test_layer->SetBounds(gfx::Size(50, 50)); - test_layer->SetDrawsContent(false); - test_layer->SetHitTestable(false); - test_layer->SetTouchActionRegion(touch_action_region); - root->test_properties()->AddChild(std::move(test_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - LayerImpl* test_layer = root->test_properties()->children[0]; + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); + LayerImpl* test_layer = AddLayer<LayerImpl>(); + test_layer->SetBounds(gfx::Size(50, 50)); + test_layer->SetDrawsContent(false); + test_layer->SetHitTestable(false); + test_layer->SetTouchActionRegion(touch_action_region); + CopyProperties(root, test_layer); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); + // As test_layer doesn't draw content, it shouldn't contribute content to the // root surface. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -1853,12 +1710,11 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { // hit testing (becuase the point is inside test_layer with respect to the old // screen space transform). gfx::PointF test_point(24.f, 24.f); - test_layer->test_properties()->position = gfx::PointF(25.f, 25.f); + test_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f)); gfx::Transform expected_screen_space_transform; expected_screen_space_transform.Translate(25.f, 25.f); - host_impl().active_tree()->property_trees()->needs_rebuild = true; - host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); + UpdateDrawProperties(host_impl().active_tree()); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); @@ -1872,14 +1728,12 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { // We change the position of the test layer such that the test point is now // inside the test_layer. - test_layer = root->test_properties()->children[0]; - test_layer->test_properties()->position = gfx::PointF(10.f, 10.f); + test_layer->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); test_layer->NoteLayerPropertyChanged(); expected_screen_space_transform.MakeIdentity(); expected_screen_space_transform.Translate(10.f, 10.f); - host_impl().active_tree()->property_trees()->needs_rebuild = true; - host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); + UpdateDrawProperties(host_impl().active_tree()); result_layer = host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); @@ -1898,8 +1752,8 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -1959,29 +1813,25 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); - int clip_layer_id = 1234; - int clipped_layer_id = 123; - gfx::Vector2dF clipping_offset(10, 10); - { - std::unique_ptr<LayerImpl> clipping_layer = - LayerImpl::Create(host_impl().active_tree(), clip_layer_id); - // The clipping layer should occlude the right selection bound. - clipping_layer->test_properties()->position = - gfx::PointF() + clipping_offset; - clipping_layer->SetBounds(gfx::Size(50, 50)); - clipping_layer->SetMasksToBounds(true); - - std::unique_ptr<LayerImpl> clipped_layer = - LayerImpl::Create(host_impl().active_tree(), clipped_layer_id); - clipped_layer->SetBounds(gfx::Size(100, 100)); - clipped_layer->SetDrawsContent(true); - clipping_layer->test_properties()->AddChild(std::move(clipped_layer)); - root->test_properties()->AddChild(std::move(clipping_layer)); - } - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + LayerImpl* clipping_layer = AddLayer<LayerImpl>(); + // The clipping layer should occlude the right selection bound. + clipping_layer->SetBounds(gfx::Size(50, 50)); + clipping_layer->SetMasksToBounds(true); + CopyProperties(root, clipping_layer); + clipping_layer->SetOffsetToTransformParent(clipping_offset); + CreateClipNode(clipping_layer); + + LayerImpl* clipped_layer = AddLayer<LayerImpl>(); + clipped_layer->SetBounds(gfx::Size(100, 100)); + clipped_layer->SetDrawsContent(true); + CopyProperties(clipping_layer, clipped_layer); + clipped_layer->SetOffsetToTransformParent( + clipping_layer->offset_to_transform_parent()); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -1990,12 +1840,12 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { input.start.type = gfx::SelectionBound::LEFT; input.start.edge_top = gfx::Point(25, 10); input.start.edge_bottom = gfx::Point(25, 30); - input.start.layer_id = clipped_layer_id; + input.start.layer_id = clipped_layer->id(); input.end.type = gfx::SelectionBound::RIGHT; input.end.edge_top = gfx::Point(75, 10); input.end.edge_bottom = gfx::Point(75, 30); - input.end.layer_id = clipped_layer_id; + input.end.layer_id = clipped_layer->id(); host_impl().active_tree()->RegisterSelection(input); // The left bound should be occluded by the clip layer. @@ -2044,37 +1894,37 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); - int root_layer_id = root->id(); - int sub_layer_id = 2; + LayerImpl* page_scale_layer = AddLayer<LayerImpl>(); + page_scale_layer->SetBounds(gfx::Size(50, 50)); + CopyProperties(root, page_scale_layer); + CreateTransformNode(page_scale_layer); gfx::Vector2dF sub_layer_offset(10, 0); - { - std::unique_ptr<LayerImpl> sub_layer = - LayerImpl::Create(host_impl().active_tree(), sub_layer_id); - sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset; - sub_layer->SetBounds(gfx::Size(50, 50)); - sub_layer->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(sub_layer)); - } + LayerImpl* sub_layer = AddLayer<LayerImpl>(); + sub_layer->SetBounds(gfx::Size(50, 50)); + sub_layer->SetDrawsContent(true); + CopyProperties(page_scale_layer, sub_layer); + sub_layer->SetOffsetToTransformParent(sub_layer_offset); - host_impl().active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl().active_tree()); float device_scale_factor = 3.f; float page_scale_factor = 5.f; gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( root->bounds(), device_scale_factor * page_scale_factor); - host_impl().active_tree()->SetDeviceViewportSize(scaled_bounds_for_root); LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = root->id(); + viewport_ids.page_scale = page_scale_layer->id(); host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); + host_impl().active_tree()->SetDeviceViewportRect( + gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + UpdateDrawProperties(host_impl().active_tree()); // Sanity check the scenario we just created. ASSERT_EQ(1u, GetRenderSurfaceList().size()); @@ -2083,12 +1933,12 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { input.start.type = gfx::SelectionBound::LEFT; input.start.edge_top = gfx::Point(10, 10); input.start.edge_bottom = gfx::Point(10, 30); - input.start.layer_id = root_layer_id; + input.start.layer_id = page_scale_layer->id(); input.end.type = gfx::SelectionBound::RIGHT; input.end.edge_top = gfx::Point(0, 0); input.end.edge_bottom = gfx::Point(0, 20); - input.end.layer_id = sub_layer_id; + input.end.layer_id = sub_layer->id(); host_impl().active_tree()->RegisterSelection(input); // The viewport bounds should be properly scaled by the page scale, but should @@ -2097,11 +1947,11 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { host_impl().active_tree()->GetViewportSelection(&output); EXPECT_EQ(input.start.type, output.start.type()); auto expected_output_start_top = gfx::PointF(input.start.edge_top); - auto expected_output_edge_bottom = gfx::PointF(input.start.edge_bottom); + auto expected_output_start_bottom = gfx::PointF(input.start.edge_bottom); expected_output_start_top.Scale(page_scale_factor); - expected_output_edge_bottom.Scale(page_scale_factor); + expected_output_start_bottom.Scale(page_scale_factor); EXPECT_EQ(expected_output_start_top, output.start.edge_top()); - EXPECT_EQ(expected_output_edge_bottom, output.start.edge_bottom()); + EXPECT_EQ(expected_output_start_bottom, output.start.edge_bottom()); EXPECT_TRUE(output.start.visible()); EXPECT_EQ(input.end.type, output.end.type()); @@ -2120,29 +1970,19 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) { LayerImpl* root = root_layer(); root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - - int root_layer_id = root->id(); - int sub_layer_id = 2; + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); gfx::Vector2dF sub_layer_offset(10, 0); - { - std::unique_ptr<LayerImpl> sub_layer = - LayerImpl::Create(host_impl().active_tree(), sub_layer_id); - sub_layer->test_properties()->position = gfx::PointF() + sub_layer_offset; - sub_layer->SetBounds(gfx::Size(50, 50)); - sub_layer->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(sub_layer)); - } + LayerImpl* sub_layer = AddLayer<LayerImpl>(); + sub_layer->SetBounds(gfx::Size(50, 50)); + sub_layer->SetDrawsContent(true); + CopyProperties(root, sub_layer); + sub_layer->SetOffsetToTransformParent(sub_layer_offset); - host_impl().active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl().active_tree()); float device_scale_factor = 3.f; float painted_device_scale_factor = 5.f; - - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = root->id(); - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl().active_tree()->set_painted_device_scale_factor( painted_device_scale_factor); @@ -2151,12 +1991,12 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) { input.start.type = gfx::SelectionBound::LEFT; input.start.edge_top = gfx::Point(10, 10); input.start.edge_bottom = gfx::Point(10, 30); - input.start.layer_id = root_layer_id; + input.start.layer_id = root->id(); input.end.type = gfx::SelectionBound::RIGHT; input.end.edge_top = gfx::Point(0, 0); input.end.edge_bottom = gfx::Point(0, 20); - input.end.layer_id = sub_layer_id; + input.end.layer_id = sub_layer->id(); host_impl().active_tree()->RegisterSelection(input); // The viewport bounds should be properly scaled by the page scale, but should @@ -2192,43 +2032,35 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - int child_id = 2; - int grand_child_id = 3; - gfx::Transform large_transform; large_transform.Scale(SkDoubleToMScalar(1e37), SkDoubleToMScalar(1e37)); large_transform.RotateAboutYAxis(30); - { - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl().active_tree(), child_id); - child->test_properties()->transform = large_transform; - child->SetBounds(gfx::Size(100, 100)); - - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl().active_tree(), grand_child_id); - grand_child->test_properties()->transform = large_transform; - grand_child->SetBounds(gfx::Size(100, 100)); - grand_child->SetDrawsContent(true); - - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - } + LayerImpl* child = AddLayer<LayerImpl>(); + child->SetBounds(gfx::Size(100, 100)); + CopyProperties(root, child); + CreateTransformNode(child).local = large_transform; + + LayerImpl* grand_child = AddLayer<LayerImpl>(); + grand_child->SetBounds(gfx::Size(100, 100)); + grand_child->SetDrawsContent(true); + CopyProperties(child, grand_child); + CreateTransformNode(grand_child).local = large_transform; - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); LayerSelection input; input.start.type = gfx::SelectionBound::LEFT; input.start.edge_top = gfx::Point(10, 10); input.start.edge_bottom = gfx::Point(10, 20); - input.start.layer_id = grand_child_id; + input.start.layer_id = grand_child->id(); input.end.type = gfx::SelectionBound::RIGHT; input.end.edge_top = gfx::Point(50, 10); input.end.edge_bottom = gfx::Point(50, 30); - input.end.layer_id = grand_child_id; + input.end.layer_id = grand_child->id(); host_impl().active_tree()->RegisterSelection(input); @@ -2246,33 +2078,28 @@ TEST_F(LayerTreeImplTest, NumLayersTestOne) { EXPECT_EQ(1u, host_impl().active_tree()->NumLayers()); EXPECT_TRUE(root_layer()); // Create another layer, should increment. - auto layer = LayerImpl::Create(host_impl().active_tree(), 2); + AddLayer<LayerImpl>(); EXPECT_EQ(2u, host_impl().active_tree()->NumLayers()); } TEST_F(LayerTreeImplTest, NumLayersSmallTree) { EXPECT_EQ(1u, host_impl().active_tree()->NumLayers()); - LayerImpl* root = root_layer(); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl().active_tree(), 2)); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl().active_tree(), 3)); - root->test_properties()->children[1]->test_properties()->AddChild( - LayerImpl::Create(host_impl().active_tree(), 4)); + AddLayer<LayerImpl>(); + AddLayer<LayerImpl>(); + AddLayer<LayerImpl>(); EXPECT_EQ(4u, host_impl().active_tree()->NumLayers()); } TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) { - host_impl().active_tree()->BuildPropertyTreesForTesting(); - host_impl().active_tree()->SetDeviceScaleFactor(1.f); host_impl().active_tree()->UpdateDrawProperties(); EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties()); + host_impl().active_tree()->SetDeviceScaleFactor(1.f); + EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties()); host_impl().active_tree()->SetDeviceScaleFactor(2.f); EXPECT_TRUE(host_impl().active_tree()->needs_update_draw_properties()); } TEST_F(LayerTreeImplTest, RasterColorSpaceDoesNotNeedDrawPropertiesUpdate) { - host_impl().active_tree()->BuildPropertyTreesForTesting(); host_impl().active_tree()->SetRasterColorSpace( 1, gfx::ColorSpace::CreateXYZD50()); host_impl().active_tree()->UpdateDrawProperties(); @@ -2287,47 +2114,45 @@ TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) { EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking); LayerImpl* root = root_layer(); - std::unique_ptr<LayerImpl> left_child = - LayerImpl::Create(host_impl().active_tree(), 2); - std::unique_ptr<LayerImpl> right_child = - LayerImpl::Create(host_impl().active_tree(), 3); + LayerImpl* top = AddLayer<LayerImpl>(); + LayerImpl* left_child = AddLayer<LayerImpl>(); + LayerImpl* right_child = AddLayer<LayerImpl>(); { gfx::Transform translate_z; translate_z.Translate3d(0, 0, 10); - root->test_properties()->transform = translate_z; - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - root->SetHitTestable(true); + top->SetBounds(gfx::Size(100, 100)); + top->SetDrawsContent(true); + top->SetHitTestable(true); + CopyProperties(root, top); + CreateTransformNode(top).local = translate_z; } { gfx::Transform translate_z; translate_z.Translate3d(0, 0, 10); - left_child->test_properties()->transform = translate_z; left_child->SetBounds(gfx::Size(100, 100)); left_child->SetDrawsContent(true); left_child->SetHitTestable(true); + CopyProperties(top, left_child); + CreateTransformNode(left_child).local = translate_z; } { gfx::Transform translate_z; translate_z.Translate3d(0, 0, 10); - right_child->test_properties()->transform = translate_z; right_child->SetBounds(gfx::Size(100, 100)); + CopyProperties(top, right_child); + CreateTransformNode(right_child).local = translate_z; } - root->test_properties()->AddChild(std::move(left_child)); - root->test_properties()->AddChild(std::move(right_child)); - - host_impl().active_tree()->SetDeviceViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); CHECK_EQ(1u, GetRenderSurfaceList().size()); gfx::PointF test_point = gfx::PointF(1.f, 1.f); LayerImpl* result_layer = host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - CHECK(result_layer); - EXPECT_EQ(2, result_layer->id()); + EXPECT_EQ(left_child, result_layer); } // When using layer lists, we may not have layers for the outer viewport. This @@ -2338,9 +2163,8 @@ TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) { const gfx::Size scroll_layer_size(2000, 2000); auto* tree_impl = host_impl().active_tree(); - LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport( - &host_impl(), tree_impl, 50, inner_viewport_size, outer_viewport_size, - scroll_layer_size); + root_layer()->SetBounds(inner_viewport_size); + SetupViewport(root_layer(), outer_viewport_size, scroll_layer_size); // With viewport layers the scrollable size should be correct. EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize()); @@ -2468,23 +2292,24 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { // Initially there are no layers in the set. EXPECT_EQ(pending_tree->picture_layers_with_paint_worklets().size(), 0u); + auto* root = EnsureRootLayerInPendingTree(); + root->SetBounds(gfx::Size(100, 100)); + SetupRootProperties(root); + // Add three layers; two with PaintWorklets and one without. - std::unique_ptr<PictureLayerImpl> child1_owned = - PictureLayerImpl::Create(pending_tree, 2, Layer::LayerMaskType::NOT_MASK); - child1_owned->SetBounds(gfx::Size(100, 100)); - std::unique_ptr<PictureLayerImpl> child2_owned = - PictureLayerImpl::Create(pending_tree, 3, Layer::LayerMaskType::NOT_MASK); - child2_owned->SetBounds(gfx::Size(100, 100)); - std::unique_ptr<PictureLayerImpl> child3_owned = - PictureLayerImpl::Create(pending_tree, 4, Layer::LayerMaskType::NOT_MASK); - child3_owned->SetBounds(gfx::Size(100, 100)); - - PictureLayerImpl* child1 = child1_owned.get(); - PictureLayerImpl* child3 = child3_owned.get(); - - root_layer()->test_properties()->AddChild(std::move(child1_owned)); - root_layer()->test_properties()->AddChild(std::move(child2_owned)); - root_layer()->test_properties()->AddChild(std::move(child3_owned)); + auto* child1 = + AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + child1->SetBounds(gfx::Size(100, 100)); + auto* child2 = + AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + child2->SetBounds(gfx::Size(100, 100)); + auto* child3 = + AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + child3->SetBounds(gfx::Size(100, 100)); + + CopyProperties(root, child1); + CopyProperties(root, child2); + CopyProperties(root, child3); Region empty_invalidation; scoped_refptr<RasterSource> raster_source1( @@ -2512,12 +2337,12 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { EXPECT_FALSE(layers.contains(child1)); // Deleting a layer should also cause it to be removed from the set. - root_layer()->test_properties()->RemoveChild(child3); + root->test_properties()->RemoveChild(child3); EXPECT_EQ(layers.size(), 0u); } namespace { -class CommitToPendingTreeLayerTreeImplTestSettings : public LayerTreeSettings { +class CommitToPendingTreeLayerTreeImplTestSettings : public LayerListSettings { public: CommitToPendingTreeLayerTreeImplTestSettings() { commit_to_active_tree = false; @@ -2539,7 +2364,7 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, // various ElementId to animation maps should not track anything for the // active tree (as they are only used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); - active_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(active_tree); LayerImpl* active_root = active_tree->root_layer_for_testing(); auto& active_opacity_map = @@ -2565,20 +2390,21 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, // and recycle tree cases. host_impl().CreatePendingTree(); LayerTreeImpl* pending_tree = host_impl().pending_tree(); - std::unique_ptr<LayerImpl> pending_root_ptr = - LayerImpl::Create(pending_tree, 2); - LayerImpl* pending_root = pending_root_ptr.get(); - pending_tree->SetRootLayerForTesting(std::move(pending_root_ptr)); - - std::unique_ptr<LayerImpl> child_ptr = - LayerImpl::Create(host_impl().pending_tree(), 3); - // The easiest way to force the child to have a TransformNode is to make it - // fixed position. Similarly a non-one opacity forces an EffectNode. - child_ptr->test_properties()->position_constraint.set_is_fixed_position(true); - child_ptr->test_properties()->opacity = 0.9f; - LayerImpl* child = child_ptr.get(); - pending_root->test_properties()->AddChild(std::move(child_ptr)); - pending_tree->BuildPropertyTreesForTesting(); + LayerImpl* pending_root = EnsureRootLayerInPendingTree(); + pending_root->SetBounds(gfx::Size(1, 1)); + LayerImpl* child = AddLayerInPendingTree<LayerImpl>(); + pending_tree->SetElementIdsForTesting(); + + SetupRootProperties(pending_root); + // A scale transform forces a TransformNode. + gfx::Transform scale3d; + scale3d.Scale3d(1, 1, 0.5); + CopyProperties(pending_root, child); + CreateTransformNode(child).local = scale3d; + // A non-one opacity forces an EffectNode. + CreateEffectNode(child).opacity = 0.9f; + + UpdateDrawProperties(pending_tree); auto& pending_opacity_map = pending_tree->element_id_to_opacity_animations_for_testing(); @@ -2631,7 +2457,7 @@ TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) { // animation maps should track on the active tree (as it is the sync tree, and // they are used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); - active_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(active_tree); LayerImpl* root = active_tree->root_layer_for_testing(); auto& opacity_map = @@ -2652,5 +2478,79 @@ TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) { EXPECT_EQ(filter_map.size(), 1u); } +class LayerTreeImplOcclusionSettings : public LayerListSettings { + public: + explicit LayerTreeImplOcclusionSettings(bool enabled) { + enable_occlusion = enabled; + minimum_occlusion_tracking_size = gfx::Size(1, 1); + } +}; + +class LayerTreeImplOcclusionTest : public LayerTreeImplTest { + public: + explicit LayerTreeImplOcclusionTest(bool enable_occlusion) + : LayerTreeImplTest(LayerTreeImplOcclusionSettings(enable_occlusion)), + enable_occlusion_(enable_occlusion) {} + + void TestOcclusion() { + LayerImpl* root = root_layer(); + root->SetBounds(gfx::Size(100, 100)); + + // Create a 50x50 layer in the center of our root bounds. + LayerImpl* bottom_layer = AddLayer<LayerImpl>(); + bottom_layer->SetBounds(gfx::Size(50, 50)); + bottom_layer->SetDrawsContent(true); + bottom_layer->SetContentsOpaque(true); + CopyProperties(root, bottom_layer); + bottom_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); + + // Create a full-bounds 100x100 layer which occludes the 50x50 layer. + LayerImpl* occluding_layer = AddLayer<LayerImpl>(); + occluding_layer->SetBounds(gfx::Size(100, 100)); + occluding_layer->SetDrawsContent(true); + occluding_layer->SetContentsOpaque(true); + CopyProperties(root, occluding_layer); + + host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds())); + UpdateDrawProperties(host_impl().active_tree()); + + LayerTreeImpl* active_tree = host_impl().active_tree(); + if (enable_occlusion_) { + // With occlusion on, the root is fully occluded, as is the bottom layer. + EXPECT_TRUE(active_tree->UnoccludedScreenSpaceRegion().IsEmpty()); + EXPECT_TRUE(bottom_layer->draw_properties() + .occlusion_in_content_space.HasOcclusion()); + } else { + // With occlusion off, the full root should be unoccluded and the bottom + // layer should have no occlusion. + EXPECT_TRUE(active_tree->UnoccludedScreenSpaceRegion().Contains( + gfx::Rect(root->bounds()))); + EXPECT_FALSE(bottom_layer->draw_properties() + .occlusion_in_content_space.HasOcclusion()); + } + } + + private: + bool enable_occlusion_; +}; + +class LayerTreeImplOcclusionDisabledTest : public LayerTreeImplOcclusionTest { + public: + LayerTreeImplOcclusionDisabledTest() : LayerTreeImplOcclusionTest(false) {} +}; + +class LayerTreeImplOcclusionEnabledTest : public LayerTreeImplOcclusionTest { + public: + LayerTreeImplOcclusionEnabledTest() : LayerTreeImplOcclusionTest(true) {} +}; + +TEST_F(LayerTreeImplOcclusionDisabledTest, OcclusionDisabled) { + TestOcclusion(); +} + +TEST_F(LayerTreeImplOcclusionEnabledTest, OcclusionEnabled) { + TestOcclusion(); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index d62c52b5326..ce1e19e2915 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -111,7 +111,7 @@ class CC_EXPORT LayerTreeSettings { // Indicates that the LayerTreeHost should defer commits unless it has a valid // viz::LocalSurfaceId set. - bool enable_surface_synchronization = false; + bool enable_surface_synchronization = true; // Indicates the case when a sub-frame gets its own LayerTree because it's // rendered in a different process from its ancestor frames. @@ -146,7 +146,7 @@ class CC_EXPORT LayerTreeSettings { // Whether to use edge anti-aliasing for all layer types that supports it. bool enable_edge_anti_aliasing = true; - // Whether SetViewportSizeAndScale should update the painted scale factor or + // Whether SetViewportRectAndScale should update the painted scale factor or // the device scale factor. bool use_painted_device_scale_factor = false; @@ -168,6 +168,13 @@ class CC_EXPORT LayerTreeSettings { // go away and CC should send Blink fractional values: // https://crbug.com/414283. bool commit_fractional_scroll_deltas = false; + + // When false, we do not check for occlusion and all quads are drawn. + // Defaults to true. + bool enable_occlusion = true; + + // Whether experimental de-jelly effect is allowed. + bool allow_de_jelly_effect = false; }; } // namespace cc diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h index 406b10abfc5..dd08f0afc1f 100644 --- a/chromium/cc/trees/mutator_host_client.h +++ b/chromium/cc/trees/mutator_host_client.h @@ -6,6 +6,7 @@ #define CC_TREES_MUTATOR_HOST_CLIENT_H_ #include "cc/paint/element_id.h" +#include "cc/paint/paint_worklet_input.h" #include "cc/trees/property_animation_state.h" #include "cc/trees/target_property.h" @@ -72,6 +73,11 @@ class MutatorHostClient { virtual void NotifyAnimationWorkletStateChange( AnimationWorkletMutationState state, ElementListType tree_type) = 0; + + virtual void OnCustomPropertyMutated( + ElementId element_id, + const std::string& custom_property_name, + PaintWorkletInput::PropertyValue custom_property_value) = 0; }; } // namespace cc diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 638a253ceb6..41c812e1585 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -202,7 +202,7 @@ class OcclusionTrackerTest : public testing::Test { root->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_list_impl_); + root, gfx::Rect(root->bounds()), &render_surface_list_impl_); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>( diff --git a/chromium/cc/trees/paint_holding_commit_trigger.h b/chromium/cc/trees/paint_holding_commit_trigger.h index fcf4832a5b8..b8828028019 100644 --- a/chromium/cc/trees/paint_holding_commit_trigger.h +++ b/chromium/cc/trees/paint_holding_commit_trigger.h @@ -19,8 +19,10 @@ enum class PaintHoldingCommitTrigger { kFirstContentfulPaint = 2, // The commit was triggered by a timeout waiting for FCP kTimeout = 3, + // The timeout was never set, probably due to non-main frame + kNotDeferred = 4, // Required for UMA enum - kMaxValue = kTimeout + kMaxValue = kNotDeferred }; } // namespace cc diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index f91deac77f3..f826436980d 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -50,8 +50,7 @@ PropertyTree<T>& PropertyTree<T>::operator=(const PropertyTree<T>&) = default; needs_rebuild)) TransformTree::TransformTree() - : source_to_parent_updates_allowed_(true), - page_scale_factor_(1.f), + : page_scale_factor_(1.f), device_scale_factor_(1.f), device_transform_scale_factor_(1.f) { cached_data_.push_back(TransformCachedNodeData()); @@ -124,13 +123,7 @@ void TransformTree::clear() { cached_data_.push_back(TransformCachedNodeData()); sticky_position_data_.clear(); -#if DCHECK_IS_ON() - TransformTree tree; - // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed - // to be true on impl thread to main thread and set it to is_main_thread here. - tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_; - DCHECK(tree == *this); -#endif + DCHECK(TransformTree() == *this); } void TransformTree::set_needs_update(bool needs_update) { @@ -202,11 +195,6 @@ bool TransformTree::OnTransformAnimated(ElementId element_id, return true; } -bool TransformTree::NeedsSourceToParentUpdate(TransformNode* node) { - return (source_to_parent_updates_allowed() && - node->parent_id != node->source_node_id); -} - void TransformTree::ResetChangeTracking() { for (int id = TransformTree::kContentsRootNodeId; id < static_cast<int>(size()); ++id) { @@ -219,10 +207,9 @@ void TransformTree::UpdateTransforms(int id) { TransformNode* node = Node(id); TransformNode* parent_node = parent(node); DCHECK(parent_node); - TransformNode* source_node = Node(node->source_node_id); // TODO(flackr): Only dirty when scroll offset changes. if (node->sticky_position_constraint_id >= 0 || - node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) { + node->needs_local_transform_update) { UpdateLocalTransform(node); } else { UndoSnapping(node); @@ -231,7 +218,7 @@ void TransformTree::UpdateTransforms(int id) { UpdateAnimationProperties(node, parent_node); UpdateSnapping(node); UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); - UpdateTransformChanged(node, parent_node, source_node); + UpdateTransformChanged(node, parent_node); UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); DCHECK(!node->needs_local_transform_update); @@ -355,18 +342,16 @@ bool TransformTree::CombineInversesBetween(int source_id, // This function should match the offset we set for sticky position layer in // CompositedLayerMapping::UpdateMainGraphicsLayerGeometry. -gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { - if (node->sticky_position_constraint_id == -1) +gfx::Vector2dF TransformTree::StickyPositionOffset(TransformNode* node) { + StickyPositionNodeData* sticky_data = MutableStickyPositionData(node->id); + if (!sticky_data) return gfx::Vector2dF(); - StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id); - const LayerStickyPositionConstraint& constraint = sticky_data->constraints; - auto& property_trees = *tree->property_trees(); + const StickyPositionConstraint& constraint = sticky_data->constraints; ScrollNode* scroll_node = - property_trees.scroll_tree.Node(sticky_data->scroll_ancestor); - TransformNode* transform_node = - property_trees.transform_tree.Node(scroll_node->transform_id); + property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); + TransformNode* transform_node = Node(scroll_node->transform_id); const auto& scroll_offset = transform_node->scroll_offset; - DCHECK(property_trees.scroll_tree.current_scroll_offset( + DCHECK(property_trees()->scroll_tree.current_scroll_offset( scroll_node->element_id) == scroll_offset); gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); if (transform_node->scrolls) { @@ -384,27 +369,32 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { // viewport since it shouldn't be affected by pinch-zoom. DCHECK(!scroll_node->scrolls_inner_viewport); if (scroll_node->scrolls_outer_viewport) { - clip.set_width(clip.width() + - property_trees.outer_viewport_container_bounds_delta().x()); - clip.set_height(clip.height() + - property_trees.outer_viewport_container_bounds_delta().y()); + clip.set_width( + clip.width() + + property_trees()->outer_viewport_container_bounds_delta().x()); + clip.set_height( + clip.height() + + property_trees()->outer_viewport_container_bounds_delta().y()); } gfx::Vector2dF ancestor_sticky_box_offset; if (sticky_data->nearest_node_shifting_sticky_box != TransformTree::kInvalidNodeId) { + const StickyPositionNodeData* ancestor_sticky_data = + GetStickyPositionData(sticky_data->nearest_node_shifting_sticky_box); + DCHECK(ancestor_sticky_data); ancestor_sticky_box_offset = - tree->StickyPositionData(sticky_data->nearest_node_shifting_sticky_box) - ->total_sticky_box_sticky_offset; + ancestor_sticky_data->total_sticky_box_sticky_offset; } gfx::Vector2dF ancestor_containing_block_offset; if (sticky_data->nearest_node_shifting_containing_block != TransformTree::kInvalidNodeId) { + const StickyPositionNodeData* ancestor_sticky_data = GetStickyPositionData( + sticky_data->nearest_node_shifting_containing_block); + DCHECK(ancestor_sticky_data); ancestor_containing_block_offset = - tree->StickyPositionData( - sticky_data->nearest_node_shifting_containing_block) - ->total_containing_block_sticky_offset; + ancestor_sticky_data->total_containing_block_sticky_offset; } // Compute the current position of the constraint rects based on the original @@ -476,57 +466,22 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { } void TransformTree::UpdateLocalTransform(TransformNode* node) { - gfx::Transform transform = node->post_local; - if (NeedsSourceToParentUpdate(node)) { - gfx::Transform to_parent; - ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); - gfx::Vector2dF unsnapping; - TransformNode* current; - TransformNode* parent_node; - // Since we are calculating the adjustment for fixed position node or a - // scroll child, we need to unsnap only if the snap was caused by a scroll. - for (current = Node(node->source_node_id); current->id > node->parent_id; - current = parent(current)) { - DCHECK(current->scrolls || current->snap_amount.IsZero()); - if (current->scrolls) - unsnapping.Subtract(current->snap_amount); - } - for (parent_node = Node(node->parent_id); - parent_node->id > node->source_node_id; - parent_node = parent(parent_node)) { - DCHECK(parent_node->scrolls || parent_node->snap_amount.IsZero()); - if (parent_node->scrolls) - unsnapping.Add(parent_node->snap_amount); - } - // If a node NeedsSourceToParentUpdate, the node is either a fixed position - // node or a scroll child. - // If the node has a fixed position, the parent of the node is an ancestor - // of source node, current->id should be equal to node->parent_id. - // Otherwise, the node's source node is always an ancestor of the node owned - // by the scroll parent, so parent_node->id should be equal to - // node->source_node_id. - DCHECK(current->id == node->parent_id || - parent_node->id == node->source_node_id); - to_parent.Translate(unsnapping.x(), unsnapping.y()); - node->source_to_parent = to_parent.To2dTranslation(); - } - - gfx::Vector2dF fixed_position_adjustment; - gfx::Vector2dF outer_viewport_bounds_delta = - property_trees()->outer_viewport_container_bounds_delta(); - if (node->moved_by_outer_viewport_bounds_delta_x) - fixed_position_adjustment.set_x(outer_viewport_bounds_delta.x()); - - if (node->moved_by_outer_viewport_bounds_delta_y) - fixed_position_adjustment.set_y(outer_viewport_bounds_delta.y()); - - transform.Translate(node->source_to_parent.x() - node->scroll_offset.x() + - fixed_position_adjustment.x(), - node->source_to_parent.y() - node->scroll_offset.y() + - fixed_position_adjustment.y()); - transform.Translate(StickyPositionOffset(this, node)); + gfx::Transform transform; + transform.Translate3d(node->post_translation.x() + node->origin.x(), + node->post_translation.y() + node->origin.y(), + node->origin.z()); + + float fixed_position_adjustment = 0; + if (node->moved_by_outer_viewport_bounds_delta_y) { + fixed_position_adjustment = + property_trees()->outer_viewport_container_bounds_delta().y(); + } + + transform.Translate(-node->scroll_offset.x(), + -node->scroll_offset.y() + fixed_position_adjustment); + transform.Translate(StickyPositionOffset(node)); transform.PreconcatTransform(node->local); - transform.PreconcatTransform(node->pre_local); + transform.Translate3d(gfx::Point3F() - node->origin); node->set_to_parent(transform); node->needs_local_transform_update = false; @@ -602,16 +557,9 @@ void TransformTree::UpdateSnapping(TransformNode* node) { } void TransformTree::UpdateTransformChanged(TransformNode* node, - TransformNode* parent_node, - TransformNode* source_node) { + TransformNode* parent_node) { DCHECK(parent_node); - if (parent_node->transform_changed) { - node->transform_changed = true; - return; - } - - if (source_node && source_node->id != parent_node->id && - source_to_parent_updates_allowed_ && source_node->transform_changed) + if (parent_node->transform_changed) node->transform_changed = true; } @@ -633,10 +581,10 @@ void TransformTree::UpdateNodeAndAncestorsAreAnimatedOrInvertible( node->has_potential_animation || is_invertible; } -void TransformTree::SetRootTransformsAndScales( +void TransformTree::SetRootScaleAndTransform( float device_scale_factor, - float page_scale_factor_for_root, const gfx::Transform& device_transform) { + device_scale_factor_ = device_scale_factor; gfx::Vector2dF device_transform_scale_components = MathUtil::ComputeTransform2dScaleComponents(device_transform, 1.f); @@ -651,11 +599,10 @@ void TransformTree::SetRootTransformsAndScales( // transform node is set to SSS and the post local transform of the contents // root node is set to SSS^-1*DT*DSF. gfx::Transform transform = device_transform; - transform.Scale(device_scale_factor * page_scale_factor_for_root, - device_scale_factor * page_scale_factor_for_root); - float fallback_value = device_scale_factor * page_scale_factor_for_root; + transform.Scale(device_scale_factor, device_scale_factor); gfx::Vector2dF screen_space_scale = - MathUtil::ComputeTransform2dScaleComponents(transform, fallback_value); + MathUtil::ComputeTransform2dScaleComponents(transform, + device_scale_factor); DCHECK_NE(screen_space_scale.x(), 0.f); DCHECK_NE(screen_space_scale.y(), 0.f); @@ -672,8 +619,8 @@ void TransformTree::SetRootTransformsAndScales( transform.ConcatTransform(root_from_screen); TransformNode* contents_root_node = Node(kContentsRootNodeId); - if (contents_root_node->post_local != transform) { - contents_root_node->post_local = transform; + if (contents_root_node->local != transform) { + contents_root_node->local = transform; contents_root_node->needs_local_transform_update = true; set_needs_update(true); } @@ -720,8 +667,6 @@ void TransformTree::SetToScreen(int node_id, const gfx::Transform& transform) { bool TransformTree::operator==(const TransformTree& other) const { return PropertyTree::operator==(other) && - source_to_parent_updates_allowed_ == - other.source_to_parent_updates_allowed() && page_scale_factor_ == other.page_scale_factor() && device_scale_factor_ == other.device_scale_factor() && device_transform_scale_factor_ == @@ -731,13 +676,20 @@ bool TransformTree::operator==(const TransformTree& other) const { cached_data_ == other.cached_data(); } -StickyPositionNodeData* TransformTree::StickyPositionData(int node_id) { +StickyPositionNodeData* TransformTree::MutableStickyPositionData(int node_id) { + const TransformNode* node = Node(node_id); + if (node->sticky_position_constraint_id == -1) + return nullptr; + return &sticky_position_data_[node->sticky_position_constraint_id]; +} + +StickyPositionNodeData& TransformTree::EnsureStickyPositionData(int node_id) { TransformNode* node = Node(node_id); if (node->sticky_position_constraint_id == -1) { node->sticky_position_constraint_id = sticky_position_data_.size(); sticky_position_data_.push_back(StickyPositionNodeData()); } - return &sticky_position_data_[node->sticky_position_constraint_id]; + return sticky_position_data_[node->sticky_position_constraint_id]; } EffectTree::EffectTree() { @@ -1076,24 +1028,6 @@ void EffectTree::AddMaskLayerId(int id) { mask_layer_ids_.push_back(id); } -void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl) { - for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) { - EffectNode* effect_node = Node(id); - bool needs_render_surface = - id == kContentsRootNodeId || effect_node->HasRenderSurface(); - if (needs_render_surface == !!render_surfaces_[id]) - continue; - - if (needs_render_surface) { - render_surfaces_[id] = std::make_unique<RenderSurfaceImpl>( - layer_tree_impl, effect_node->stable_id); - render_surfaces_[id]->set_effect_tree_index(id); - } else { - render_surfaces_[id].reset(); - } - } -} - bool EffectTree::ContributesToDrawnSurface(int id) { // All drawn nodes contribute to drawn surface. // Exception : Nodes that are hidden and are drawn only for the sake of @@ -1202,8 +1136,9 @@ bool EffectTree::ClippedHitTestRegionIsRectangle(int effect_id) const { bool EffectTree::HitTestMayBeAffectedByMask(int effect_id) const { const EffectNode* effect_node = Node(effect_id); for (; effect_node->id != kContentsRootNodeId; - effect_node = Node(effect_node->target_id)) { - if (effect_node->has_masking_child || effect_node->is_masked) + effect_node = Node(effect_node->parent_id)) { + if (!effect_node->rounded_corner_bounds.IsEmpty() || + effect_node->has_masking_child || effect_node->is_masked) return true; } return false; @@ -1991,8 +1926,7 @@ void PropertyTrees::UpdateChangeTracking() { i < static_cast<int>(transform_tree.size()); ++i) { TransformNode* node = transform_tree.Node(i); TransformNode* parent_node = transform_tree.parent(node); - TransformNode* source_node = transform_tree.Node(node->source_node_id); - transform_tree.UpdateTransformChanged(node, parent_node, source_node); + transform_tree.UpdateTransformChanged(node, parent_node); } } diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 75b972dd86c..214b9fca971 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -14,10 +14,10 @@ #include "base/containers/flat_map.h" #include "cc/base/synced_property.h" #include "cc/cc_export.h" -#include "cc/layers/layer_sticky_position_constraint.h" #include "cc/paint/element_id.h" #include "cc/paint/filter_operations.h" #include "cc/trees/mutator_host_client.h" +#include "cc/trees/sticky_position_constraint.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" @@ -150,30 +150,13 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { void ResetChangeTracking(); // Updates the parent, target, and screen space transforms and snapping. void UpdateTransforms(int id); - void UpdateTransformChanged(TransformNode* node, - TransformNode* parent_node, - TransformNode* source_node); + void UpdateTransformChanged(TransformNode* node, TransformNode* parent_node); void UpdateNodeAndAncestorsAreAnimatedOrInvertible( TransformNode* node, TransformNode* parent_node); 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 - // parent (their "source"), but are parented in the transform tree by their - // fixed-position container. This value needs to be updated on main-thread - // property trees (for position changes initiated by Blink), but not on the - // compositor thread (since the offset from a node corresponding to a - // fixed-position layer to its fixed-position container is unaffected by - // compositor-driven effects). - void set_source_to_parent_updates_allowed(bool allowed) { - source_to_parent_updates_allowed_ = allowed; - } - bool source_to_parent_updates_allowed() const { - return source_to_parent_updates_allowed_; - } - // We store the page scale factor on the transform tree so that it can be // easily be retrieved and updated in UpdatePageScale. void set_page_scale_factor(float page_scale_factor) { @@ -186,9 +169,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { } float device_scale_factor() const { return device_scale_factor_; } - void SetRootTransformsAndScales(float device_scale_factor, - float page_scale_factor_for_root, - const gfx::Transform& device_transform); + void SetRootScaleAndTransform(float device_scale_factor, + const gfx::Transform& device_transform); float device_transform_scale_factor() const { return device_transform_scale_factor_; } @@ -220,7 +202,10 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { return cached_data_; } - StickyPositionNodeData* StickyPositionData(int node_id); + const StickyPositionNodeData* GetStickyPositionData(int node_id) const { + return const_cast<TransformTree*>(this)->MutableStickyPositionData(node_id); + } + StickyPositionNodeData& EnsureStickyPositionData(int node_id); // Computes the combined transform between |source_id| and |dest_id|. These // two nodes must be on the same ancestor chain. @@ -240,6 +225,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { // |anc_id|. bool IsDescendant(int desc_id, int anc_id) const; + StickyPositionNodeData* MutableStickyPositionData(int node_id); + gfx::Vector2dF StickyPositionOffset(TransformNode* node); void UpdateLocalTransform(TransformNode* node); void UpdateScreenSpaceTransform(TransformNode* node, TransformNode* parent_node); @@ -250,9 +237,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { void UpdateNodeAndAncestorsHaveIntegerTranslations( TransformNode* node, TransformNode* parent_node); - bool NeedsSourceToParentUpdate(TransformNode* node); - bool source_to_parent_updates_allowed_; // When to_screen transform has perspective, the transform node's sublayer // scale is calculated using page scale factor, device scale factor and the // scale factor of device transform. So we need to store them explicitly. @@ -266,7 +251,7 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { struct StickyPositionNodeData { int scroll_ancestor; - LayerStickyPositionConstraint constraints; + StickyPositionConstraint constraints; // 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 @@ -351,8 +336,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { return render_surfaces_[id].get(); } - void UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl); - bool ContributesToDrawnSurface(int id); void ResetChangeTracking(); @@ -418,6 +401,7 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { int CurrentlyScrollingNodeId() const; #endif void set_currently_scrolling_node(int scroll_node_id); + int currently_scrolling_node() const { return currently_scrolling_node_id_; } gfx::Transform ScreenSpaceTransform(int scroll_node_id) const; gfx::Vector2dF ClampScrollToMaxScrollOffset(ScrollNode* node, LayerTreeImpl*); diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index 44a2033de9a..e962ff9a63c 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -32,7 +32,6 @@ namespace { struct DataForRecursion { int transform_tree_parent; - int transform_tree_parent_fixed; int clip_tree_parent; int effect_tree_parent; int scroll_tree_parent; @@ -76,11 +75,7 @@ class PropertyTreeBuilderContext { transform_tree_(property_trees->transform_tree), clip_tree_(property_trees->clip_tree), effect_tree_(property_trees->effect_tree), - scroll_tree_(property_trees->scroll_tree) { - InitializeScrollChildrenMap(); - } - - void InitializeScrollChildrenMap(); + scroll_tree_(property_trees->scroll_tree) {} void BuildPropertyTrees(float device_scale_factor, const gfx::Rect& viewport, @@ -128,26 +123,8 @@ class PropertyTreeBuilderContext { ClipTree& clip_tree_; EffectTree& effect_tree_; ScrollTree& scroll_tree_; - std::multimap<const LayerType*, LayerType*> scroll_children_map_; }; -static LayerPositionConstraint PositionConstraint(Layer* layer) { - return layer->position_constraint(); -} - -static LayerPositionConstraint PositionConstraint(LayerImpl* layer) { - return layer->test_properties()->position_constraint; -} - -static LayerStickyPositionConstraint StickyPositionConstraint(Layer* layer) { - return layer->sticky_position_constraint(); -} - -static LayerStickyPositionConstraint StickyPositionConstraint( - LayerImpl* layer) { - return layer->test_properties()->sticky_position_constraint; -} - static LayerImplList& LayerChildren(LayerImpl* layer) { return layer->test_properties()->children; } @@ -164,22 +141,6 @@ static Layer* LayerChildAt(Layer* layer, int index) { return layer->children()[index].get(); } -static Layer* ScrollParent(Layer* layer) { - return layer->scroll_parent(); -} - -static LayerImpl* ScrollParent(LayerImpl* layer) { - return layer->test_properties()->scroll_parent; -} - -static Layer* ClipParent(Layer* layer) { - return layer->clip_parent(); -} - -static LayerImpl* ClipParent(LayerImpl* layer) { - return layer->test_properties()->clip_parent; -} - static bool HasClipRect(Layer* layer) { return !layer->clip_rect().IsEmpty(); } @@ -302,13 +263,6 @@ bool HasAnyAnimationTargetingProperty(const MutatorHost& host, // ------------------------------------------------------------------- template <typename LayerType> -static int GetTransformParent(const DataForRecursion& data, LayerType* layer) { - return PositionConstraint(layer).is_fixed_position() - ? data.transform_tree_parent_fixed - : data.transform_tree_parent; -} - -template <typename LayerType> static bool LayerClipsSubtreeToItsBounds(LayerType* layer) { return layer->masks_to_bounds() || MaskLayer(layer); } @@ -335,14 +289,6 @@ static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) { return layer->test_properties()->rounded_corner_bounds; } -template <typename LayerType> -static int GetScrollParentId(const DataForRecursion& data, LayerType* layer) { - const bool inherits_scroll = !ScrollParent(layer); - const int id = inherits_scroll ? data.scroll_tree_parent - : ScrollParent(layer)->scroll_tree_index(); - return id; -} - static Layer* LayerParent(Layer* layer) { return layer->parent(); } @@ -367,14 +313,6 @@ static inline bool Is3dSorted(LayerImpl* layer) { return layer->test_properties()->sorting_context_id != 0; } -static inline bool HasLatestSequenceNumber(const Layer* layer, int number) { - return layer->property_tree_sequence_number() == number; -} - -static inline bool HasLatestSequenceNumber(const LayerImpl*, int) { - return true; -} - static inline void SetHasClipNode(Layer* layer, bool val) { layer->SetHasClipNode(val); } @@ -387,13 +325,7 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( LayerType* layer, bool created_transform_node, DataForRecursion* data_for_children) const { - const bool inherits_clip = !ClipParent(layer); - // Sanity check the clip parent already built clip node before us. - DCHECK(inherits_clip || - HasLatestSequenceNumber(ClipParent(layer), - property_trees_.sequence_number)); - const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent - : ClipParent(layer)->clip_tree_index(); + const int parent_id = data_from_ancestor.clip_tree_parent; bool layer_clips_subtree = LayerClipsSubtree(layer); bool requires_node = @@ -409,7 +341,7 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( node.transform_id = created_transform_node ? data_for_children->transform_tree_parent - : GetTransformParent(data_from_ancestor, layer); + : data_from_ancestor.transform_tree_parent; if (layer_clips_subtree) { node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; } else { @@ -439,14 +371,6 @@ static inline gfx::Point3F TransformOrigin(LayerImpl* layer) { return layer->test_properties()->transform_origin; } -static inline bool IsContainerForFixedPositionLayers(Layer* layer) { - return layer->IsContainerForFixedPositionLayers(); -} - -static inline bool IsContainerForFixedPositionLayers(LayerImpl* layer) { - return layer->test_properties()->is_container_for_fixed_position_layers; -} - static inline bool ShouldFlattenTransform(Layer* layer) { return layer->should_flatten_transform(); } @@ -467,8 +391,6 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( overscroll_elasticity_element_id_ && layer->element_id() == overscroll_elasticity_element_id_; const bool is_scrollable = layer->scrollable(); - const bool is_fixed = PositionConstraint(layer).is_fixed_position(); - const bool is_sticky = StickyPositionConstraint(layer).is_sticky; // Scrolling a layer should not move it from being pixel-aligned to moving off // the pixel grid and becoming fuzzy. So always snap scrollable things to the // pixel grid. Layers may also request to be snapped as such. @@ -495,63 +417,26 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( DCHECK(!is_scrollable || is_snapped); bool requires_node = is_root || is_snapped || has_significant_transform || - has_any_transform_animation || has_surface || is_fixed || + has_any_transform_animation || has_surface || is_page_scale_layer || is_overscroll_elasticity_layer || - is_sticky || is_at_boundary_of_3d_rendering_context || + is_at_boundary_of_3d_rendering_context || HasRoundedCorner(layer); int parent_index = TransformTree::kRootNodeId; - int source_index = TransformTree::kRootNodeId; - gfx::Vector2dF source_offset; - + gfx::Vector2dF parent_offset; if (!is_root) { - parent_index = GetTransformParent(data_from_ancestor, layer); - // 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 = LayerParent(layer)->transform_tree_index(); - source_offset = LayerParent(layer)->offset_to_transform_parent(); - } - - // For a container of fixed position descendants, define for them their - // fixed-position transform parent as being this layer's transform node, or - // its transform parent's node if this layer won't have a node of its own. - // - // But if this layer is scrollable, then we point fixed position descendants - // to not be affected by this layer as it changes its scroll offset during - // a compositor thread scroll. We do this by pointing them to the direct - // parent of this layer, which acts as a proxy for this layer, without - // including scrolling, based on the assumption this layer has no transform - // itself when scrollable. - if (IsContainerForFixedPositionLayers(layer) || is_root) { - data_for_children->affected_by_outer_viewport_bounds_delta = - layer->IsResizedByBrowserControls(); - if (is_scrollable) { - DCHECK(Transform(layer).IsIdentity()); - if (!is_root) { - data_for_children->transform_tree_parent_fixed = - LayerParent(layer)->transform_tree_index(); - } - } else { - data_for_children->transform_tree_parent_fixed = - requires_node ? transform_tree_.next_available_id() : parent_index; - } + parent_index = data_from_ancestor.transform_tree_parent; + // Now layer tree mode (IsUsingLayerLists is false) is for ui compositor + // only. The transform tree hierarchy is always the same as layer hierarchy. + DCHECK_EQ(parent_index, LayerParent(layer)->transform_tree_index()); + parent_offset = LayerParent(layer)->offset_to_transform_parent(); } if (!requires_node) { data_for_children->should_flatten |= ShouldFlattenTransform(layer); gfx::Vector2dF local_offset = Position(layer).OffsetFromOrigin() + Transform(layer).To2dTranslation(); - gfx::Vector2dF source_to_parent; - if (source_index != parent_index) { - gfx::Transform to_parent; - transform_tree_.ComputeTranslation(source_index, parent_index, - &to_parent); - source_to_parent = to_parent.To2dTranslation(); - } - layer->SetOffsetToTransformParent(source_offset + source_to_parent + - local_offset); + layer->SetOffsetToTransformParent(parent_offset + local_offset); layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree( data_from_ancestor.should_flatten); layer->SetTransformTreeIndex(parent_index); @@ -574,11 +459,30 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( node->scrolls = is_scrollable; node->should_be_snapped = is_snapped; node->flattens_inherited_transform = data_for_children->should_flatten; - node->sorting_context_id = SortingContextId(layer); - if (layer == page_scale_layer_) - data_for_children->in_subtree_of_page_scale_layer = true; + if (is_root || is_page_scale_layer) { + // Root layer and page scale layer should not have transform or offset. + DCHECK(Position(layer).IsOrigin()); + DCHECK(parent_offset.IsZero()); + DCHECK(Transform(layer).IsIdentity()); + + if (is_root) { + DCHECK(!is_page_scale_layer); + transform_tree_.SetRootScaleAndTransform( + transform_tree_.device_scale_factor(), device_transform_); + } else { + DCHECK(is_page_scale_layer); + transform_tree_.set_page_scale_factor(page_scale_factor_); + node->local.Scale(page_scale_factor_, page_scale_factor_); + data_for_children->in_subtree_of_page_scale_layer = true; + } + } else { + node->local = Transform(layer); + node->origin = TransformOrigin(layer); + node->post_translation = parent_offset + Position(layer).OffsetFromOrigin(); + } + node->in_subtree_of_page_scale_layer = data_for_children->in_subtree_of_page_scale_layer; @@ -591,96 +495,13 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( GetAnimationScales(mutator_host_, layer, &node->maximum_animation_scale, &node->starting_animation_scale); - float post_local_scale_factor = 1.0f; - - if (is_page_scale_layer) { - if (!is_root) - post_local_scale_factor *= page_scale_factor_; - transform_tree_.set_page_scale_factor(page_scale_factor_); - } - - node->source_node_id = source_index; - node->post_local_scale_factor = post_local_scale_factor; - if (is_root) { - float page_scale_factor_for_root = - is_page_scale_layer ? page_scale_factor_ : 1.f; - // SetRootTransformsAndScales will be incorrect if the root layer has - // non-zero position, so ensure it is zero. - DCHECK(Position(layer).IsOrigin()); - transform_tree_.SetRootTransformsAndScales( - transform_tree_.device_scale_factor(), page_scale_factor_for_root, - device_transform_); - } else { - node->source_offset = source_offset; - node->update_post_local_transform(Position(layer), TransformOrigin(layer)); - } - if (is_overscroll_elasticity_layer) { DCHECK(!is_scrollable); node->scroll_offset = gfx::ScrollOffset(elastic_overscroll_); - } else if (!ScrollParent(layer)) { + } else { node->scroll_offset = layer->CurrentScrollOffset(); } - if (is_fixed) { - if (data_from_ancestor.affected_by_outer_viewport_bounds_delta) { - node->moved_by_outer_viewport_bounds_delta_x = - PositionConstraint(layer).is_fixed_to_right_edge(); - node->moved_by_outer_viewport_bounds_delta_y = - PositionConstraint(layer).is_fixed_to_bottom_edge(); - if (node->moved_by_outer_viewport_bounds_delta_x || - node->moved_by_outer_viewport_bounds_delta_y) { - transform_tree_.AddNodeAffectedByOuterViewportBoundsDelta(node->id); - } - } - } - - node->local = Transform(layer); - node->update_pre_local_transform(TransformOrigin(layer)); - - if (StickyPositionConstraint(layer).is_sticky) { - StickyPositionNodeData* sticky_data = - transform_tree_.StickyPositionData(node->id); - sticky_data->constraints = StickyPositionConstraint(layer); - sticky_data->scroll_ancestor = GetScrollParentId(data_from_ancestor, layer); - ScrollNode* scroll_ancestor = - scroll_tree_.Node(sticky_data->scroll_ancestor); - - // Position sticky should never attach to the inner viewport since it - // shouldn't be affected by pinch-zoom. If we did then we'd need setting - // the inner viewport bounds delta to cause a TransformTree update, which - // it currently doesn't. - DCHECK(!scroll_ancestor->scrolls_inner_viewport); - - if (sticky_data->constraints.is_anchored_right || - sticky_data->constraints.is_anchored_bottom) { - // Sticky nodes whose ancestor scroller is the inner / outer viewport - // need to have their local transform updated when the inner / outer - // viewport bounds change, but do not unconditionally move by that delta - // like fixed position nodes. - if (scroll_ancestor->scrolls_outer_viewport) - transform_tree_.AddNodeAffectedByOuterViewportBoundsDelta(node->id); - } - // Copy the ancestor nodes for later use. These elements 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). - ElementId shifting_sticky_box_element_id = - sticky_data->constraints.nearest_element_shifting_sticky_box; - if (shifting_sticky_box_element_id) { - sticky_data->nearest_node_shifting_sticky_box = - transform_tree_.FindNodeFromElementId(shifting_sticky_box_element_id) - ->id; - } - ElementId shifting_containing_block_element_id = - sticky_data->constraints.nearest_element_shifting_containing_block; - if (shifting_containing_block_element_id) { - sticky_data->nearest_node_shifting_containing_block = - transform_tree_ - .FindNodeFromElementId(shifting_containing_block_element_id) - ->id; - } - } - node->needs_local_transform_update = true; transform_tree_.UpdateTransforms(node->id); @@ -1234,14 +1055,6 @@ static inline bool UserScrollableVertical(LayerImpl* layer) { return layer->test_properties()->user_scrollable_vertical; } -static inline OverscrollBehavior GetOverscrollBehavior(Layer* layer) { - return layer->overscroll_behavior(); -} - -static inline OverscrollBehavior GetOverscrollBehavior(LayerImpl* layer) { - return layer->test_properties()->overscroll_behavior; -} - static inline const base::Optional<SnapContainerData>& GetSnapContainerData( Layer* layer) { return layer->snap_container_data(); @@ -1270,7 +1083,7 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( const DataForRecursion& data_from_ancestor, LayerType* layer, DataForRecursion* data_for_children) const { - int parent_id = GetScrollParentId(data_from_ancestor, layer); + int parent_id = data_from_ancestor.scroll_tree_parent; bool is_root = !LayerParent(layer); bool scrollable = layer->scrollable(); @@ -1316,7 +1129,6 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( node.user_scrollable_vertical = UserScrollableVertical(layer); node.element_id = layer->element_id(); node.transform_id = data_for_children->transform_tree_parent; - node.overscroll_behavior = GetOverscrollBehavior(layer); node.snap_container_data = GetSnapContainerData(layer); node_id = scroll_tree_.Insert(node, parent_id); @@ -1418,23 +1230,8 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( for (size_t i = 0; i < LayerChildren(layer).size(); ++i) { LayerType* current_child = LayerChildAt(layer, i); SetLayerPropertyChangedForChild(layer, current_child); - if (!ScrollParent(current_child)) { - BuildPropertyTreesInternal(current_child, data_for_children); - subtree_has_rounded_corner |= - *data_for_children.subtree_has_rounded_corner; - } - } - - auto scroll_children_range = scroll_children_map_.equal_range(layer); - for (auto it = scroll_children_range.first; - it != scroll_children_range.second; ++it) { - LayerType* scroll_child = it->second; - DCHECK_EQ(ScrollParent(scroll_child), layer); - DCHECK(LayerParent(scroll_child)); - base::AutoReset<int> auto_reset_effect_tree_parent( - &data_for_children.effect_tree_parent, - LayerParent(scroll_child)->effect_tree_index()); - BuildPropertyTreesInternal(scroll_child, data_for_children); + BuildPropertyTreesInternal(current_child, data_for_children); + subtree_has_rounded_corner |= *data_for_children.subtree_has_rounded_corner; } created_render_surface = UpdateRenderSurfaceIfNeeded( @@ -1453,13 +1250,6 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( } } -const LayerTreeHost& AllLayerRange(const Layer* root_layer) { - return *root_layer->layer_tree_host(); -} -const LayerTreeImpl& AllLayerRange(const LayerImpl* root_layer) { - return *root_layer->layer_tree_impl(); -} - } // namespace Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) { @@ -1484,45 +1274,29 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( const gfx::Rect& viewport, SkColor root_background_color) const { if (!property_trees_.needs_rebuild) { - bool page_scale_is_root_layer = page_scale_layer_ == root_layer_; + DCHECK_NE(page_scale_layer_, root_layer_); if (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()); - - // 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 device_scale_factor_for_page_scale_node = 1.f; - gfx::Transform device_transform_for_page_scale_node; - if (page_scale_is_root_layer) { - device_transform_for_page_scale_node = device_transform_; - device_scale_factor_for_page_scale_node = device_scale_factor; - } - - draw_property_utils::UpdatePageScaleFactor( - &property_trees_, node, page_scale_factor_, - device_scale_factor_for_page_scale_node, - device_transform_for_page_scale_node); + draw_property_utils::UpdatePageScaleFactor(&property_trees_, node, + page_scale_factor_); } draw_property_utils::UpdateElasticOverscroll( &property_trees_, overscroll_elasticity_element_id_, elastic_overscroll_); clip_tree_.SetViewportClip(gfx::RectF(viewport)); - float page_scale_factor_for_root = - page_scale_is_root_layer ? page_scale_factor_ : 1.f; - // SetRootTransformsAndScales will be incorrect if the root layer has + // SetRootScaleAndTransform will be incorrect if the root layer has // non-zero position, so ensure it is zero. DCHECK(Position(root_layer_).IsOrigin()); - transform_tree_.SetRootTransformsAndScales( - device_scale_factor, page_scale_factor_for_root, device_transform_); + transform_tree_.SetRootScaleAndTransform(device_scale_factor, + device_transform_); return; } DataForRecursion data_for_recursion; data_for_recursion.transform_tree_parent = TransformTree::kInvalidNodeId; - data_for_recursion.transform_tree_parent_fixed = - TransformTree::kInvalidNodeId; data_for_recursion.clip_tree_parent = ClipTree::kRootNodeId; data_for_recursion.effect_tree_parent = EffectTree::kInvalidNodeId; data_for_recursion.scroll_tree_parent = ScrollTree::kRootNodeId; @@ -1566,41 +1340,6 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( scroll_tree_.set_needs_update(false); } -#if DCHECK_IS_ON() -template <typename LayerType> -static void CheckDanglingScrollParent(LayerType* root_layer) { - std::unordered_set<const LayerType*> layers; - for (const auto* layer : AllLayerRange(root_layer)) - layers.insert(layer); - for (auto* layer : AllLayerRange(root_layer)) - DCHECK(!ScrollParent(layer) || - layers.find(ScrollParent(layer)) != layers.end()); -} - -static void CheckClipPointersForLayer(Layer* layer) { - if (!layer) - return; - - if (layer->clip_children()) { - for (auto it = layer->clip_children()->begin(); - it != layer->clip_children()->end(); ++it) { - DCHECK_EQ((*it)->clip_parent(), layer); - } - } -} -#endif - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::InitializeScrollChildrenMap() { -#if DCHECK_IS_ON() - CheckDanglingScrollParent(root_layer_); -#endif - for (auto* layer : AllLayerRange(root_layer_)) { - if (ScrollParent(layer)) - scroll_children_map_.emplace(ScrollParent(layer), layer); - } -} - void PropertyTreeBuilder::BuildPropertyTrees( Layer* root_layer, const Layer* page_scale_layer, @@ -1626,10 +1365,6 @@ void PropertyTreeBuilder::BuildPropertyTrees( elastic_overscroll, page_scale_factor, device_transform, root_layer->layer_tree_host()->mutator_host(), property_trees) .BuildPropertyTrees(device_scale_factor, viewport, color); -#if DCHECK_IS_ON() - for (auto* layer : AllLayerRange(root_layer)) - CheckClipPointersForLayer(layer); -#endif property_trees->ResetCachedData(); // During building property trees, all copy requests are moved from layers to // effect tree, which are then pushed at commit to compositor thread and diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc index 848d6e057fb..890e9032ba6 100644 --- a/chromium/cc/trees/property_tree_unittest.cc +++ b/chromium/cc/trees/property_tree_unittest.cc @@ -22,7 +22,6 @@ TEST(PropertyTreeTest, ComputeTransformRoot) { TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Translate(2, 2); - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 0); tree.UpdateTransforms(1); @@ -44,14 +43,13 @@ TEST(PropertyTreeTest, SetNeedsUpdate) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 0); EXPECT_FALSE(tree.needs_update()); - tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform()); + tree.SetRootScaleAndTransform(0.6f, gfx::Transform()); EXPECT_TRUE(tree.needs_update()); tree.set_needs_update(false); - tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform()); + tree.SetRootScaleAndTransform(0.6f, gfx::Transform()); EXPECT_FALSE(tree.needs_update()); } @@ -60,13 +58,11 @@ TEST(PropertyTreeTest, ComputeTransformChild) { TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Translate(2, 2); - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 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.UpdateTransforms(child.id); @@ -103,19 +99,16 @@ TEST(PropertyTreeTest, ComputeTransformSibling) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; - contents_root.source_node_id = 0; contents_root.local.Translate(2, 2); contents_root.id = tree.Insert(contents_root, 0); tree.UpdateTransforms(1); TransformNode child; child.local.Translate(3, 3); - child.source_node_id = 1; child.id = tree.Insert(child, 1); TransformNode sibling; sibling.local.Translate(7, 7); - sibling.source_node_id = 1; sibling.id = tree.Insert(sibling, 1); tree.UpdateTransforms(2); @@ -150,23 +143,19 @@ TEST(PropertyTreeTest, ComputeTransformSiblingSingularAncestor) { TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Translate(2, 2); - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 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); TransformNode child; child.local.Translate(3, 3); - child.source_node_id = 2; child.id = tree.Insert(child, 2); TransformNode sibling; sibling.local.Translate(7, 7); - sibling.source_node_id = 2; sibling.id = tree.Insert(sibling, 2); tree.UpdateTransforms(2); @@ -200,7 +189,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.Node(grand_parent)->source_node_id = 0; gfx::Transform rotation_about_x; rotation_about_x.RotateAboutXAxis(15); @@ -212,16 +200,13 @@ TEST(PropertyTreeTest, TransformsWithFlattening) { RenderSurfaceReason::kTest; effect_tree.Node(effect_parent)->surface_contents_scale = gfx::Vector2dF(1.f, 1.f); - tree.Node(parent)->source_node_id = grand_parent; tree.Node(parent)->local = rotation_about_x; int child = tree.Insert(TransformNode(), 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.Node(grand_child)->source_node_id = child; tree.Node(grand_child)->flattens_inherited_transform = true; tree.Node(grand_child)->local = rotation_about_x; @@ -275,13 +260,11 @@ TEST(PropertyTreeTest, MultiplicationOrder) { TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Translate(2, 2); - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 0); tree.UpdateTransforms(1); TransformNode child; child.local.Scale(2, 2); - child.source_node_id = 1; child.id = tree.Insert(child, 1); tree.UpdateTransforms(2); @@ -308,13 +291,11 @@ TEST(PropertyTreeTest, ComputeTransformWithUninvertibleTransform) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 0); tree.UpdateTransforms(1); TransformNode child; child.local.Scale(0, 0); - child.source_node_id = 1; child.id = tree.Insert(child, 1); tree.UpdateTransforms(2); @@ -338,25 +319,21 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; - contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 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.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.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.UpdateTransforms(child_id); @@ -398,18 +375,15 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) { TransformTree& tree = property_trees.transform_tree; int parent = tree.Insert(TransformNode(), 0); - tree.Node(parent)->source_node_id = 0; tree.Node(parent)->local.Translate(2, 2); gfx::Transform rotation_about_x; rotation_about_x.RotateAboutXAxis(15); int child = tree.Insert(TransformNode(), parent); - tree.Node(child)->source_node_id = parent; tree.Node(child)->local = rotation_about_x; int grand_child = tree.Insert(TransformNode(), child); - tree.Node(grand_child)->source_node_id = child; tree.Node(grand_child)->flattens_inherited_transform = true; tree.set_needs_update(true); @@ -452,12 +426,10 @@ TEST(PropertyTreeTest, NonIntegerTranslationTest) { TransformTree& tree = property_trees.transform_tree; int parent = tree.Insert(TransformNode(), 0); - tree.Node(parent)->source_node_id = 0; tree.Node(parent)->local.Translate(1.5f, 1.5f); int child = tree.Insert(TransformNode(), parent); tree.Node(child)->local.Translate(1, 1); - tree.Node(child)->source_node_id = parent; tree.set_needs_update(true); draw_property_utils::ComputeTransforms(&tree); EXPECT_FALSE( @@ -500,14 +472,12 @@ TEST(PropertyTreeTest, SingularTransformSnapTest) { effect_tree.Node(effect_parent)->surface_contents_scale = gfx::Vector2dF(1.f, 1.f); tree.Node(parent)->scrolls = true; - tree.Node(parent)->source_node_id = 0; int child = tree.Insert(TransformNode(), parent); TransformNode* child_node = tree.Node(child); child_node->scrolls = true; child_node->local.Scale3d(6.0f, 6.0f, 0.0f); child_node->local.Translate(1.3f, 1.3f); - child_node->source_node_id = parent; tree.set_needs_update(true); draw_property_utils::ComputeTransforms(&tree); @@ -544,7 +514,6 @@ TEST(EffectTreeTest, CopyOutputRequestsAreTransformed) { TransformTree& transform_tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Scale(2, 2); - contents_root.source_node_id = 0; contents_root.id = transform_tree.Insert(contents_root, 0); transform_tree.UpdateTransforms(contents_root.id); @@ -643,7 +612,6 @@ TEST(EffectTreeTest, CopyOutputRequestsThatBecomeIllegalAreDropped) { TransformTree& transform_tree = property_trees.transform_tree; TransformNode contents_root; contents_root.local.Scale(1.0f / 1.0e9f, 1.0f / 1.0e9f); - contents_root.source_node_id = 0; contents_root.id = transform_tree.Insert(contents_root, 0); transform_tree.UpdateTransforms(contents_root.id); diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index 2e69eddc64e..ed8eb19667d 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -16,8 +16,8 @@ #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" #include "cc/input/browser_controls_offset_manager.h" +#include "cc/metrics/compositor_timing_history.h" #include "cc/paint/paint_worklet_layer_painter.h" -#include "cc/scheduler/compositor_timing_history.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index dc7b697ae2b..7e9e5b66b2f 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -39,7 +39,7 @@ ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host, commit_waits_for_activation_(false), started_(false), defer_main_frame_update_(false), - defer_commits_(true) { + defer_commits_(false) { TRACE_EVENT0("cc", "ProxyMain::ProxyMain"); DCHECK(task_runner_provider_); DCHECK(IsMainThread()); @@ -201,11 +201,10 @@ void ProxyMain::BeginMainFrame( current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE; // Check now if we should stop deferring commits due to a timeout. We - // may also stop deferring in BeginMainFrame, but maintain the status - // from this point to keep scroll in sync. - if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) { + // may also stop deferring in layer_tree_host_->BeginMainFrame, but update + // the status at this point to keep scroll in sync. + if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout); - } skip_commit |= defer_commits_; if (!skip_commit) { @@ -448,10 +447,14 @@ void ProxyMain::SetDeferMainFrameUpdate(bool defer_main_frame_update) { return; defer_main_frame_update_ = defer_main_frame_update; - if (defer_main_frame_update_) + if (defer_main_frame_update_) { TRACE_EVENT_ASYNC_BEGIN0("cc", "ProxyMain::SetDeferMainFrameUpdate", this); - else + } else { TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferMainFrameUpdate", this); + } + + // Notify dependent systems that the deferral status has changed. + layer_tree_host_->OnDeferMainFrameUpdatesChanged(defer_main_frame_update_); // The impl thread needs to know that it should not issue BeginMainFrame. ImplThreadTaskRunner()->PostTask( @@ -472,15 +475,21 @@ void ProxyMain::StartDeferringCommits(base::TimeDelta timeout) { defer_commits_ = true; commits_restart_time_ = base::TimeTicks::Now() + timeout; + + // Notify dependent systems that the deferral status has changed. + layer_tree_host_->OnDeferCommitsChanged(defer_commits_); } void ProxyMain::StopDeferringCommits(PaintHoldingCommitTrigger trigger) { if (!defer_commits_) return; defer_commits_ = false; - UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger", trigger); + UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger2", trigger); commits_restart_time_ = base::TimeTicks(); TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferCommits", this); + + // Notify depended systems that the deferral status has changed. + layer_tree_host_->OnDeferCommitsChanged(defer_commits_); } bool ProxyMain::CommitRequested() const { diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc index 50227da93d4..ab20c16bcda 100644 --- a/chromium/cc/trees/scroll_node.cc +++ b/chromium/cc/trees/scroll_node.cc @@ -23,6 +23,7 @@ ScrollNode::ScrollNode() max_scroll_offset_affected_by_page_scale(false), scrolls_inner_viewport(false), scrolls_outer_viewport(false), + prevent_viewport_scrolling_from_inner(false), should_flatten(false), user_scrollable_horizontal(false), user_scrollable_vertical(false), @@ -41,6 +42,8 @@ bool ScrollNode::operator==(const ScrollNode& other) const { max_scroll_offset_affected_by_page_scale == other.max_scroll_offset_affected_by_page_scale && scrolls_inner_viewport == other.scrolls_inner_viewport && + prevent_viewport_scrolling_from_inner == + other.prevent_viewport_scrolling_from_inner && scrolls_outer_viewport == other.scrolls_outer_viewport && offset_to_transform_parent == other.offset_to_transform_parent && should_flatten == other.should_flatten && @@ -65,6 +68,8 @@ void ScrollNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetBoolean("scrolls_inner_viewport", scrolls_inner_viewport); value->SetBoolean("scrolls_outer_viewport", scrolls_outer_viewport); + value->SetBoolean("prevent_viewport_scrolling_from_inner", + prevent_viewport_scrolling_from_inner); element_id.AddToTracedValue(value); value->SetInteger("transform_id", transform_id); diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h index 1d2e6fa789e..57357bdf2e9 100644 --- a/chromium/cc/trees/scroll_node.h +++ b/chromium/cc/trees/scroll_node.h @@ -47,12 +47,13 @@ struct CC_EXPORT ScrollNode { bool max_scroll_offset_affected_by_page_scale : 1; bool scrolls_inner_viewport : 1; bool scrolls_outer_viewport : 1; + bool prevent_viewport_scrolling_from_inner : 1; bool should_flatten : 1; bool user_scrollable_horizontal : 1; bool user_scrollable_vertical : 1; // This offset is used when |scrollable| is false and there isn't a transform - // node already present that covers this offset. + // node already present that covers this offset. For layer tree mode only. gfx::Vector2dF offset_to_transform_parent; ElementId element_id; diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 0bc215ea7c4..962b023a9a2 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -11,10 +11,10 @@ #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" #include "cc/input/browser_controls_offset_manager.h" +#include "cc/metrics/compositor_timing_history.h" #include "cc/paint/paint_worklet_layer_painter.h" #include "cc/resources/ui_resource_manager.h" #include "cc/scheduler/commit_earlyout_reason.h" -#include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/scheduler.h" #include "cc/trees/latency_info_swap_promise.h" #include "cc/trees/layer_tree_frame_sink.h" @@ -51,7 +51,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, #endif inside_draw_(false), defer_main_frame_update_(false), - defer_commits_(true), + defer_commits_(false), animate_requested_(false), commit_requested_(false), inside_synchronous_composite_(false), @@ -266,15 +266,19 @@ void SingleThreadProxy::SetDeferMainFrameUpdate(bool defer_main_frame_update) { if (defer_main_frame_update_ == defer_main_frame_update) return; - if (defer_main_frame_update) + if (defer_main_frame_update) { TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate", this); - else + } else { TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate", this); + } defer_main_frame_update_ = defer_main_frame_update; + // Notify dependent systems that the deferral status has changed. + layer_tree_host_->OnDeferMainFrameUpdatesChanged(defer_main_frame_update_); + // The scheduler needs to know that it should not issue BeginMainFrame. scheduler_on_impl_thread_->SetDeferBeginMainFrame(defer_main_frame_update_); } @@ -291,6 +295,9 @@ void SingleThreadProxy::StartDeferringCommits(base::TimeDelta timeout) { defer_commits_ = true; commits_restart_time_ = base::TimeTicks::Now() + timeout; + + // Notify dependent systems that the deferral status has changed. + layer_tree_host_->OnDeferCommitsChanged(defer_commits_); } void SingleThreadProxy::StopDeferringCommits( @@ -299,8 +306,11 @@ void SingleThreadProxy::StopDeferringCommits( return; defer_commits_ = false; commits_restart_time_ = base::TimeTicks(); - UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger", trigger); + UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger2", trigger); TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); + + // Notify dependent systems that the deferral status has changed. + layer_tree_host_->OnDeferCommitsChanged(defer_commits_); } bool SingleThreadProxy::CommitRequested() const { @@ -808,16 +818,17 @@ void SingleThreadProxy::BeginMainFrame( // a commit here. commit_requested_ = true; + // Check now if we should stop deferring commits. Do this before + // DoBeginMainFrame because the latter updates scroll offsets, which + // we should avoid if deferring commits. + if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) + StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout); + DoBeginMainFrame(begin_frame_args); // New commits requested inside UpdateLayers should be respected. commit_requested_ = false; - // Check now if we should stop deferring commits - if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) { - StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout); - } - // At this point the main frame may have deferred commits to avoid committing // right now. if (defer_main_frame_update_ || defer_commits_ || @@ -843,12 +854,16 @@ void SingleThreadProxy::BeginMainFrame( void SingleThreadProxy::DoBeginMainFrame( const viz::BeginFrameArgs& begin_frame_args) { - // The impl-side scroll deltas may be manipulated directly via the - // InputHandler on the UI thread and the scale deltas may change when they are - // clamped on the impl thread. - std::unique_ptr<ScrollAndScaleSet> scroll_info = - host_impl_->ProcessScrollDeltas(); - layer_tree_host_->ApplyScrollAndScale(scroll_info.get()); + // Only update scroll deltas if we are going to commit the frame, otherwise + // scroll offsets get confused. + if (!defer_commits_) { + // The impl-side scroll deltas may be manipulated directly via the + // InputHandler on the UI thread and the scale deltas may change when they + // are clamped on the impl thread. + std::unique_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); + layer_tree_host_->ApplyScrollAndScale(scroll_info.get()); + } layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); diff --git a/chromium/cc/trees/sticky_position_constraint.cc b/chromium/cc/trees/sticky_position_constraint.cc new file mode 100644 index 00000000000..19f4cabe0fe --- /dev/null +++ b/chromium/cc/trees/sticky_position_constraint.cc @@ -0,0 +1,47 @@ +// Copyright 2013 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/sticky_position_constraint.h" + +namespace cc { + +StickyPositionConstraint::StickyPositionConstraint() + : is_anchored_left(false), + is_anchored_right(false), + is_anchored_top(false), + is_anchored_bottom(false), + left_offset(0.f), + right_offset(0.f), + top_offset(0.f), + bottom_offset(0.f) {} + +StickyPositionConstraint::StickyPositionConstraint( + const StickyPositionConstraint& other) = default; + +bool StickyPositionConstraint::operator==( + const StickyPositionConstraint& other) const { + return is_anchored_left == other.is_anchored_left && + is_anchored_right == other.is_anchored_right && + is_anchored_top == other.is_anchored_top && + is_anchored_bottom == other.is_anchored_bottom && + left_offset == other.left_offset && + right_offset == other.right_offset && top_offset == other.top_offset && + bottom_offset == other.bottom_offset && + constraint_box_rect == other.constraint_box_rect && + scroll_container_relative_sticky_box_rect == + other.scroll_container_relative_sticky_box_rect && + scroll_container_relative_containing_block_rect == + other.scroll_container_relative_containing_block_rect && + nearest_element_shifting_sticky_box == + other.nearest_element_shifting_sticky_box && + nearest_element_shifting_containing_block == + other.nearest_element_shifting_containing_block; +} + +bool StickyPositionConstraint::operator!=( + const StickyPositionConstraint& other) const { + return !(*this == other); +} + +} // namespace cc diff --git a/chromium/cc/trees/sticky_position_constraint.h b/chromium/cc/trees/sticky_position_constraint.h new file mode 100644 index 00000000000..3a0b06b075e --- /dev/null +++ b/chromium/cc/trees/sticky_position_constraint.h @@ -0,0 +1,63 @@ +// Copyright 2013 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_STICKY_POSITION_CONSTRAINT_H_ +#define CC_TREES_STICKY_POSITION_CONSTRAINT_H_ + +#include "cc/cc_export.h" + +#include "cc/paint/element_id.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_f.h" + +namespace cc { + +struct CC_EXPORT StickyPositionConstraint { + StickyPositionConstraint(); + StickyPositionConstraint(const StickyPositionConstraint& other); + + bool is_anchored_left : 1; + bool is_anchored_right : 1; + bool is_anchored_top : 1; + bool is_anchored_bottom : 1; + + // The offset from each edge of the ancestor scroller (or the viewport) to + // try to maintain to the sticky box as we scroll. + float left_offset; + float right_offset; + float top_offset; + float bottom_offset; + + // The rectangle in which the sticky box is able to be positioned. This may be + // smaller than the scroller viewport due to things like padding. + gfx::Rect constraint_box_rect; + + // The rectangle corresponding to original layout position of the sticky box + // relative to the scroll ancestor. The sticky box is only offset once the + // scroll has passed its initial position (e.g. top_offset will only push + // the element down from its original position). + gfx::Rect scroll_container_relative_sticky_box_rect; + + // The layout rectangle of the sticky box's containing block relative to the + // scroll ancestor. The sticky box is only moved as far as its containing + // block boundary. + gfx::Rect scroll_container_relative_containing_block_rect; + + // The nearest ancestor sticky element ids that affect the sticky box + // constraint rect and the containing block constraint rect respectively. + // They are used to generate nearest_node_shifting_sticky_box and + // nearest_node_shifting_containing_block in StickyPositionNodeData when the + // property trees are generated. They are useless after the property trees + // are generated. + ElementId nearest_element_shifting_sticky_box; + ElementId nearest_element_shifting_containing_block; + + bool operator==(const StickyPositionConstraint&) const; + bool operator!=(const StickyPositionConstraint&) const; +}; + +} // namespace cc + +#endif // CC_TREES_STICKY_POSITION_CONSTRAINT_H_ diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc index d91bf1d61bf..780bba5ec67 100644 --- a/chromium/cc/trees/transform_node.cc +++ b/chromium/cc/trees/transform_node.cc @@ -16,7 +16,6 @@ TransformNode::TransformNode() : id(TransformTree::kInvalidNodeId), parent_id(TransformTree::kInvalidNodeId), sticky_position_constraint_id(-1), - source_node_id(TransformTree::kInvalidNodeId), sorting_context_id(0), needs_local_transform_update(true), node_and_ancestors_are_animated_or_invertible(true), @@ -25,16 +24,14 @@ TransformNode::TransformNode() has_potential_animation(false), is_currently_animating(false), to_screen_is_potentially_animated(false), - flattens_inherited_transform(false), + flattens_inherited_transform(true), node_and_ancestors_are_flat(true), node_and_ancestors_have_only_integer_translation(true), scrolls(false), should_be_snapped(false), - moved_by_outer_viewport_bounds_delta_x(false), moved_by_outer_viewport_bounds_delta_y(false), in_subtree_of_page_scale_layer(false), transform_changed(false), - post_local_scale_factor(1.0f), maximum_animation_scale(kNotScaled), starting_animation_scale(kNotScaled) {} @@ -42,10 +39,9 @@ TransformNode::TransformNode(const TransformNode&) = default; bool TransformNode::operator==(const TransformNode& other) const { return id == other.id && parent_id == other.parent_id && - element_id == other.element_id && pre_local == other.pre_local && - local == other.local && post_local == other.post_local && + element_id == other.element_id && local == other.local && + origin == other.origin && post_translation == other.post_translation && to_parent == other.to_parent && - source_node_id == other.source_node_id && sorting_context_id == other.sorting_context_id && needs_local_transform_update == other.needs_local_transform_update && node_and_ancestors_are_animated_or_invertible == @@ -62,48 +58,24 @@ bool TransformNode::operator==(const TransformNode& other) const { other.node_and_ancestors_have_only_integer_translation && scrolls == other.scrolls && should_be_snapped == other.should_be_snapped && - moved_by_outer_viewport_bounds_delta_x == - other.moved_by_outer_viewport_bounds_delta_x && moved_by_outer_viewport_bounds_delta_y == other.moved_by_outer_viewport_bounds_delta_y && in_subtree_of_page_scale_layer == other.in_subtree_of_page_scale_layer && transform_changed == other.transform_changed && - post_local_scale_factor == other.post_local_scale_factor && scroll_offset == other.scroll_offset && snap_amount == other.snap_amount && - source_offset == other.source_offset && - source_to_parent == other.source_to_parent && maximum_animation_scale == other.maximum_animation_scale && starting_animation_scale == other.starting_animation_scale; } -void TransformNode::update_pre_local_transform( - const gfx::Point3F& transform_origin) { - pre_local.MakeIdentity(); - pre_local.Translate3d(-transform_origin.x(), -transform_origin.y(), - -transform_origin.z()); -} - -void TransformNode::update_post_local_transform( - const gfx::PointF& position, - const gfx::Point3F& transform_origin) { - post_local.MakeIdentity(); - post_local.Scale(post_local_scale_factor, post_local_scale_factor); - post_local.Translate3d( - position.x() + source_offset.x() + transform_origin.x(), - position.y() + source_offset.y() + transform_origin.y(), - transform_origin.z()); -} - void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); element_id.AddToTracedValue(value); - MathUtil::AddToTracedValue("pre_local", pre_local, value); MathUtil::AddToTracedValue("local", local, value); - MathUtil::AddToTracedValue("post_local", post_local, value); - value->SetInteger("source_node_id", source_node_id); + MathUtil::AddToTracedValue("origin", origin, value); + MathUtil::AddToTracedValue("post_translation", post_translation, value); value->SetInteger("sorting_context_id", sorting_context_id); value->SetInteger("flattens_inherited_transform", flattens_inherited_transform); diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h index 4f123a6390f..401af01e617 100644 --- a/chromium/cc/trees/transform_node.h +++ b/chromium/cc/trees/transform_node.h @@ -7,6 +7,7 @@ #include "cc/cc_export.h" #include "cc/paint/element_id.h" +#include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" @@ -32,23 +33,13 @@ struct CC_EXPORT TransformNode { // The local transform information is combined to form to_parent (ignoring // snapping) as follows: - // - // to_parent = M_post_local * T_scroll * M_local * M_pre_local. - // - // The pre/post may seem odd when read LTR, but we multiply our points from - // the right, so the pre_local matrix affects the result "first". This lines - // up with the notions of pre/post used in skia and gfx::Transform. - // - // TODO(vollick): The values labeled with "will be moved..." take up a lot of - // space, but are only necessary for animated or scrolled nodes (otherwise - // we'll just use the baked to_parent). These values will be ultimately stored - // directly on the transform/scroll display list items when that's possible, - // or potentially in a scroll tree. - // - // TODO(vollick): will be moved when accelerated effects are implemented. - gfx::Transform pre_local; + // to_parent = + // T_post_translation * T_origin * T_scroll * M_local * -T_origin. gfx::Transform local; - gfx::Transform post_local; + gfx::Point3F origin; + // For layer tree mode only. In layer list mode, when the translation is + // needed, blink creates paint offset translation node above this node. + gfx::Vector2dF post_translation; gfx::Transform to_parent; @@ -56,19 +47,13 @@ struct CC_EXPORT TransformNode { // transform node. -1 indicates there are no sticky position constraints. int sticky_position_constraint_id; - // This is the node with respect to which source_offset is defined. This will - // not be needed once layerization moves to cc, but is needed in order to - // efficiently update the transform tree for changes to position in the layer - // tree. - int source_node_id; - // This id determines which 3d rendering context the node is in. 0 is a // special value and indicates that the node is not in any 3d rendering // context. int sorting_context_id; // True if |TransformTree::UpdateLocalTransform| needs to be called which - // will update |to_parent| and |source_to_parent| (if possible). + // will update |to_parent|. bool needs_local_transform_update : 1; // Whether this node or any ancestor has a potentially running @@ -92,7 +77,7 @@ struct CC_EXPORT TransformNode { bool to_screen_is_potentially_animated : 1; // Flattening, when needed, is only applied to a node's inherited transform, - // never to its local transform. + // never to its local transform. It's true by default. bool flattens_inherited_transform : 1; // This is true if the to_parent transform at every node on the path to the @@ -106,13 +91,9 @@ struct CC_EXPORT TransformNode { bool should_be_snapped : 1; - // These are used by the compositor to determine which layers need to be - // repositioned by the compositor as a result of browser controls - // expanding/contracting the outer viewport size before Blink repositions the - // fixed layers. - // TODO(bokan): Note: we never change bounds_delta in the x direction so we - // can remove this variable. - bool moved_by_outer_viewport_bounds_delta_x : 1; + // Used by the compositor to determine which layers need to be repositioned by + // the compositor as a result of browser controls expanding/contracting the + // outer viewport size before Blink repositions the fixed layers. bool moved_by_outer_viewport_bounds_delta_y : 1; // Layer scale factor is used as a fallback when we either cannot adjust @@ -124,10 +105,6 @@ struct CC_EXPORT TransformNode { // We need to track changes to to_screen transform to compute the damage rect. bool transform_changed : 1; - // TODO(vollick): will be moved when accelerated effects are implemented. - float post_local_scale_factor; - - // TODO(vollick): will be moved when accelerated effects are implemented. gfx::ScrollOffset scroll_offset; // This value stores the snapped amount whenever we snap. If the snap is due @@ -135,10 +112,6 @@ struct CC_EXPORT TransformNode { // otherwise we may need it to undo the snapping next frame. gfx::Vector2dF snap_amount; - // TODO(vollick): will be moved when accelerated effects are implemented. - gfx::Vector2dF source_offset; - gfx::Vector2dF source_to_parent; - // See MutatorHost::GetAnimationScales() for their meanings. Updated by // PropertyTrees::AnimationScalesChanged(). float maximum_animation_scale; @@ -151,11 +124,6 @@ struct CC_EXPORT TransformNode { is_invertible = to_parent.IsInvertible(); } - void update_pre_local_transform(const gfx::Point3F& transform_origin); - - void update_post_local_transform(const gfx::PointF& position, - const gfx::Point3F& transform_origin); - void AsValueInto(base::trace_event::TracedValue* value) const; }; diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index 393e45b1167..33c32cbb52c 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -149,8 +149,9 @@ static void PushLayerPropertiesInternal(Iterator source_layers_begin, bool host_set_on_source = source_layer->layer_tree_host() == host_tree; bool source_found_by_iterator = false; - for (auto it = host_tree->begin(); it != host_tree->end(); ++it) { - if (*it == source_layer) { + for (auto host_tree_it = host_tree->begin(); + host_tree_it != host_tree->end(); ++it) { + if (*host_tree_it == source_layer) { source_found_by_iterator = true; break; } diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index 6d0d4e5688e..08690725e5f 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -119,14 +119,6 @@ void ExpectTreesAreIdentical(Layer* root_layer, mask_layer_id, effect_tree.Node(layer_impl->effect_tree_index())->mask_layer_id); } - - const Layer* layer_clip_parent = layer->clip_parent(); - - if (layer_clip_parent) { - const std::set<Layer*>* clip_children = - layer_clip_parent->clip_children(); - ASSERT_TRUE(clip_children->find(layer) != clip_children->end()); - } } } @@ -540,7 +532,7 @@ TEST_F(TreeSynchronizerTest, SyncMaskLayer) { // First child gets a mask layer. FakeContentLayerClient client; scoped_refptr<PictureLayer> mask_layer = PictureLayer::Create(&client); - layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get()); + layer_tree_root->children()[0]->SetMaskLayer(mask_layer); host_->SetRootLayer(layer_tree_root); host_->BuildPropertyTreesForTesting(); |