Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 CombineTransformsBetween(dest_id, source_id, &dest_to_source); | 339 CombineTransformsBetween(dest_id, source_id, &dest_to_source); |
| 340 gfx::Transform source_to_dest; | 340 gfx::Transform source_to_dest; |
| 341 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); | 341 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); |
| 342 transform->PreconcatTransform(source_to_dest); | 342 transform->PreconcatTransform(source_to_dest); |
| 343 return all_are_invertible; | 343 return all_are_invertible; |
| 344 } | 344 } |
| 345 | 345 |
| 346 gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { | 346 gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { |
| 347 if (node->sticky_position_constraint_id == -1) | 347 if (node->sticky_position_constraint_id == -1) |
| 348 return gfx::Vector2dF(); | 348 return gfx::Vector2dF(); |
| 349 const StickyPositionNodeData* sticky_data = | 349 StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id); |
| 350 tree->StickyPositionData(node->id); | 350 LayerStickyPositionConstraint& constraint = sticky_data->constraints; |
| 351 const LayerStickyPositionConstraint& constraint = sticky_data->constraints; | |
| 352 ScrollNode* scroll_node = | 351 ScrollNode* scroll_node = |
| 353 tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); | 352 tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); |
| 354 gfx::ScrollOffset scroll_offset = | 353 gfx::ScrollOffset scroll_offset = |
| 355 tree->property_trees()->scroll_tree.current_scroll_offset( | 354 tree->property_trees()->scroll_tree.current_scroll_offset( |
| 356 scroll_node->owning_layer_id); | 355 scroll_node->owning_layer_id); |
| 357 gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); | 356 gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); |
| 358 TransformNode* scroll_ancestor_transform_node = | 357 TransformNode* scroll_ancestor_transform_node = |
| 359 tree->Node(scroll_node->transform_id); | 358 tree->Node(scroll_node->transform_id); |
| 360 if (scroll_ancestor_transform_node->scrolls) { | 359 if (scroll_ancestor_transform_node->scrolls) { |
| 361 // The scroll position does not include snapping which shifts the scroll | 360 // The scroll position does not include snapping which shifts the scroll |
| 362 // offset to align to a pixel boundary, we need to manually include it here. | 361 // offset to align to a pixel boundary, we need to manually include it here. |
| 363 // In this case, snapping is caused by a scroll. | 362 // In this case, snapping is caused by a scroll. |
| 364 scroll_position -= scroll_ancestor_transform_node->snap_amount; | 363 scroll_position -= scroll_ancestor_transform_node->snap_amount; |
| 365 } | 364 } |
| 366 | 365 |
| 367 gfx::RectF clip( | 366 gfx::RectF clip( |
| 368 scroll_position, | 367 scroll_position, |
| 369 gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( | 368 gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( |
| 370 scroll_node->id))); | 369 scroll_node->id))); |
| 371 gfx::Vector2dF sticky_offset( | 370 // TODO(smcgruer): This is very likely wrong, but the MTO seems wrong for |
| 372 constraint.scroll_container_relative_sticky_box_rect.OffsetFromOrigin()); | 371 // nested elements. For example, in https://output.jsbin.com/bovegil it |
| 373 gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); | 372 // is [0,30] for the outer (correct) but then [0,-50] for the middle and |
| 373 // [0,-25] for the inner (that seems wrong). | |
|
flackr
2017/02/02 18:18:11
Sounds like we need to update the way this is comp
smcgruer
2017/02/02 20:21:26
Is there any guarantee in CompositedLayerMapping::
flackr
2017/02/02 23:31:15
Yes, compositing inputs are clean at at that point
| |
| 374 LOG(INFO) << "Node " << node->id << ": main_thread_offset is " | |
| 375 << sticky_data->main_thread_offset.ToString(); | |
| 376 gfx::Vector2dF layer_offset; | |
| 377 if (!constraint.nearest_sticky_element_shifting_containing_block) | |
| 378 layer_offset = sticky_data->main_thread_offset; | |
| 374 | 379 |
| 375 // In each of the following cases, we measure the limit which is the point | 380 // In each of the following cases, we measure the limit which is the point |
| 376 // that the element should stick to, clamping on one side to 0 (because sticky | 381 // that the element should stick to, clamping on one side to 0 (because sticky |
| 377 // only pushes elements in one direction). Then we clamp to how far we can | 382 // only pushes elements in one direction). Then we clamp to how far we can |
| 378 // push the element in that direction without being pushed outside of its | 383 // push the element in that direction without being pushed outside of its |
| 379 // containing block. | 384 // containing block. |
| 380 // | 385 // |
| 381 // Note: The order of applying the sticky constraints is applied such that | 386 // Note: The order of applying the sticky constraints is applied such that |
| 382 // left offset takes precedence over right offset, and top takes precedence | 387 // left offset takes precedence over right offset, and top takes precedence |
| 383 // over bottom offset. | 388 // over bottom offset. |
| 389 | |
| 390 // TODO(smcgruer): I'm not sure why, but at points when scrolling this method | |
| 391 // is called with valid ancestor pointers *BUT* they have a | |
| 392 // transform_tree_index of -1. | |
|
flackr
2017/02/02 18:18:11
We can't access the Layers at this point, I believ
smcgruer
2017/02/02 20:21:26
Done.
| |
| 393 | |
| 394 gfx::Vector2dF ancestor_sticky_box_offset; | |
| 395 if (constraint.nearest_sticky_element_shifting_sticky_box && | |
| 396 constraint.nearest_sticky_element_shifting_sticky_box | |
| 397 ->transform_tree_index() >= 0) { | |
| 398 const StickyPositionNodeData* sticky_data = tree->StickyPositionData( | |
| 399 constraint.nearest_sticky_element_shifting_sticky_box | |
| 400 ->transform_tree_index()); | |
| 401 ancestor_sticky_box_offset = | |
| 402 sticky_data->constraint.total_sticky_box_sticky_offset; | |
| 403 } | |
| 404 | |
| 405 gfx::Vector2dF ancestor_containing_block_offset; | |
| 406 if (constraint.nearest_sticky_element_shifting_containing_block && | |
| 407 constraint.nearest_sticky_element_shifting_containing_block | |
| 408 ->transform_tree_index() >= 0) { | |
| 409 const StickyPositionNodeData* sticky_data = tree->StickyPositionData( | |
| 410 constraint.nearest_sticky_element_shifting_containing_block | |
| 411 ->transform_tree_index()); | |
| 412 ancestor_containing_block_offset = | |
| 413 sticky_data->constraint.total_containing_block_sticky_offset; | |
| 414 } | |
| 415 | |
| 416 gfx::Rect sticky_box_rect = | |
| 417 constraint.scroll_container_relative_sticky_box_rect; | |
| 418 gfx::Rect containing_block_rect = | |
| 419 constraint.scroll_container_relative_containing_block_rect; | |
| 420 sticky_box_rect.Offset(ancestor_sticky_box_offset.x(), | |
| 421 ancestor_sticky_box_offset.y()); | |
| 422 sticky_box_rect.Offset(ancestor_containing_block_offset.x(), | |
| 423 ancestor_containing_block_offset.y()); | |
| 424 containing_block_rect.Offset(ancestor_containing_block_offset.x(), | |
| 425 ancestor_containing_block_offset.y()); | |
| 426 | |
| 427 gfx::Vector2dF sticky_offset(sticky_box_rect.OffsetFromOrigin()); | |
| 428 | |
| 384 if (constraint.is_anchored_right) { | 429 if (constraint.is_anchored_right) { |
| 385 float right_limit = clip.right() - constraint.right_offset; | 430 float right_limit = clip.right() - constraint.right_offset; |
| 386 float right_delta = std::min<float>( | 431 float right_delta = |
| 387 0, right_limit - | 432 std::min<float>(0, right_limit - sticky_box_rect.right()); |
| 388 constraint.scroll_container_relative_sticky_box_rect.right()); | 433 float available_space = |
| 389 float available_space = std::min<float>( | 434 std::min<float>(0, containing_block_rect.x() - sticky_box_rect.x()); |
| 390 0, constraint.scroll_container_relative_containing_block_rect.x() - | |
| 391 constraint.scroll_container_relative_sticky_box_rect.x()); | |
| 392 if (right_delta < available_space) | 435 if (right_delta < available_space) |
| 393 right_delta = available_space; | 436 right_delta = available_space; |
| 394 sticky_offset.set_x(sticky_offset.x() + right_delta); | 437 sticky_offset.set_x(sticky_offset.x() + right_delta); |
| 395 } | 438 } |
| 396 if (constraint.is_anchored_left) { | 439 if (constraint.is_anchored_left) { |
| 397 float left_limit = clip.x() + constraint.left_offset; | 440 float left_limit = clip.x() + constraint.left_offset; |
| 398 float left_delta = std::max<float>( | 441 float left_delta = std::max<float>(0, left_limit - sticky_box_rect.x()); |
| 399 0, | |
| 400 left_limit - constraint.scroll_container_relative_sticky_box_rect.x()); | |
| 401 float available_space = std::max<float>( | 442 float available_space = std::max<float>( |
| 402 0, constraint.scroll_container_relative_containing_block_rect.right() - | 443 0, containing_block_rect.right() - sticky_box_rect.right()); |
| 403 constraint.scroll_container_relative_sticky_box_rect.right()); | |
| 404 if (left_delta > available_space) | 444 if (left_delta > available_space) |
| 405 left_delta = available_space; | 445 left_delta = available_space; |
| 406 sticky_offset.set_x(sticky_offset.x() + left_delta); | 446 sticky_offset.set_x(sticky_offset.x() + left_delta); |
| 407 } | 447 } |
| 408 if (constraint.is_anchored_bottom) { | 448 if (constraint.is_anchored_bottom) { |
| 409 float bottom_limit = clip.bottom() - constraint.bottom_offset; | 449 float bottom_limit = clip.bottom() - constraint.bottom_offset; |
| 410 float bottom_delta = std::min<float>( | 450 float bottom_delta = |
| 411 0, bottom_limit - | 451 std::min<float>(0, bottom_limit - sticky_box_rect.bottom()); |
| 412 constraint.scroll_container_relative_sticky_box_rect.bottom()); | 452 float available_space = |
| 413 float available_space = std::min<float>( | 453 std::min<float>(0, containing_block_rect.y() - sticky_box_rect.y()); |
| 414 0, constraint.scroll_container_relative_containing_block_rect.y() - | |
| 415 constraint.scroll_container_relative_sticky_box_rect.y()); | |
| 416 if (bottom_delta < available_space) | 454 if (bottom_delta < available_space) |
| 417 bottom_delta = available_space; | 455 bottom_delta = available_space; |
| 418 sticky_offset.set_y(sticky_offset.y() + bottom_delta); | 456 sticky_offset.set_y(sticky_offset.y() + bottom_delta); |
| 419 } | 457 } |
| 420 if (constraint.is_anchored_top) { | 458 if (constraint.is_anchored_top) { |
| 421 float top_limit = clip.y() + constraint.top_offset; | 459 float top_limit = clip.y() + constraint.top_offset; |
| 422 float top_delta = std::max<float>( | 460 float top_delta = std::max<float>(0, top_limit - sticky_box_rect.y()); |
| 423 0, | |
| 424 top_limit - constraint.scroll_container_relative_sticky_box_rect.y()); | |
| 425 float available_space = std::max<float>( | 461 float available_space = std::max<float>( |
| 426 0, constraint.scroll_container_relative_containing_block_rect.bottom() - | 462 0, containing_block_rect.bottom() - sticky_box_rect.bottom()); |
| 427 constraint.scroll_container_relative_sticky_box_rect.bottom()); | |
| 428 if (top_delta > available_space) | 463 if (top_delta > available_space) |
| 429 top_delta = available_space; | 464 top_delta = available_space; |
| 430 sticky_offset.set_y(sticky_offset.y() + top_delta); | 465 sticky_offset.set_y(sticky_offset.y() + top_delta); |
| 431 } | 466 } |
| 432 return sticky_offset - layer_offset - node->source_to_parent - | 467 |
| 433 constraint.scroll_container_relative_sticky_box_rect | 468 constraint.total_sticky_box_sticky_offset = |
| 434 .OffsetFromOrigin(); | 469 ancestor_sticky_box_offset + sticky_offset - |
| 470 sticky_box_rect.OffsetFromOrigin(); | |
| 471 constraint.total_containing_block_sticky_offset = | |
| 472 ancestor_containing_block_offset + sticky_offset - | |
| 473 sticky_box_rect.OffsetFromOrigin(); | |
| 474 | |
| 475 // TODO(smcgruer): Confusing bit here. With the current state of the code, the | |
| 476 // following values are returned for https://output.jsbin.com/bovegil : [0,0] | |
| 477 // for the outer, [0,0] for the middle, and [0,25] for the inner. That *seems* | |
| 478 // like the wrong value for the outer and the right value for the inner, but | |
| 479 // visually it is correct for outer and wrong for inner! (outer is offset | |
| 480 // correctly, inner is offset too far...). | |
|
flackr
2017/02/02 18:18:11
Keep in mind what we are returning is the addition
smcgruer
2017/02/02 20:21:26
Ah, makes sense.
| |
| 481 gfx::Vector2dF result(sticky_offset - layer_offset - node->source_to_parent - | |
| 482 sticky_box_rect.OffsetFromOrigin()); | |
| 483 LOG(INFO) << "Node " << node->id << ": result is " << result.ToString(); | |
| 484 return result; | |
| 435 } | 485 } |
| 436 | 486 |
| 437 void TransformTree::UpdateLocalTransform(TransformNode* node) { | 487 void TransformTree::UpdateLocalTransform(TransformNode* node) { |
| 438 gfx::Transform transform = node->post_local; | 488 gfx::Transform transform = node->post_local; |
| 439 if (NeedsSourceToParentUpdate(node)) { | 489 if (NeedsSourceToParentUpdate(node)) { |
| 440 gfx::Transform to_parent; | 490 gfx::Transform to_parent; |
| 441 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); | 491 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); |
| 442 gfx::Vector2dF unsnapping; | 492 gfx::Vector2dF unsnapping; |
| 443 TransformNode* current; | 493 TransformNode* current; |
| 444 TransformNode* parent_node; | 494 TransformNode* parent_node; |
| (...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2096 | 2146 |
| 2097 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2147 const EffectNode* effect_node = effect_tree.Node(effect_id); |
| 2098 | 2148 |
| 2099 bool success = GetFromTarget(transform_id, effect_id, transform); | 2149 bool success = GetFromTarget(transform_id, effect_id, transform); |
| 2100 transform->Scale(effect_node->surface_contents_scale.x(), | 2150 transform->Scale(effect_node->surface_contents_scale.x(), |
| 2101 effect_node->surface_contents_scale.y()); | 2151 effect_node->surface_contents_scale.y()); |
| 2102 return success; | 2152 return success; |
| 2103 } | 2153 } |
| 2104 | 2154 |
| 2105 } // namespace cc | 2155 } // namespace cc |
| OLD | NEW |