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

Unified Diff: cc/trees/property_tree.cc

Issue 816543004: Update from https://crrev.com/308996 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years 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.h » ('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
new file mode 100644
index 0000000000000000000000000000000000000000..95c2b5a7730b570330e9d346cf42e8c241799fbf
--- /dev/null
+++ b/cc/trees/property_tree.cc
@@ -0,0 +1,199 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+
+#include "base/logging.h"
+#include "cc/trees/property_tree.h"
+
+namespace cc {
+
+template <typename T>
+PropertyTree<T>::PropertyTree() {
+ nodes_.push_back(T());
+ back()->id = 0;
+ back()->parent_id = -1;
+}
+
+template <typename T>
+PropertyTree<T>::~PropertyTree() {
+}
+
+template <typename T>
+int PropertyTree<T>::Insert(const T& tree_node, int parent_id) {
+ DCHECK_GT(nodes_.size(), 0u);
+ nodes_.push_back(tree_node);
+ T& node = nodes_.back();
+ node.parent_id = parent_id;
+ node.id = static_cast<int>(nodes_.size()) - 1;
+ return node.id;
+}
+
+template class PropertyTree<TransformNode>;
+template class PropertyTree<ClipNode>;
+
+TransformNodeData::TransformNodeData()
+ : target_id(-1),
+ is_invertible(true),
+ ancestors_are_invertible(true),
+ is_animated(false),
+ to_screen_is_animated(false),
+ flattens(false) {
+}
+
+TransformNodeData::~TransformNodeData() {
+}
+
+ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) {
+}
+
+bool TransformTree::ComputeTransform(int source_id,
+ int dest_id,
+ gfx::Transform* transform) const {
+ transform->MakeIdentity();
+
+ if (source_id == dest_id)
+ return true;
+
+ if (source_id > dest_id && IsDescendant(source_id, dest_id))
+ return CombineTransformsBetween(source_id, dest_id, transform);
+
+ if (dest_id > source_id && IsDescendant(dest_id, source_id))
+ return CombineInversesBetween(source_id, dest_id, transform);
+
+ int lca = LowestCommonAncestor(source_id, dest_id);
+
+ bool no_singular_matrices_to_lca =
+ CombineTransformsBetween(source_id, lca, transform);
+
+ bool no_singular_matrices_from_lca =
+ CombineInversesBetween(lca, dest_id, transform);
+
+ return no_singular_matrices_to_lca && no_singular_matrices_from_lca;
+}
+
+bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const {
+ gfx::Transform transform;
+ return ComputeTransform(source_id, dest_id, &transform) &&
+ 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;
+ }
+}
+
+bool TransformTree::IsDescendant(int desc_id, int source_id) const {
+ while (desc_id != source_id) {
+ if (desc_id < 0)
+ return false;
+ desc_id = Node(desc_id)->parent_id;
+ }
+ return true;
+}
+
+int TransformTree::LowestCommonAncestor(int a, int b) const {
+ std::set<int> chain_a;
+ std::set<int> chain_b;
+ while (a || b) {
+ if (a) {
+ a = Node(a)->parent_id;
+ if (a > -1 && chain_b.find(a) != chain_b.end())
+ return a;
+ chain_a.insert(a);
+ }
+ if (b) {
+ b = Node(b)->parent_id;
+ if (b > -1 && chain_a.find(b) != chain_a.end())
+ return b;
+ chain_b.insert(b);
+ }
+ }
+ NOTREACHED();
+ return 0;
+}
+
+bool TransformTree::CombineTransformsBetween(int source_id,
+ int dest_id,
+ gfx::Transform* transform) const {
+ const TransformNode* current = Node(source_id);
+ const TransformNode* dest = Node(dest_id);
+ if (!dest || dest->data.ancestors_are_invertible) {
+ transform->ConcatTransform(current->data.to_screen);
+ if (dest)
+ transform->ConcatTransform(dest->data.from_screen);
+ return true;
+ }
+
+ bool all_are_invertible = true;
+ for (; current && current->id > dest_id; current = parent(current)) {
+ transform->ConcatTransform(current->data.to_parent);
+ if (!current->data.is_invertible)
+ all_are_invertible = false;
+ }
+
+ return all_are_invertible;
+}
+
+bool TransformTree::CombineInversesBetween(int source_id,
+ int dest_id,
+ gfx::Transform* transform) const {
+ const TransformNode* current = Node(dest_id);
+ const TransformNode* dest = Node(source_id);
+ if (current->data.ancestors_are_invertible) {
+ transform->PreconcatTransform(current->data.from_screen);
+ if (dest)
+ transform->PreconcatTransform(dest->data.to_screen);
+ return true;
+ }
+
+ bool all_are_invertible = true;
+ for (; current && current->id > source_id; current = parent(current)) {
+ transform->PreconcatTransform(current->data.from_parent);
+ if (!current->data.is_invertible)
+ all_are_invertible = false;
+ }
+
+ return all_are_invertible;
+}
+
+} // namespace cc
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698