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

Unified Diff: cc/trees/layer_tree_host_common.cc

Issue 12552004: Support bottom-right anchored fixed-position elements during a pinch gesture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: forgot to save the comments. sorry. :( Created 7 years, 9 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/layers/layer_position_constraint_unittest.cc ('k') | cc/trees/layer_tree_host_common_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/layer_tree_host_common.cc
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index e1258b05af0863d3b648fb1b37a3acadfa25722a..7a552d8a5014ccfaf8caeaa674cfb2dfa4bddb70 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -342,6 +342,120 @@ static bool SubtreeShouldRenderToSeparateSurface(
return false;
}
+static LayerImpl* NextTargetSurface(LayerImpl* layer) {
+ return layer->parent() ? layer->parent()->render_target() : 0;
+}
+
+// This function returns a translation matrix that can be applied on a vector
+// that's in the layer's target surface coordinate, while the position offset is
+// specified in some ancestor layer's coordinate.
+gfx::Transform ComputeSizeDeltaCompensation(
+ LayerImpl* layer,
+ LayerImpl* container,
+ const gfx::Vector2dF& position_offset) {
+ gfx::Transform result_transform;
+
+ // To apply a translate in the container's layer space,
+ // the following steps need to be done:
+ // Step 1a. transform from target surface space to the container's target
+ // surface space
+ // Step 1b. transform from container's target surface space to the
+ // container's layer space
+ // Step 2. apply the compensation
+ // Step 3. transform back to target surface space
+
+ gfx::Transform target_surface_space_to_container_layer_space;
+ // Calculate step 1a
+ LayerImpl* container_target_surface =
+ container ? container->render_target() : 0;
+ for (LayerImpl* current_target_surface = NextTargetSurface(layer);
+ current_target_surface &&
+ current_target_surface != container_target_surface;
+ current_target_surface = NextTargetSurface(current_target_surface)) {
+ // Note: Concat is used here to convert the result coordinate space from
+ // current render surface to the next render surface.
+ target_surface_space_to_container_layer_space.ConcatTransform(
+ current_target_surface->render_surface()->draw_transform());
+ }
+ // Calculate step 1b
+ if (container) {
+ gfx::Transform container_layer_space_to_container_target_surface_space =
+ container->draw_transform();
+ container_layer_space_to_container_target_surface_space.Scale(
+ container->contents_scale_x(), container->contents_scale_y());
+
+ gfx::Transform container_target_surface_space_to_container_layer_space;
+ if (container_layer_space_to_container_target_surface_space.GetInverse(
+ &container_target_surface_space_to_container_layer_space)) {
+ // Note: Again, Concat is used to conver the result coordinate space from
+ // the container render surface to the container layer.
+ target_surface_space_to_container_layer_space.ConcatTransform(
+ container_target_surface_space_to_container_layer_space);
+ }
+ }
+
+ // Apply step 3
+ gfx::Transform container_layer_space_to_target_surface_space;
+ if (target_surface_space_to_container_layer_space.GetInverse(
+ &container_layer_space_to_target_surface_space))
+ result_transform.PreconcatTransform(
+ container_layer_space_to_target_surface_space);
+ else {
+ // FIXME: A non-invertible matrix could still make meaningful projection.
+ // For example ScaleZ(0) is non-invertible but the layer is still visible.
+ return gfx::Transform();
+ }
+
+ // Apply step 2
+ result_transform.Translate(position_offset.x(), position_offset.y());
+
+ // Apply step 1
+ result_transform.PreconcatTransform(
+ target_surface_space_to_container_layer_space);
+
+ return result_transform;
+}
+
+void ApplyPositionAdjustment(
+ Layer* layer,
+ Layer* container,
+ const gfx::Transform& scroll_compensation,
+ gfx::Transform* combined_transform) { }
+void ApplyPositionAdjustment(
+ LayerImpl* layer,
+ LayerImpl* container,
+ const gfx::Transform& scroll_compensation,
+ gfx::Transform* combined_transform)
+{
+ if (!layer->position_constraint().is_fixed_position())
+ return;
+
+ // Special case: this layer is a composited fixed-position layer; we need to
+ // explicitly compensate for all ancestors' nonzero scroll_deltas to keep
+ // this layer fixed correctly.
+ // Note carefully: this is Concat, not Preconcat
+ // (current_scroll_compensation * combined_transform).
+ combined_transform->ConcatTransform(scroll_compensation);
+
+ // For right-edge or bottom-edge anchored fixed position layers,
+ // the layer should relocate itself if the container changes its size.
+ bool fixed_to_right_edge =
+ layer->position_constraint().is_fixed_to_right_edge();
+ bool fixed_to_bottom_edge =
+ layer->position_constraint().is_fixed_to_bottom_edge();
+ gfx::Vector2dF position_offset =
+ container ? container->fixed_container_size_delta() : gfx::Vector2dF();
+ position_offset.set_x(fixed_to_right_edge ? position_offset.x() : 0);
+ position_offset.set_y(fixed_to_bottom_edge ? position_offset.y() : 0);
+ if (position_offset.IsZero())
+ return;
+
+ // Note: Again, this is Concat. The compensation matrix will be applied on
+ // the vector in target surface space.
+ combined_transform->ConcatTransform(
+ ComputeSizeDeltaCompensation(layer, container, position_offset));
+}
+
gfx::Transform ComputeScrollCompensationForThisLayer(
LayerImpl* scrolling_layer,
const gfx::Transform& parent_matrix) {
@@ -425,7 +539,7 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
// Avoid the overheads (including stack allocation and matrix
// initialization/copy) if we know that the scroll compensation doesn't need
// to be reset or adjusted.
- if (!layer->is_container_for_fixed_position_layers() &&
+ if (!layer->IsContainerForFixedPositionLayers() &&
layer->scroll_delta().IsZero() && !layer->render_surface())
return current_scroll_compensation_matrix;
@@ -434,7 +548,7 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
// If this layer is not a container, then it inherits the existing scroll
// compensations.
- if (!layer->is_container_for_fixed_position_layers())
+ if (!layer->IsContainerForFixedPositionLayers())
next_scroll_compensation_matrix = current_scroll_compensation_matrix;
// If the current layer has a non-zero scroll_delta, then we should compute
@@ -636,6 +750,7 @@ static void CalculateDrawPropertiesInternal(
const gfx::Transform& parent_matrix,
const gfx::Transform& full_hierarchy_matrix,
const gfx::Transform& current_scroll_compensation_matrix,
+ LayerType* current_fixed_container,
gfx::Rect clip_rect_from_ancestor,
gfx::Rect clip_rect_from_ancestor_in_descendant_space,
bool ancestor_clips_subtree,
@@ -859,14 +974,9 @@ static void CalculateDrawPropertiesInternal(
RoundTranslationComponents(&combined_transform);
}
- if (layer->fixed_to_container_layer()) {
- // Special case: this layer is a composited fixed-position layer; we need to
- // explicitly compensate for all ancestors' nonzero scroll_deltas to keep
- // this layer fixed correctly.
- // Note carefully: this is Concat, not Preconcat
- // (current_scroll_compensation * combined_transform).
- combined_transform.ConcatTransform(current_scroll_compensation_matrix);
- }
+ // Apply adjustment from position constraints.
+ ApplyPositionAdjustment(layer, current_fixed_container,
+ current_scroll_compensation_matrix, &combined_transform);
// The draw_transform that gets computed below is effectively the layer's
// draw_transform, unless the layer itself creates a render_surface. In that
@@ -1105,6 +1215,9 @@ static void CalculateDrawPropertiesInternal(
gfx::Transform next_scroll_compensation_matrix =
ComputeScrollCompensationMatrixForChildren(
layer, parent_matrix, current_scroll_compensation_matrix);
+ LayerType* next_fixed_container =
+ layer->IsContainerForFixedPositionLayers() ?
+ layer : current_fixed_container;
gfx::Rect accumulated_drawable_content_rect_of_children;
for (size_t i = 0; i < layer->children().size(); ++i) {
@@ -1116,6 +1229,7 @@ static void CalculateDrawPropertiesInternal(
sublayer_matrix,
next_hierarchy_matrix,
next_scroll_compensation_matrix,
+ next_fixed_container,
clip_rect_for_subtree,
clip_rect_for_subtree_in_descendant_space,
subtree_should_be_clipped,
@@ -1323,6 +1437,7 @@ void LayerTreeHostCommon::CalculateDrawProperties(
device_scale_transform,
identity_matrix,
identity_matrix,
+ NULL,
device_viewport_rect,
device_viewport_rect,
subtree_should_be_clipped,
@@ -1376,6 +1491,7 @@ void LayerTreeHostCommon::CalculateDrawProperties(
device_scale_transform,
identity_matrix,
identity_matrix,
+ NULL,
device_viewport_rect,
device_viewport_rect,
subtree_should_be_clipped,
« no previous file with comments | « cc/layers/layer_position_constraint_unittest.cc ('k') | cc/trees/layer_tree_host_common_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698