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

Unified Diff: cc/trees/property_tree.cc

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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 95c2b5a7730b570330e9d346cf42e8c241799fbf..25d42aad7451c90e13b3eddfa1f38cd86172076a 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -5,6 +5,7 @@
#include <set>
#include "base/logging.h"
+#include "cc/base/math_util.h"
#include "cc/trees/property_tree.h"
namespace cc {
@@ -35,11 +36,16 @@ template class PropertyTree<ClipNode>;
TransformNodeData::TransformNodeData()
: target_id(-1),
+ content_target_id(-1),
+ needs_local_transform_update(true),
is_invertible(true),
ancestors_are_invertible(true),
is_animated(false),
to_screen_is_animated(false),
- flattens(false) {
+ flattens(false),
+ scrolls(false),
+ needs_sublayer_scale(false),
+ layer_scale_factor(1.0f) {
}
TransformNodeData::~TransformNodeData() {
@@ -79,47 +85,18 @@ bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const {
transform.Preserves2dAxisAlignment();
}
-void TransformTree::UpdateScreenSpaceTransform(int id) {
- TransformNode* current_node = Node(id);
- TransformNode* parent_node = parent(current_node);
- TransformNode* target_node = Node(current_node->data.target_id);
-
- if (!parent_node) {
- current_node->data.to_screen = current_node->data.to_parent;
- current_node->data.ancestors_are_invertible = true;
- current_node->data.to_screen_is_animated = false;
- } else if (parent_node->data.flattens) {
- // Flattening is tricky. Once a layer is drawn into its render target, it
- // cannot escape, so we only need to consider transforms between the layer
- // and its target when flattening (i.e., its draw transform). To compute the
- // screen space transform when flattening is involved we combine three
- // transforms, A * B * C, where A is the screen space transform of the
- // target, B is the flattened draw transform of the layer's parent, and C is
- // the local transform.
- current_node->data.to_screen = target_node->data.to_screen;
- gfx::Transform flattened;
- ComputeTransform(parent_node->id, target_node->id, &flattened);
- flattened.FlattenTo2d();
- current_node->data.to_screen.PreconcatTransform(flattened);
- current_node->data.to_screen.PreconcatTransform(
- current_node->data.to_parent);
- current_node->data.ancestors_are_invertible =
- parent_node->data.ancestors_are_invertible;
- } else {
- current_node->data.to_screen = parent_node->data.to_screen;
- current_node->data.to_screen.PreconcatTransform(
- current_node->data.to_parent);
- current_node->data.ancestors_are_invertible =
- parent_node->data.ancestors_are_invertible;
- }
- if (!current_node->data.to_screen.GetInverse(&current_node->data.from_screen))
- current_node->data.ancestors_are_invertible = false;
-
- if (parent_node) {
- current_node->data.to_screen_is_animated =
- current_node->data.is_animated ||
- parent_node->data.to_screen_is_animated;
- }
+void TransformTree::UpdateTransforms(int id) {
+ TransformNode* node = Node(id);
+ TransformNode* parent_node = parent(node);
+ TransformNode* target_node = Node(node->data.target_id);
+ if (node->data.needs_local_transform_update)
+ UpdateLocalTransform(node);
+ UpdateLocalTransform(node);
+ UpdateScreenSpaceTransform(node, parent_node, target_node);
+ UpdateSublayerScale(node);
+ UpdateTargetSpaceTransform(node, target_node);
+ UpdateIsAnimated(node, parent_node);
+ UpdateSnapping(node);
}
bool TransformTree::IsDescendant(int desc_id, int source_id) const {
@@ -196,4 +173,123 @@ bool TransformTree::CombineInversesBetween(int source_id,
return all_are_invertible;
}
+void TransformTree::UpdateLocalTransform(TransformNode* node) {
+ gfx::Transform transform = node->data.post_local;
+ transform.Translate(-node->data.scroll_offset.x(),
+ -node->data.scroll_offset.y());
+ transform.PreconcatTransform(node->data.local);
+ transform.PreconcatTransform(node->data.pre_local);
+ node->data.set_to_parent(transform);
+ node->data.needs_local_transform_update = false;
+}
+
+void TransformTree::UpdateScreenSpaceTransform(TransformNode* node,
+ TransformNode* parent_node,
+ TransformNode* target_node) {
+ if (!parent_node) {
+ node->data.to_screen = node->data.to_parent;
+ node->data.ancestors_are_invertible = true;
+ node->data.to_screen_is_animated = false;
+ } else if (parent_node->data.flattens) {
+ // Flattening is tricky. Once a layer is drawn into its render target, it
+ // cannot escape, so we only need to consider transforms between the layer
+ // and its target when flattening (i.e., its draw transform). To compute the
+ // screen space transform when flattening is involved we combine three
+ // transforms, A * B * C, where A is the screen space transform of the
+ // target, B is the flattened draw transform of the layer's parent, and C is
+ // the local transform.
+ node->data.to_screen = target_node->data.to_screen;
+ gfx::Transform flattened;
+ ComputeTransform(parent_node->id, target_node->id, &flattened);
+ flattened.FlattenTo2d();
+ node->data.to_screen.PreconcatTransform(flattened);
+ node->data.to_screen.PreconcatTransform(node->data.to_parent);
+ node->data.ancestors_are_invertible =
+ parent_node->data.ancestors_are_invertible;
+ } else {
+ node->data.to_screen = parent_node->data.to_screen;
+ node->data.to_screen.PreconcatTransform(node->data.to_parent);
+ node->data.ancestors_are_invertible =
+ parent_node->data.ancestors_are_invertible;
+ }
+
+ if (!node->data.to_screen.GetInverse(&node->data.from_screen))
+ node->data.ancestors_are_invertible = false;
+}
+
+void TransformTree::UpdateSublayerScale(TransformNode* node) {
+ // The sublayer scale depends on the screen space transform, so update it too.
+ node->data.sublayer_scale =
+ node->data.needs_sublayer_scale
+ ? MathUtil::ComputeTransform2dScaleComponents(
+ node->data.to_screen, node->data.layer_scale_factor)
+ : gfx::Vector2dF(1.0f, 1.0f);
+}
+
+void TransformTree::UpdateTargetSpaceTransform(TransformNode* node,
+ TransformNode* target_node) {
+ node->data.to_target.MakeIdentity();
+ if (node->data.needs_sublayer_scale) {
+ node->data.to_target.Scale(node->data.sublayer_scale.x(),
+ node->data.sublayer_scale.y());
+ } else {
+ const bool target_is_root_surface = target_node->id == 1;
+ // In order to include the root transform for the root surface, we walk up
+ // to the root of the transform tree in ComputeTransform.
+ int target_id = target_is_root_surface ? 0 : target_node->id;
+ if (target_node) {
+ node->data.to_target.Scale(target_node->data.sublayer_scale.x(),
+ target_node->data.sublayer_scale.y());
+ }
+
+ gfx::Transform unscaled_target_transform;
+ ComputeTransform(node->id, target_id, &unscaled_target_transform);
+ node->data.to_target.PreconcatTransform(unscaled_target_transform);
+ }
+
+ if (!node->data.to_target.GetInverse(&node->data.from_target))
+ node->data.ancestors_are_invertible = false;
+}
+
+void TransformTree::UpdateIsAnimated(TransformNode* node,
+ TransformNode* parent_node) {
+ if (parent_node) {
+ node->data.to_screen_is_animated =
+ node->data.is_animated || parent_node->data.to_screen_is_animated;
+ }
+}
+
+void TransformTree::UpdateSnapping(TransformNode* node) {
+ if (!node->data.scrolls || node->data.to_screen_is_animated ||
+ !node->data.to_target.IsScaleOrTranslation()) {
+ return;
+ }
+
+ // Scroll snapping must be done in target space (the pixels we care about).
+ // This means we effectively snap the target space transform. If TT is the
+ // target space transform and TT' is TT with its translation components
+ // rounded, then what we're after is the scroll delta X, where TT * X = TT'.
+ // I.e., we want a transform that will realize our scroll snap. It follows
+ // that X = TT^-1 * TT'. We cache TT and TT^-1 to make this more efficient.
+ gfx::Transform rounded = node->data.to_target;
+ rounded.RoundTranslationComponents();
+ gfx::Transform delta = node->data.from_target;
+ delta *= rounded;
+ gfx::Transform inverse_delta(gfx::Transform::kSkipInitialization);
+ bool invertible_delta = delta.GetInverse(&inverse_delta);
+
+ // The delta should be a translation, modulo floating point error, and should
+ // therefore be invertible.
+ DCHECK(invertible_delta);
+
+ // Now that we have our scroll delta, we must apply it to each of our
+ // combined, to/from matrices.
+ node->data.to_parent.PreconcatTransform(delta);
+ node->data.from_parent.ConcatTransform(inverse_delta);
+ node->data.to_target.PreconcatTransform(delta);
+ node->data.from_target.ConcatTransform(inverse_delta);
+ node->data.to_screen.PreconcatTransform(delta);
+ node->data.from_screen.ConcatTransform(inverse_delta);
+}
+
} // namespace cc
« 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