Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3435)

Unified Diff: cc/trees/property_tree.cc

Issue 1736073002: cc: Move SyncedScrollOffset to scroll tree (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and add comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/property_tree.cc
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 12bba3677f96f779da1aa8e463e30c2e03cf03a9..f10b6d30f03ed6150c6a3344c0f9f3164108304f 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -10,11 +10,15 @@
#include "base/logging.h"
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
+#include "cc/layers/layer_impl.h"
#include "cc/proto/gfx_conversions.h"
#include "cc/proto/property_tree.pb.h"
#include "cc/proto/scroll_offset.pb.h"
+#include "cc/proto/synced_property_conversions.h"
#include "cc/proto/transform.pb.h"
#include "cc/proto/vector2df.pb.h"
+#include "cc/trees/layer_tree_host_common.h"
+#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/property_tree.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
@@ -1287,13 +1291,46 @@ void EffectTree::FromProtobuf(const proto::PropertyTree& proto) {
PropertyTree::FromProtobuf(proto);
}
-ScrollTree::ScrollTree() : currently_scrolling_node_id_(-1) {}
+ScrollTree::ScrollTree()
+ : currently_scrolling_node_id_(-1),
+ layer_id_to_scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {}
ScrollTree::~ScrollTree() {}
+ScrollTree& ScrollTree::operator=(const ScrollTree& from) {
+ PropertyTree::operator=(from);
+ currently_scrolling_node_id_ = -1;
+ // layer_id_to_scroll_offset_map_ is intentionally omitted in operator=,
+ // because we do not want to simply copy the map when property tree is
+ // propagating from pending to active.
+ // In the main to pending case, we do want to copy it, but this can be done by
+ // calling UpdateScrollOffsetMap after the assignment;
+ // In the other case, we want pending and active property trees to share the
+ // same map.
+ return *this;
+}
+
bool ScrollTree::operator==(const ScrollTree& other) const {
- return PropertyTree::operator==(other) &&
- CurrentlyScrollingNode() == other.CurrentlyScrollingNode();
+ const ScrollTree::ScrollOffsetMap& other_scroll_offset_map =
+ other.scroll_offset_map();
+ if (layer_id_to_scroll_offset_map_.size() != other_scroll_offset_map.size())
+ return false;
+
+ for (auto map_entry : layer_id_to_scroll_offset_map_) {
+ int key = map_entry.first;
+ if (other_scroll_offset_map.find(key) == other_scroll_offset_map.end() ||
+ map_entry.second != layer_id_to_scroll_offset_map_.at(key))
+ return false;
+ }
+
+ bool is_currently_scrolling_node_equal =
+ (currently_scrolling_node_id_ == -1)
+ ? (!other.CurrentlyScrollingNode())
+ : (other.CurrentlyScrollingNode() &&
+ currently_scrolling_node_id_ ==
+ other.CurrentlyScrollingNode()->id);
+
+ return PropertyTree::operator==(other) && is_currently_scrolling_node_equal;
}
void ScrollTree::ToProtobuf(proto::PropertyTree* proto) const {
@@ -1304,6 +1341,14 @@ void ScrollTree::ToProtobuf(proto::PropertyTree* proto) const {
proto::ScrollTreeData* data = proto->mutable_scroll_tree_data();
data->set_currently_scrolling_node_id(currently_scrolling_node_id_);
+ for (auto i : layer_id_to_scroll_offset_map_) {
+ data->add_layer_id_to_scroll_offset_map();
+ proto::ScrollOffsetMapEntry* entry =
+ data->mutable_layer_id_to_scroll_offset_map(
+ data->layer_id_to_scroll_offset_map_size() - 1);
+ entry->set_layer_id(i.first);
+ SyncedScrollOffsetToProto(*i.second.get(), entry->mutable_scroll_offset());
+ }
}
void ScrollTree::FromProtobuf(const proto::PropertyTree& proto) {
@@ -1314,6 +1359,24 @@ void ScrollTree::FromProtobuf(const proto::PropertyTree& proto) {
const proto::ScrollTreeData& data = proto.scroll_tree_data();
currently_scrolling_node_id_ = data.currently_scrolling_node_id();
+
+ for (int i = 0; i < data.layer_id_to_scroll_offset_map_size(); ++i) {
+ const proto::ScrollOffsetMapEntry entry =
+ data.layer_id_to_scroll_offset_map(i);
+ layer_id_to_scroll_offset_map_[entry.layer_id()] = new SyncedScrollOffset();
+ ProtoToSyncedScrollOffset(
+ entry.scroll_offset(),
+ layer_id_to_scroll_offset_map_[entry.layer_id()].get());
+ }
+}
+
+void ScrollTree::clear() {
+ PropertyTree<ScrollNode>::clear();
+
+ if (property_trees()->is_main_thread) {
+ currently_scrolling_node_id_ = -1;
+ layer_id_to_scroll_offset_map_.clear();
+ }
}
gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const {
@@ -1399,12 +1462,130 @@ gfx::Transform ScrollTree::ScreenSpaceTransform(int scroll_node_id) const {
return screen_space_transform;
}
+// TODO(sunxd): Make this function private once scroll offset access is fully
+// directed to scroll tree.
+SyncedScrollOffset* ScrollTree::synced_scroll_offset(int layer_id) {
+ if (layer_id_to_scroll_offset_map_.find(layer_id) ==
+ layer_id_to_scroll_offset_map_.end()) {
+ layer_id_to_scroll_offset_map_[layer_id] = new SyncedScrollOffset;
+ }
+ return layer_id_to_scroll_offset_map_[layer_id].get();
+}
+
+gfx::ScrollOffset ScrollTree::PullDeltaForMainThread(
+ SyncedScrollOffset* scroll_offset) {
+ // TODO(miletus): Remove all this temporary flooring machinery when
+ // Blink fully supports fractional scrolls.
+ gfx::ScrollOffset current_offset =
+ scroll_offset->Current(property_trees()->is_active);
+ gfx::ScrollOffset current_delta = property_trees()->is_active
+ ? scroll_offset->Delta()
+ : scroll_offset->PendingDelta().get();
+ gfx::ScrollOffset floored_delta(floor(current_delta.x()),
+ floor(current_delta.y()));
+ gfx::ScrollOffset diff_delta = floored_delta - current_delta;
+ gfx::ScrollOffset tmp_offset = current_offset + diff_delta;
+ scroll_offset->SetCurrent(tmp_offset);
+ gfx::ScrollOffset delta = scroll_offset->PullDeltaForMainThread();
+ scroll_offset->SetCurrent(current_offset);
+ return delta;
+}
+
+void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info) {
+ for (auto map_entry : layer_id_to_scroll_offset_map_) {
+ gfx::ScrollOffset scroll_delta =
+ PullDeltaForMainThread(map_entry.second.get());
+
+ if (!scroll_delta.IsZero()) {
+ LayerTreeHostCommon::ScrollUpdateInfo scroll;
+ scroll.layer_id = map_entry.first;
+ scroll.scroll_delta = gfx::Vector2d(scroll_delta.x(), scroll_delta.y());
+ scroll_info->scrolls.push_back(scroll);
+ }
+ }
+}
+
+void ScrollTree::UpdateScrollOffsetMapEntry(
+ int key,
+ ScrollTree::ScrollOffsetMap* new_scroll_offset_map,
+ LayerTreeImpl* layer_tree_impl) {
+ bool changed = false;
+ // If we are pushing scroll offset from main to pending tree, we create a new
+ // instance of synced scroll offset; if we are pushing from pending to active,
+ // we reuse the pending tree's value in the map.
+ if (!property_trees()->is_active) {
+ changed = synced_scroll_offset(key)->PushFromMainThread(
+ new_scroll_offset_map->at(key)->PendingBase());
+
+ if (new_scroll_offset_map->at(key)->clobber_active_value()) {
+ synced_scroll_offset(key)->set_clobber_active_value();
+ }
+ if (changed)
+ layer_tree_impl->LayerById(key)->DidUpdateScrollOffset();
+ } else {
+ layer_id_to_scroll_offset_map_[key] = new_scroll_offset_map->at(key);
+ changed |= synced_scroll_offset(key)->PushPendingToActive();
+ if (changed)
+ layer_tree_impl->LayerById(key)->DidUpdateScrollOffset();
+ }
+}
+
+void ScrollTree::UpdateScrollOffsetMap(
+ ScrollTree::ScrollOffsetMap* new_scroll_offset_map,
+ LayerTreeImpl* layer_tree_impl) {
+ if (layer_tree_impl && layer_tree_impl->root_layer()) {
+ DCHECK(!property_trees()->is_main_thread);
+ for (auto map_entry = layer_id_to_scroll_offset_map_.begin();
+ map_entry != layer_id_to_scroll_offset_map_.end();) {
+ int key = map_entry->first;
+ if (new_scroll_offset_map->find(key) != new_scroll_offset_map->end()) {
+ UpdateScrollOffsetMapEntry(key, new_scroll_offset_map, layer_tree_impl);
+ ++map_entry;
+ } else {
+ map_entry = layer_id_to_scroll_offset_map_.erase(map_entry);
+ }
+ }
+
+ for (auto& map_entry : *new_scroll_offset_map) {
+ int key = map_entry.first;
+ if (layer_id_to_scroll_offset_map_.find(key) ==
+ layer_id_to_scroll_offset_map_.end())
+ UpdateScrollOffsetMapEntry(key, new_scroll_offset_map, layer_tree_impl);
+ }
+ }
+}
+
+ScrollTree::ScrollOffsetMap& ScrollTree::scroll_offset_map() {
+ return layer_id_to_scroll_offset_map_;
+}
+
+const ScrollTree::ScrollOffsetMap& ScrollTree::scroll_offset_map() const {
+ return layer_id_to_scroll_offset_map_;
+}
+
+void ScrollTree::ApplySentScrollDeltasFromAbortedCommit() {
+ DCHECK(property_trees()->is_active);
+ for (auto& map_entry : layer_id_to_scroll_offset_map_)
+ map_entry.second->AbortCommit();
+}
+
+bool ScrollTree::SetScrollOffset(int layer_id,
+ const gfx::ScrollOffset& scroll_offset) {
+ if (property_trees()->is_main_thread)
+ return synced_scroll_offset(layer_id)->PushFromMainThread(scroll_offset);
+ else if (property_trees()->is_active)
+ return synced_scroll_offset(layer_id)->SetCurrent(scroll_offset);
+ return false;
+}
+
PropertyTrees::PropertyTrees()
: needs_rebuild(true),
non_root_surfaces_enabled(true),
changed(false),
full_tree_damaged(false),
- sequence_number(0) {
+ sequence_number(0),
+ is_main_thread(true),
+ is_active(false) {
transform_tree.SetPropertyTrees(this);
effect_tree.SetPropertyTrees(this);
clip_tree.SetPropertyTrees(this);
@@ -1419,6 +1600,8 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const {
scroll_tree == other.scroll_tree &&
needs_rebuild == other.needs_rebuild && changed == other.changed &&
full_tree_damaged == other.full_tree_damaged &&
+ is_main_thread == other.is_main_thread &&
+ is_active == other.is_active &&
non_root_surfaces_enabled == other.non_root_surfaces_enabled &&
sequence_number == other.sequence_number;
}
@@ -1433,6 +1616,8 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) {
full_tree_damaged = from.full_tree_damaged;
non_root_surfaces_enabled = from.non_root_surfaces_enabled;
sequence_number = from.sequence_number;
+ is_main_thread = from.is_main_thread;
+ is_active = from.is_active;
inner_viewport_container_bounds_delta_ =
from.inner_viewport_container_bounds_delta();
outer_viewport_container_bounds_delta_ =
@@ -1457,6 +1642,8 @@ void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const {
proto->set_changed(changed);
proto->set_full_tree_damaged(full_tree_damaged);
proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled);
+ proto->set_is_main_thread(is_main_thread);
+ proto->set_is_active(is_active);
// TODO(khushalsagar): Consider using the sequence number to decide if
// property trees need to be serialized again for a commit. See crbug/555370.
@@ -1475,6 +1662,8 @@ void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) {
full_tree_damaged = proto.full_tree_damaged();
non_root_surfaces_enabled = proto.non_root_surfaces_enabled();
sequence_number = proto.sequence_number();
+ is_main_thread = proto.is_main_thread();
+ is_active = proto.is_active();
transform_tree.SetPropertyTrees(this);
effect_tree.SetPropertyTrees(this);
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698