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

Side by Side Diff: cc/trees/property_tree.cc

Issue 2251303003: Implement position: sticky updates on compositor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup and add unit test for impl side sticky position update. Created 4 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 void TransformTree::clear() { 142 void TransformTree::clear() {
143 PropertyTree<TransformNode>::clear(); 143 PropertyTree<TransformNode>::clear();
144 144
145 page_scale_factor_ = 1.f; 145 page_scale_factor_ = 1.f;
146 device_scale_factor_ = 1.f; 146 device_scale_factor_ = 1.f;
147 device_transform_scale_factor_ = 1.f; 147 device_transform_scale_factor_ = 1.f;
148 nodes_affected_by_inner_viewport_bounds_delta_.clear(); 148 nodes_affected_by_inner_viewport_bounds_delta_.clear();
149 nodes_affected_by_outer_viewport_bounds_delta_.clear(); 149 nodes_affected_by_outer_viewport_bounds_delta_.clear();
150 cached_data_.clear(); 150 cached_data_.clear();
151 cached_data_.push_back(TransformCachedNodeData()); 151 cached_data_.push_back(TransformCachedNodeData());
152 sticky_position_data_.clear();
153 sticky_position_data_free_ids_.clear();
152 154
153 #if DCHECK_IS_ON() 155 #if DCHECK_IS_ON()
154 TransformTree tree; 156 TransformTree tree;
155 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed 157 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed
156 // to be true on impl thread to main thread and set it to is_main_thread here. 158 // to be true on impl thread to main thread and set it to is_main_thread here.
157 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_; 159 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_;
158 DCHECK(tree == *this); 160 DCHECK(tree == *this);
159 #endif 161 #endif
160 } 162 }
161 163
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 node->transform_changed = false; 245 node->transform_changed = false;
244 } 246 }
245 } 247 }
246 248
247 void TransformTree::UpdateTransforms(int id) { 249 void TransformTree::UpdateTransforms(int id) {
248 TransformNode* node = Node(id); 250 TransformNode* node = Node(id);
249 TransformNode* parent_node = parent(node); 251 TransformNode* parent_node = parent(node);
250 TransformNode* target_node = Node(TargetId(id)); 252 TransformNode* target_node = Node(TargetId(id));
251 TransformNode* source_node = Node(node->source_node_id); 253 TransformNode* source_node = Node(node->source_node_id);
252 property_trees()->UpdateCachedNumber(); 254 property_trees()->UpdateCachedNumber();
253 if (node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) 255 // TODO(flackr): Only dirty when scroll offset changes.
256 if (node->sticky_position_constraint_id >= 0 ||
257 node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) {
254 UpdateLocalTransform(node); 258 UpdateLocalTransform(node);
255 else 259 } else {
256 UndoSnapping(node); 260 UndoSnapping(node);
261 }
257 UpdateScreenSpaceTransform(node, parent_node, target_node); 262 UpdateScreenSpaceTransform(node, parent_node, target_node);
258 UpdateSurfaceContentsScale(node); 263 UpdateSurfaceContentsScale(node);
259 UpdateAnimationProperties(node, parent_node); 264 UpdateAnimationProperties(node, parent_node);
260 UpdateSnapping(node); 265 UpdateSnapping(node);
261 UpdateTargetSpaceTransform(node, target_node); 266 UpdateTargetSpaceTransform(node, target_node);
262 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); 267 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
263 UpdateTransformChanged(node, parent_node, source_node); 268 UpdateTransformChanged(node, parent_node, source_node);
264 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); 269 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node);
265 } 270 }
266 271
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 // from the destination to the source, with flattening, and then invert the 397 // from the destination to the source, with flattening, and then invert the
393 // result. 398 // result.
394 gfx::Transform dest_to_source; 399 gfx::Transform dest_to_source;
395 CombineTransformsBetween(dest_id, source_id, &dest_to_source); 400 CombineTransformsBetween(dest_id, source_id, &dest_to_source);
396 gfx::Transform source_to_dest; 401 gfx::Transform source_to_dest;
397 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); 402 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest);
398 transform->PreconcatTransform(source_to_dest); 403 transform->PreconcatTransform(source_to_dest);
399 return all_are_invertible; 404 return all_are_invertible;
400 } 405 }
401 406
407 TransformNode* ScrollingAncestor(TransformTree* tree, TransformNode* node) {
ajuma 2016/09/08 22:08:54 This function seems to be unused?
flackr 2016/09/20 17:08:13 Removed. Yes, this ended up not being needed as we
408 do {
409 node = tree->parent(node);
410 } while (!node->scrolls);
411 return node;
412 }
413
414 gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
415 if (node->sticky_position_constraint_id == -1)
416 return gfx::Vector2dF();
417 const StickyPositionNodeData* sticky_data =
418 tree->StickyPositionData(node->id);
419 const LayerStickyPositionConstraint& constraint = sticky_data->constraints;
420 ScrollNode* scroll_node =
421 tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor);
422 gfx::ScrollOffset scroll_offset =
423 tree->property_trees()->scroll_tree.current_scroll_offset(
424 scroll_node->owner_id);
425
426 gfx::RectF clip(gfx::PointF(scroll_offset.x(), scroll_offset.y()),
427 gfx::SizeF(scroll_node->scroll_clip_layer_bounds));
428 gfx::Vector2dF sticky_offset(
429 constraint.absolute_sticky_box_rect.OffsetFromOrigin());
430 gfx::Vector2dF layer_offset(sticky_data->main_thread_offset);
431 if (constraint.is_anchored_right) {
ajuma 2016/09/08 22:08:54 Please explain (in a comment) what the math here i
flackr 2016/09/20 17:08:13 Done. I tried to summarize above.
432 float right_limit = clip.right() - constraint.right_offset;
433 float right_delta = std::min<float>(
434 0, right_limit - constraint.absolute_sticky_box_rect.right());
435 float available_space =
436 std::min<float>(0, constraint.absolute_containing_block_rect.x() -
437 constraint.absolute_sticky_box_rect.x());
438 if (right_delta < available_space)
439 right_delta = available_space;
440 sticky_offset.set_x(sticky_offset.x() + right_delta);
441 }
442 if (constraint.is_anchored_left) {
443 float left_limit = clip.x() + constraint.left_offset;
444 float left_delta = std::max<float>(
445 0, left_limit - constraint.absolute_sticky_box_rect.x());
446 float available_space =
447 std::max<float>(0, constraint.absolute_containing_block_rect.right() -
448 constraint.absolute_sticky_box_rect.right());
449 if (left_delta > available_space)
450 left_delta = available_space;
451 sticky_offset.set_x(sticky_offset.x() + left_delta);
452 }
453 if (constraint.is_anchored_bottom) {
454 float bottom_limit = clip.bottom() - constraint.bottom_offset;
455 float bottom_delta = std::min<float>(
456 0, bottom_limit - constraint.absolute_sticky_box_rect.bottom());
457 float available_space =
458 std::min<float>(0, constraint.absolute_containing_block_rect.y() -
459 constraint.absolute_sticky_box_rect.y());
460 if (bottom_delta < available_space)
461 bottom_delta = available_space;
462 sticky_offset.set_y(sticky_offset.y() + bottom_delta);
463 }
464 if (constraint.is_anchored_top) {
465 float top_limit = clip.y() + constraint.top_offset;
466 float top_delta =
467 std::max<float>(0, top_limit - constraint.absolute_sticky_box_rect.y());
468 float available_space =
469 std::max<float>(0, constraint.absolute_containing_block_rect.bottom() -
470 constraint.absolute_sticky_box_rect.bottom());
471 if (top_delta > available_space)
472 top_delta = available_space;
473 sticky_offset.set_y(sticky_offset.y() + top_delta);
474 }
475 return sticky_offset - layer_offset -
476 constraint.absolute_sticky_box_rect.OffsetFromOrigin();
477 }
478
402 void TransformTree::UpdateLocalTransform(TransformNode* node) { 479 void TransformTree::UpdateLocalTransform(TransformNode* node) {
403 gfx::Transform transform = node->post_local; 480 gfx::Transform transform = node->post_local;
404 if (NeedsSourceToParentUpdate(node)) { 481 if (NeedsSourceToParentUpdate(node)) {
405 gfx::Transform to_parent; 482 gfx::Transform to_parent;
406 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); 483 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent);
407 gfx::Vector2dF unsnapping; 484 gfx::Vector2dF unsnapping;
408 TransformNode* current; 485 TransformNode* current;
409 TransformNode* parent_node; 486 TransformNode* parent_node;
410 for (current = Node(node->source_node_id); current->id > node->parent_id; 487 for (current = Node(node->source_node_id); current->id > node->parent_id;
411 current = parent(current)) { 488 current = parent(current)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 fixed_position_adjustment.set_y(inner_viewport_bounds_delta.y()); 520 fixed_position_adjustment.set_y(inner_viewport_bounds_delta.y());
444 else if (node->affected_by_outer_viewport_bounds_delta_y) 521 else if (node->affected_by_outer_viewport_bounds_delta_y)
445 fixed_position_adjustment.set_y(outer_viewport_bounds_delta.y()); 522 fixed_position_adjustment.set_y(outer_viewport_bounds_delta.y());
446 523
447 transform.Translate(node->source_to_parent.x() - node->scroll_offset.x() + 524 transform.Translate(node->source_to_parent.x() - node->scroll_offset.x() +
448 fixed_position_adjustment.x(), 525 fixed_position_adjustment.x(),
449 node->source_to_parent.y() - node->scroll_offset.y() + 526 node->source_to_parent.y() - node->scroll_offset.y() +
450 fixed_position_adjustment.y()); 527 fixed_position_adjustment.y());
451 transform.PreconcatTransform(node->local); 528 transform.PreconcatTransform(node->local);
452 transform.PreconcatTransform(node->pre_local); 529 transform.PreconcatTransform(node->pre_local);
530
531 transform.Translate(StickyPositionOffset(this, node));
ajuma 2016/09/08 22:08:54 I'd have expected this to happen a couple lines ea
flackr 2016/09/20 17:08:13 Good catch, this is a position effect and shouldn'
532
453 node->set_to_parent(transform); 533 node->set_to_parent(transform);
454 node->needs_local_transform_update = false; 534 node->needs_local_transform_update = false;
455 } 535 }
456 536
457 void TransformTree::UpdateScreenSpaceTransform(TransformNode* node, 537 void TransformTree::UpdateScreenSpaceTransform(TransformNode* node,
458 TransformNode* parent_node, 538 TransformNode* parent_node,
459 TransformNode* target_node) { 539 TransformNode* target_node) {
460 if (!parent_node) { 540 if (!parent_node) {
461 SetToScreen(node->id, node->to_parent); 541 SetToScreen(node->id, node->to_parent);
462 node->ancestors_are_invertible = true; 542 node->ancestors_are_invertible = true;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 device_scale_factor_ == other.device_scale_factor() && 832 device_scale_factor_ == other.device_scale_factor() &&
753 device_transform_scale_factor_ == 833 device_transform_scale_factor_ ==
754 other.device_transform_scale_factor() && 834 other.device_transform_scale_factor() &&
755 nodes_affected_by_inner_viewport_bounds_delta_ == 835 nodes_affected_by_inner_viewport_bounds_delta_ ==
756 other.nodes_affected_by_inner_viewport_bounds_delta() && 836 other.nodes_affected_by_inner_viewport_bounds_delta() &&
757 nodes_affected_by_outer_viewport_bounds_delta_ == 837 nodes_affected_by_outer_viewport_bounds_delta_ ==
758 other.nodes_affected_by_outer_viewport_bounds_delta() && 838 other.nodes_affected_by_outer_viewport_bounds_delta() &&
759 cached_data_ == other.cached_data(); 839 cached_data_ == other.cached_data();
760 } 840 }
761 841
842 StickyPositionNodeData* TransformTree::StickyPositionData(int node_id) {
843 TransformNode* node = Node(node_id);
844 int sticky_data_id = node->sticky_position_constraint_id;
845 if (sticky_data_id == -1) {
846 if (!sticky_position_data_free_ids_.empty()) {
847 sticky_data_id = sticky_position_data_free_ids_.back();
848 sticky_position_data_free_ids_.pop_back();
849 } else {
850 sticky_data_id = sticky_position_data_.size();
851 sticky_position_data_.push_back(StickyPositionNodeData());
852 }
853 node->sticky_position_constraint_id = sticky_data_id;
854 }
855 return &sticky_position_data_[sticky_data_id];
856 }
857
858 void TransformTree::SetNotSticky(int node_id) {
859 TransformNode* node = Node(node_id);
860 int sticky_data_id = node->sticky_position_constraint_id;
861 if (sticky_data_id == -1)
862 return;
863 sticky_position_data_free_ids_.push_back(sticky_data_id);
flackr 2016/09/08 17:52:30 I'm not sure if we always rebuild the tree when st
ajuma 2016/09/08 22:08:54 Since Layer::SetStickyPositionConstraint calls Set
flackr 2016/09/20 17:08:13 Done. I agree, I expect sticky / not sticky change
864 node->sticky_position_constraint_id = -1;
865 }
866
762 void TransformTree::ToProtobuf(proto::PropertyTree* proto) const { 867 void TransformTree::ToProtobuf(proto::PropertyTree* proto) const {
flackr 2016/09/08 17:52:30 When is this used? Will the sticky position data n
ajuma 2016/09/08 22:08:54 This was added for Blimp, though currently they do
flackr 2016/09/20 17:08:13 Done.
763 DCHECK(!proto->has_property_type()); 868 DCHECK(!proto->has_property_type());
764 proto->set_property_type(proto::PropertyTree::Transform); 869 proto->set_property_type(proto::PropertyTree::Transform);
765 870
766 PropertyTree::ToProtobuf(proto); 871 PropertyTree::ToProtobuf(proto);
767 proto::TransformTreeData* data = proto->mutable_transform_tree_data(); 872 proto::TransformTreeData* data = proto->mutable_transform_tree_data();
768 873
769 data->set_source_to_parent_updates_allowed(source_to_parent_updates_allowed_); 874 data->set_source_to_parent_updates_allowed(source_to_parent_updates_allowed_);
770 data->set_page_scale_factor(page_scale_factor_); 875 data->set_page_scale_factor(page_scale_factor_);
771 data->set_device_scale_factor(device_scale_factor_); 876 data->set_device_scale_factor(device_scale_factor_);
772 data->set_device_transform_scale_factor(device_transform_scale_factor_); 877 data->set_device_transform_scale_factor(device_transform_scale_factor_);
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 from_target.ConcatTransform(draw_transforms.from_target); 2336 from_target.ConcatTransform(draw_transforms.from_target);
2232 from_target.Scale(effect_node->surface_contents_scale.x(), 2337 from_target.Scale(effect_node->surface_contents_scale.x(),
2233 effect_node->surface_contents_scale.y()); 2338 effect_node->surface_contents_scale.y());
2234 DCHECK(from_target.ApproximatelyEqual(*transform) || 2339 DCHECK(from_target.ApproximatelyEqual(*transform) ||
2235 !draw_transforms.invertible); 2340 !draw_transforms.invertible);
2236 } 2341 }
2237 return success; 2342 return success;
2238 } 2343 }
2239 2344
2240 } // namespace cc 2345 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698