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

Unified Diff: cc/trees/draw_property_utils.cc

Issue 1800923002: cc: Directly use property trees to calculate clip rect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clean up and try Created 4 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 | « no previous file | cc/trees/property_tree.h » ('j') | cc/trees/property_tree.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/draw_property_utils.cc
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 38492034fbcf2188876566de70cb80cc055b96ae..cf4bb68f178eb9d4438f0757931d0f9868c0c85c 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -133,7 +133,6 @@ void CalculateVisibleRects(const std::vector<LayerType*>& visible_layer_list,
clip_to_target, clip_node->data.clip_in_target_space));
}
clip_rect_in_target_space = combined_clip_rect_in_target_space;
-
} else {
clip_rect_in_target_space =
gfx::ToEnclosingRect(clip_node->data.clip_in_target_space);
@@ -452,22 +451,27 @@ void FindLayersThatNeedUpdates(
template <typename LayerType>
void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree,
- LayerType* layer) {
+ LayerType* layer,
+ int target_id) {
EffectNode* node = effect_tree->Node(layer->effect_tree_index());
+ if (node->owner_id == layer->id())
+ node->data.target_id = target_id;
- if (node->owner_id == layer->id() && node->data.has_render_surface)
+ if (node->owner_id == layer->id() && node->data.has_render_surface) {
layer->SetHasRenderSurface(true);
- else
+ target_id = node->id;
+ } else {
layer->SetHasRenderSurface(false);
+ }
for (size_t i = 0; i < layer->children().size(); ++i) {
- UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(effect_tree,
- layer->child_at(i));
+ UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(
+ effect_tree, layer->child_at(i), target_id);
}
}
void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) {
- UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer);
+ UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer, 0);
}
void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) {
@@ -484,7 +488,8 @@ void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree,
if (!non_root_surfaces_enabled)
UpdateRenderSurfacesNonRootSurfacesDisabled(layer);
else
- UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer);
+ UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer,
+ 0);
}
} // namespace
@@ -649,6 +654,147 @@ void ComputeEffects(EffectTree* effect_tree) {
effect_tree->set_needs_update(false);
}
+static gfx::RectF ComputeCurrentClip(const ClipNode* clip_node,
+ const TransformTree& transform_tree,
+ int target_transform_id) {
+ if (clip_node->data.transform_id != target_transform_id) {
+ gfx::Transform current_to_target;
+ if (!transform_tree.ComputeTransformWithDestinationSublayerScale(
+ clip_node->data.transform_id, target_transform_id,
+ &current_to_target))
+ return gfx::RectF();
+ if (clip_node->data.transform_id > target_transform_id)
+ return MathUtil::MapClippedRect(current_to_target, clip_node->data.clip);
+ else
+ return MathUtil::ProjectClippedRect(current_to_target,
+ clip_node->data.clip);
+ } else {
+ gfx::RectF current_clip = clip_node->data.clip;
+ gfx::Vector2dF sublayer_scale =
+ transform_tree.Node(target_transform_id)->data.sublayer_scale;
+ if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) {
+ current_clip.Scale(sublayer_scale.x(), sublayer_scale.y());
+ }
+ return current_clip;
+ }
+ NOTREACHED();
+ return gfx::RectF();
+}
+
+static gfx::RectF ComputeAccumulatedClip(const ClipTree& clip_tree,
+ int local_clip_id,
+ const EffectTree& effect_tree,
+ int target_id,
+ const TransformTree& transform_tree) {
+ const ClipNode* clip_node = clip_tree.Node(local_clip_id);
+ const EffectNode* target_node = effect_tree.Node(target_id);
+ int target_transform_id = target_node->data.transform_id;
+ if (local_clip_id == target_node->data.clip_id)
ajuma 2016/03/15 14:59:56 This confused me for a bit since it seemed like th
weiliangc 2016/03/15 15:29:36 This is a special case I started with, but is no l
+ return ComputeCurrentClip(clip_tree.Node(local_clip_id), transform_tree,
+ target_transform_id);
+
+ // Collect all the clips that need to be accumulated.
+ std::stack<const ClipNode*> parent_chain;
+
+ // If target is not direct ancestor of clip, this will find least common
+ // ancestor between the target and the clip.
+ while (target_node->id >= 0 && clip_node->id >= 0) {
+ while (target_node->data.clip_id > clip_node->id ||
+ target_node->data.has_unclipped_descendants) {
+ target_node = effect_tree.Node(target_node->data.target_id);
+ }
+ if (target_node->data.clip_id == clip_node->id)
+ break;
+ while (target_node->data.clip_id < clip_node->id) {
+ parent_chain.push(clip_node);
+ clip_node = clip_tree.parent(clip_node);
+ }
+ if (target_node->data.clip_id == clip_node->id) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ break;
+ }
+ }
+
+ // TODO(weiliangc): If we don't create clip for render surface, we don't need
+ // to check applies_local_clip.
+ while (clip_node->id != 1 && !clip_node->data.applies_local_clip &&
+ parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ }
+
+ if (!clip_node->data.applies_local_clip && clip_node->id != 1)
+ return gfx::RectF();
+
+ gfx::RectF accumulated_clip =
+ ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
+
+ while (parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ if (!clip_node->data.applies_local_clip && clip_node->id != 1) {
ajuma 2016/03/15 14:59:56 Do we still need this special handling for the vie
weiliangc 2016/03/15 15:29:36 No, I realized viewport clip always applies local
+ continue;
+ }
+ gfx::RectF current_clip =
+ ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
+ accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip);
+ }
+
+ return accumulated_clip;
+}
+
+static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) {
+ EffectTree* effect_tree = &property_trees->effect_tree;
+ const ClipTree* clip_tree = &property_trees->clip_tree;
+ const TransformTree* transform_tree = &property_trees->transform_tree;
+ EffectNode* root_effect_node = effect_tree->Node(1);
+ root_effect_node->data.clip_rect = gfx::ToEnclosingRect(
+ clip_tree->Node(root_effect_node->data.clip_id)->data.clip);
+ for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) {
+ EffectNode* effect_node = effect_tree->Node(i);
+ const EffectNode* target_node =
+ effect_tree->Node(effect_node->data.target_id);
+ gfx::RectF accumulated_clip =
+ ComputeAccumulatedClip(*clip_tree, effect_node->data.clip_id,
+ *effect_tree, target_node->id, *transform_tree);
+
+ const ClipNode* clip_node = clip_tree->Node(effect_node->data.clip_id);
+ if (!clip_node->data.applies_local_clip &&
+ !effect_node->data.has_unclipped_descendants) {
+ CHECK(accumulated_clip == clip_node->data.clip_in_target_space);
+ }
+ effect_node->data.clip_rect = gfx::ToEnclosingRect(accumulated_clip);
+ }
+}
+
+static void ComputeLayerClipRect(const PropertyTrees* property_trees,
+ const LayerImpl* layer) {
+ const EffectTree* effect_tree = &property_trees->effect_tree;
+ const ClipTree* clip_tree = &property_trees->clip_tree;
+ const TransformTree* transform_tree = &property_trees->transform_tree;
+ const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index());
+ const EffectNode* target_node =
+ effect_node->data.has_render_surface
+ ? effect_node
+ : effect_tree->Node(effect_node->data.target_id);
+
+ gfx::RectF accumulated_clip =
+ ComputeAccumulatedClip(*clip_tree, layer->clip_tree_index(), *effect_tree,
+ target_node->id, *transform_tree);
+ if (!property_trees->non_root_surfaces_enabled ||
+ clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) {
+ CHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip))
+ << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index()
+ << " layer clip: " << layer->clip_rect().ToString() << " v.s. "
+ << gfx::ToEnclosingRect(accumulated_clip).ToString()
+ << " and clip node clip: "
+ << gfx::ToEnclosingRect(clip_tree->Node(layer->clip_tree_index())
+ ->data.clip_in_target_space)
+ .ToString();
+ }
+}
+
template <typename LayerType>
static void ComputeVisibleRectsInternal(
LayerType* root_layer,
@@ -742,10 +888,15 @@ void ComputeVisibleRects(LayerImpl* root_layer,
&property_trees->effect_tree, can_render_to_separate_surface, root_layer);
if (can_render_to_separate_surface)
ValidateRenderSurfaces(root_layer);
+ if (can_render_to_separate_surface)
+ ComputeClipsWithEffectTree(property_trees);
LayerImplList update_layer_list;
ComputeVisibleRectsInternal(root_layer, property_trees,
can_render_to_separate_surface,
&update_layer_list, visible_layer_list);
+ if (can_render_to_separate_surface)
+ for (auto layer : *visible_layer_list)
+ ComputeLayerClipRect(property_trees, layer);
}
template <typename LayerType>
@@ -800,6 +951,8 @@ static void SetSurfaceDrawTransform(const TransformTree& tree,
static void SetSurfaceIsClipped(const ClipNode* clip_node,
RenderSurfaceImpl* render_surface) {
+ DCHECK(render_surface->OwningLayerId() == clip_node->owner_id)
+ << "we now create clip node for every render surface";
// If the render surface's owning layer doesn't form a clip node, it is not
// clipped.
if (render_surface->OwningLayerId() != clip_node->owner_id)
@@ -1040,6 +1193,18 @@ void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees,
SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node),
property_trees->transform_tree, render_surface);
+
+ if (!property_trees->non_root_surfaces_enabled)
+ return;
+
+ if (render_surface->is_clipped()) {
+ const EffectNode* effect_node =
+ property_trees->effect_tree.Node(render_surface->EffectTreeIndex());
+ DCHECK(effect_node->data.has_render_surface);
+ CHECK(effect_node->data.clip_rect == render_surface->clip_rect())
+ << "effect tree's: " << effect_node->data.clip_rect.ToString()
+ << " clip: " << render_surface->clip_rect().ToString();
+ }
}
template <typename LayerType>
« no previous file with comments | « no previous file | cc/trees/property_tree.h » ('j') | cc/trees/property_tree.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698