| Index: cc/trees/draw_property_utils.cc
|
| diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
|
| index 0e25f0687715978be833548261978ecd61da2438..9295d1aa5e4dddd588321c3edd2a9927a8a905a1 100644
|
| --- a/cc/trees/draw_property_utils.cc
|
| +++ b/cc/trees/draw_property_utils.cc
|
| @@ -8,6 +8,7 @@
|
|
|
| #include "cc/base/math_util.h"
|
| #include "cc/layers/layer.h"
|
| +#include "cc/layers/layer_impl.h"
|
| #include "cc/trees/property_tree.h"
|
| #include "cc/trees/property_tree_builder.h"
|
| #include "ui/gfx/geometry/rect_conversions.h"
|
| @@ -16,12 +17,13 @@ namespace cc {
|
|
|
| namespace {
|
|
|
| +template <typename LayerType>
|
| void CalculateVisibleRects(
|
| - const std::vector<Layer*>& layers_that_need_visible_rects,
|
| + const std::vector<LayerType*>& layers_that_need_visible_rects,
|
| const ClipTree& clip_tree,
|
| const TransformTree& transform_tree) {
|
| for (size_t i = 0; i < layers_that_need_visible_rects.size(); ++i) {
|
| - Layer* layer = layers_that_need_visible_rects[i];
|
| + LayerType* layer = layers_that_need_visible_rects[i];
|
|
|
| // TODO(ajuma): Compute content_scale rather than using it. Note that for
|
| // PictureLayer and PictureImageLayers, content_bounds == bounds and
|
| @@ -134,36 +136,43 @@ void CalculateVisibleRects(
|
| }
|
| }
|
|
|
| -static bool IsRootLayerOfNewRenderingContext(Layer* layer) {
|
| +template <typename LayerType>
|
| +static bool IsRootLayerOfNewRenderingContext(LayerType* layer) {
|
| if (layer->parent())
|
| return !layer->parent()->Is3dSorted() && layer->Is3dSorted();
|
| return layer->Is3dSorted();
|
| }
|
|
|
| -static inline bool LayerIsInExisting3DRenderingContext(Layer* layer) {
|
| +template <typename LayerType>
|
| +static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) {
|
| return layer->Is3dSorted() && layer->parent() &&
|
| layer->parent()->Is3dSorted();
|
| }
|
|
|
| -static bool TransformToScreenIsKnown(Layer* layer, const TransformTree& tree) {
|
| +template <typename LayerType>
|
| +static bool TransformToScreenIsKnown(LayerType* layer,
|
| + const TransformTree& tree) {
|
| const TransformNode* node = tree.Node(layer->transform_tree_index());
|
| return !node->data.to_screen_is_animated;
|
| }
|
|
|
| -static bool IsLayerBackFaceExposed(Layer* layer, const TransformTree& tree) {
|
| +template <typename LayerType>
|
| +static bool IsLayerBackFaceExposed(LayerType* layer,
|
| + const TransformTree& tree) {
|
| if (!TransformToScreenIsKnown(layer, tree))
|
| return false;
|
| if (LayerIsInExisting3DRenderingContext(layer))
|
| - return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible();
|
| + return DrawTransformFromPropertyTrees(layer, tree).IsBackFaceVisible();
|
| return layer->transform().IsBackFaceVisible();
|
| }
|
|
|
| -static bool IsSurfaceBackFaceExposed(Layer* layer,
|
| +template <typename LayerType>
|
| +static bool IsSurfaceBackFaceExposed(LayerType* layer,
|
| const TransformTree& tree) {
|
| if (!TransformToScreenIsKnown(layer, tree))
|
| return false;
|
| if (LayerIsInExisting3DRenderingContext(layer))
|
| - return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible();
|
| + return DrawTransformFromPropertyTrees(layer, tree).IsBackFaceVisible();
|
|
|
| if (IsRootLayerOfNewRenderingContext(layer))
|
| return layer->transform().IsBackFaceVisible();
|
| @@ -174,13 +183,15 @@ static bool IsSurfaceBackFaceExposed(Layer* layer,
|
| return false;
|
| }
|
|
|
| -static bool HasSingularTransform(Layer* layer, const TransformTree& tree) {
|
| +template <typename LayerType>
|
| +static bool HasSingularTransform(LayerType* layer, const TransformTree& tree) {
|
| const TransformNode* node = tree.Node(layer->transform_tree_index());
|
| return !node->data.is_invertible || !node->data.ancestors_are_invertible;
|
| }
|
|
|
| -static bool IsBackFaceInvisible(Layer* layer, const TransformTree& tree) {
|
| - Layer* backface_test_layer = layer;
|
| +template <typename LayerType>
|
| +static bool IsBackFaceInvisible(LayerType* layer, const TransformTree& tree) {
|
| + LayerType* backface_test_layer = layer;
|
| if (layer->use_parent_backface_visibility()) {
|
| DCHECK(layer->parent());
|
| DCHECK(!layer->parent()->use_parent_backface_visibility());
|
| @@ -190,25 +201,36 @@ static bool IsBackFaceInvisible(Layer* layer, const TransformTree& tree) {
|
| IsLayerBackFaceExposed(backface_test_layer, tree);
|
| }
|
|
|
| -static bool IsAnimatingTransformToScreen(Layer* layer,
|
| +template <typename LayerType>
|
| +static bool IsAnimatingTransformToScreen(LayerType* layer,
|
| const TransformTree& tree) {
|
| const TransformNode* node = tree.Node(layer->transform_tree_index());
|
| return node->data.to_screen_is_animated;
|
| }
|
|
|
| -static bool IsInvisibleDueToTransform(Layer* layer, const TransformTree& tree) {
|
| +template <typename LayerType>
|
| +static bool IsInvisibleDueToTransform(LayerType* layer,
|
| + const TransformTree& tree) {
|
| if (IsAnimatingTransformToScreen(layer, tree))
|
| return false;
|
| return HasSingularTransform(layer, tree) || IsBackFaceInvisible(layer, tree);
|
| }
|
|
|
| -void FindLayersThatNeedVisibleRects(Layer* layer,
|
| +bool LayerIsInvisible(const Layer* layer) {
|
| + return !layer->opacity() && !layer->OpacityIsAnimating() &&
|
| + !layer->OpacityCanAnimateOnImplThread();
|
| +}
|
| +
|
| +bool LayerIsInvisible(const LayerImpl* layer) {
|
| + return !layer->opacity() && !layer->OpacityIsAnimating();
|
| +}
|
| +
|
| +template <typename LayerType>
|
| +void FindLayersThatNeedVisibleRects(LayerType* layer,
|
| const TransformTree& tree,
|
| bool subtree_is_visible_from_ancestor,
|
| - std::vector<Layer*>* layers_to_update) {
|
| - const bool layer_is_invisible =
|
| - (!layer->opacity() && !layer->OpacityIsAnimating() &&
|
| - !layer->OpacityCanAnimateOnImplThread());
|
| + std::vector<LayerType*>* layers_to_update) {
|
| + const bool layer_is_invisible = LayerIsInvisible(layer);
|
| const bool layer_is_backfacing =
|
| (layer->has_render_surface() && !layer->double_sided() &&
|
| IsSurfaceBackFaceExposed(layer, tree));
|
| @@ -228,9 +250,7 @@ void FindLayersThatNeedVisibleRects(Layer* layer,
|
| }
|
|
|
| for (size_t i = 0; i < layer->children().size(); ++i) {
|
| - FindLayersThatNeedVisibleRects(layer->children()[i].get(),
|
| - tree,
|
| - layer_is_drawn,
|
| + FindLayersThatNeedVisibleRects(layer->child_at(i), tree, layer_is_drawn,
|
| layers_to_update);
|
| }
|
| }
|
| @@ -326,7 +346,23 @@ void ComputeTransforms(TransformTree* transform_tree) {
|
| transform_tree->UpdateTransforms(i);
|
| }
|
|
|
| -void ComputeVisibleRectsUsingPropertyTrees(
|
| +template <typename LayerType>
|
| +void ComputeVisibleRectsUsingPropertyTreesInternal(
|
| + LayerType* root_layer,
|
| + PropertyTrees* property_trees) {
|
| + ComputeTransforms(&property_trees->transform_tree);
|
| + ComputeClips(&property_trees->clip_tree, property_trees->transform_tree);
|
| +
|
| + std::vector<LayerType*> layers_to_update;
|
| + const bool subtree_is_visible_from_ancestor = true;
|
| + FindLayersThatNeedVisibleRects(root_layer, property_trees->transform_tree,
|
| + subtree_is_visible_from_ancestor,
|
| + &layers_to_update);
|
| + CalculateVisibleRects(layers_to_update, property_trees->clip_tree,
|
| + property_trees->transform_tree);
|
| +}
|
| +
|
| +void BuildPropertyTreesAndComputeVisibleRects(
|
| Layer* root_layer,
|
| const Layer* page_scale_layer,
|
| float page_scale_factor,
|
| @@ -337,16 +373,145 @@ void ComputeVisibleRectsUsingPropertyTrees(
|
| PropertyTreeBuilder::BuildPropertyTrees(
|
| root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
|
| viewport, device_transform, property_trees);
|
| - ComputeTransforms(&property_trees->transform_tree);
|
| - ComputeClips(&property_trees->clip_tree, property_trees->transform_tree);
|
| + ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees);
|
| +}
|
|
|
| - std::vector<Layer*> layers_to_update;
|
| - const bool subtree_is_visible_from_ancestor = true;
|
| - FindLayersThatNeedVisibleRects(root_layer, property_trees->transform_tree,
|
| - subtree_is_visible_from_ancestor,
|
| - &layers_to_update);
|
| - CalculateVisibleRects(layers_to_update, property_trees->clip_tree,
|
| - property_trees->transform_tree);
|
| +void BuildPropertyTreesAndComputeVisibleRects(
|
| + LayerImpl* root_layer,
|
| + const LayerImpl* page_scale_layer,
|
| + float page_scale_factor,
|
| + float device_scale_factor,
|
| + const gfx::Rect& viewport,
|
| + const gfx::Transform& device_transform,
|
| + PropertyTrees* property_trees) {
|
| + PropertyTreeBuilder::BuildPropertyTrees(
|
| + root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
|
| + viewport, device_transform, property_trees);
|
| + ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees);
|
| +}
|
| +
|
| +void ComputeVisibleRectsUsingPropertyTrees(Layer* root_layer,
|
| + PropertyTrees* property_trees) {
|
| + ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees);
|
| +}
|
| +
|
| +void ComputeVisibleRectsUsingPropertyTrees(LayerImpl* root_layer,
|
| + PropertyTrees* property_trees) {
|
| + ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees);
|
| +}
|
| +
|
| +template <typename LayerType>
|
| +gfx::Transform DrawTransformFromPropertyTreesInternal(
|
| + const LayerType* layer,
|
| + const TransformTree& tree) {
|
| + const TransformNode* node = tree.Node(layer->transform_tree_index());
|
| + // TODO(vollick): ultimately we'll need to find this information (whether or
|
| + // not we establish a render surface) somewhere other than the layer.
|
| + const TransformNode* target_node =
|
| + layer->render_surface() ? node : tree.Node(node->data.content_target_id);
|
| +
|
| + gfx::Transform xform;
|
| + const bool owns_non_root_surface = layer->parent() && layer->render_surface();
|
| + if (!owns_non_root_surface) {
|
| + // If you're not the root, or you don't own a surface, you need to apply
|
| + // your local offset.
|
| + xform = node->data.to_target;
|
| + if (layer->should_flatten_transform_from_property_tree())
|
| + xform.FlattenTo2d();
|
| + xform.Translate(layer->offset_to_transform_parent().x(),
|
| + layer->offset_to_transform_parent().y());
|
| + // A fixed-position layer does not necessarily have the same render target
|
| + // as its transform node. In particular, its transform node may be an
|
| + // ancestor of its render target's transform node. For example, given layer
|
| + // tree R->S->F, suppose F is fixed and S owns a render surface (e.g., say S
|
| + // has opacity 0.9 and both S and F draw content). Then F's transform node
|
| + // is the root node, so the target space transform from that node is defined
|
| + // with respect to the root render surface. But F will render to S's
|
| + // surface, so must apply a change of basis transform to the target space
|
| + // transform from its transform node.
|
| + if (layer->position_constraint().is_fixed_position()) {
|
| + gfx::Transform tree_target_to_render_target;
|
| + tree.ComputeTransform(node->data.content_target_id,
|
| + layer->render_target()->transform_tree_index(),
|
| + &tree_target_to_render_target);
|
| + xform.ConcatTransform(tree_target_to_render_target);
|
| + }
|
| + } else {
|
| + // Surfaces need to apply their sublayer scale.
|
| + xform.Scale(target_node->data.sublayer_scale.x(),
|
| + target_node->data.sublayer_scale.y());
|
| + }
|
| + xform.Scale(1.0 / layer->contents_scale_x(), 1.0 / layer->contents_scale_y());
|
| + return xform;
|
| +}
|
| +
|
| +gfx::Transform DrawTransformFromPropertyTrees(const Layer* layer,
|
| + const TransformTree& tree) {
|
| + return DrawTransformFromPropertyTreesInternal(layer, tree);
|
| +}
|
| +
|
| +gfx::Transform DrawTransformFromPropertyTrees(const LayerImpl* layer,
|
| + const TransformTree& tree) {
|
| + return DrawTransformFromPropertyTreesInternal(layer, tree);
|
| +}
|
| +
|
| +template <typename LayerType>
|
| +gfx::Transform ScreenSpaceTransformFromPropertyTreesInternal(
|
| + LayerType* layer,
|
| + const TransformTree& tree) {
|
| + gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(),
|
| + layer->offset_to_transform_parent().y());
|
| + if (layer->transform_tree_index() >= 0) {
|
| + gfx::Transform ssxform =
|
| + tree.Node(layer->transform_tree_index())->data.to_screen;
|
| + xform.ConcatTransform(ssxform);
|
| + if (layer->should_flatten_transform_from_property_tree())
|
| + xform.FlattenTo2d();
|
| + }
|
| + xform.Scale(1.0 / layer->contents_scale_x(), 1.0 / layer->contents_scale_y());
|
| + return xform;
|
| +}
|
| +
|
| +gfx::Transform ScreenSpaceTransformFromPropertyTrees(
|
| + const Layer* layer,
|
| + const TransformTree& tree) {
|
| + return ScreenSpaceTransformFromPropertyTreesInternal(layer, tree);
|
| +}
|
| +
|
| +gfx::Transform ScreenSpaceTransformFromPropertyTrees(
|
| + const LayerImpl* layer,
|
| + const TransformTree& tree) {
|
| + return ScreenSpaceTransformFromPropertyTreesInternal(layer, tree);
|
| +}
|
| +
|
| +template <typename LayerType>
|
| +float DrawOpacityFromPropertyTreesInternal(LayerType layer,
|
| + const OpacityTree& tree) {
|
| + if (!layer->render_target())
|
| + return 0.f;
|
| +
|
| + const OpacityNode* target_node =
|
| + tree.Node(layer->render_target()->opacity_tree_index());
|
| + const OpacityNode* node = tree.Node(layer->opacity_tree_index());
|
| + if (node == target_node)
|
| + return 1.f;
|
| +
|
| + float draw_opacity = 1.f;
|
| + while (node != target_node) {
|
| + draw_opacity *= node->data;
|
| + node = tree.parent(node);
|
| + }
|
| + return draw_opacity;
|
| +}
|
| +
|
| +float DrawOpacityFromPropertyTrees(const Layer* layer,
|
| + const OpacityTree& tree) {
|
| + return DrawOpacityFromPropertyTreesInternal(layer, tree);
|
| +}
|
| +
|
| +float DrawOpacityFromPropertyTrees(const LayerImpl* layer,
|
| + const OpacityTree& tree) {
|
| + return DrawOpacityFromPropertyTreesInternal(layer, tree);
|
| }
|
|
|
| } // namespace cc
|
|
|