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

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: fix perftests compile by not verify clip tree calc there Created 4 years, 7 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/draw_property_utils.h ('k') | cc/trees/layer_tree_host_common.h » ('j') | no next file with comments »
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 0d8250c79fc46a6603d38ef89de2694b2c931253..775482a2d496f1a310db6430761f05e7f0e0e420 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -162,7 +162,6 @@ void CalculateVisibleRects(
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);
@@ -367,7 +366,6 @@ void UpdateRenderSurfaceForLayer(EffectTree* effect_tree,
else
layer->SetHasRenderSurface(false);
}
-
} // namespace
template <typename LayerType>
@@ -615,6 +613,162 @@ 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;
+ }
+}
+
+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;
+
+ // 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->data.applies_local_clip && parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ }
+
+ if (!clip_node->data.applies_local_clip)
+ 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) {
+ continue;
+ }
+ gfx::RectF current_clip =
+ ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
+
+ if (current_clip.IsEmpty())
+ return gfx::RectF();
+
+ accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip);
+ }
+
+ return accumulated_clip.IsEmpty() ? gfx::RectF() : 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);
+ const RenderSurfaceImpl* root_render_surface =
+ root_effect_node->data.render_surface;
+ gfx::Rect root_clip = gfx::ToEnclosingRect(
+ clip_tree->Node(root_effect_node->data.clip_id)->data.clip);
+ if (root_render_surface->is_clipped())
+ DCHECK(root_clip == root_render_surface->clip_rect())
+ << "clip on root render surface: "
+ << root_render_surface->clip_rect().ToString()
+ << " v.s. root effect node's clip: " << root_clip.ToString();
+ 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 RenderSurfaceImpl* render_surface = effect_node->data.render_surface;
+ if (render_surface && render_surface->is_clipped()) {
+ DCHECK(gfx::ToEnclosingRect(accumulated_clip) ==
+ render_surface->clip_rect())
+ << " render surface's clip rect: "
+ << render_surface->clip_rect().ToString()
+ << " v.s. accumulated clip: "
+ << gfx::ToEnclosingRect(accumulated_clip).ToString();
+ }
+ }
+}
+
+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);
+ // TODO(weiliangc): When effect node has up to date render surface info on
+ // compositor thread, no need to check for resourceless draw mode
+ if (!property_trees->non_root_surfaces_enabled) {
+ target_node = effect_tree->Node(1);
+ }
+
+ 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_when_surfaces_disabled) ||
+ clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) {
+ DCHECK(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();
+ }
+}
+
static void ComputeVisibleRectsInternal(
LayerImpl* root_layer,
PropertyTrees* property_trees,
@@ -645,7 +799,9 @@ static void ComputeVisibleRectsInternal(
void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) {
for (auto* layer : *root_layer->layer_tree_host()) {
- UpdateRenderSurfaceForLayer(&property_trees->effect_tree, true, layer);
+ UpdateRenderSurfaceForLayer(&property_trees->effect_tree,
+ property_trees->non_root_surfaces_enabled,
+ layer);
#if DCHECK_IS_ON()
ValidateRenderSurfaceForLayer(layer);
#endif
@@ -698,6 +854,15 @@ void BuildPropertyTreesAndComputeVisibleRects(
can_render_to_separate_surface, visible_layer_list);
}
+void VerifyClipTreeCalculations(const LayerImplList& layer_list,
+ PropertyTrees* property_trees) {
+ if (property_trees->non_root_surfaces_enabled) {
+ ComputeClipsWithEffectTree(property_trees);
+ }
+ for (auto layer : layer_list)
+ ComputeLayerClipRect(property_trees, layer);
+}
+
void ComputeVisibleRects(LayerImpl* root_layer,
PropertyTrees* property_trees,
bool can_render_to_separate_surface,
@@ -775,12 +940,10 @@ static void SetSurfaceDrawTransform(const TransformTree& tree,
static void SetSurfaceIsClipped(const ClipNode* clip_node,
RenderSurfaceImpl* 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)
- render_surface->SetIsClipped(false);
- else
- render_surface->SetIsClipped(clip_node->data.target_is_clipped);
+ DCHECK(render_surface->OwningLayerId() == clip_node->owner_id)
+ << "we now create clip node for every render surface";
+
+ render_surface->SetIsClipped(clip_node->data.target_is_clipped);
}
static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
« no previous file with comments | « cc/trees/draw_property_utils.h ('k') | cc/trees/layer_tree_host_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698