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

Unified Diff: cc/trees/draw_property_utils.cc

Issue 2067783002: cc: Calculate visible rect inside non root copy request (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rectF
Patch Set: rebase Created 4 years, 6 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
Index: cc/trees/draw_property_utils.cc
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 6881a25cc1a3f323a0bbaaf55f6f9a04dcad94a5..923bf90589fd38582dd81a4648d9e2928104da9a 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -92,6 +92,113 @@ bool ComputeClipRectInTargetSpace(const LayerType* layer,
return true;
}
+struct ClipRect {
+ bool is_clipped;
+ gfx::RectF clip_rect;
+};
+
+static ClipRect ComputeRectInTargetSpace(gfx::RectF rect,
+ const TransformTree& transform_tree,
+ int current_transform_id,
+ int target_transform_id) {
+ gfx::Transform current_to_target;
+ if (!transform_tree.ComputeTransformWithDestinationSublayerScale(
+ current_transform_id, target_transform_id, &current_to_target))
+ return ClipRect{false, gfx::RectF()};
ajuma 2016/06/14 15:09:53 To make the bools here and below more readable (th
weiliangc 2016/06/15 12:27:57 Renamed ClipRect to ConditionalClip, and add comme
+ if (current_transform_id > target_transform_id)
+ return ClipRect{true, MathUtil::MapClippedRect(current_to_target, rect)};
+ else
ajuma 2016/06/14 15:09:53 Nit: no need for 'else' after return
weiliangc 2016/06/15 12:27:57 Done.
+ return ClipRect{true,
+ MathUtil::ProjectClippedRect(current_to_target, rect)};
+}
+
+static ClipRect ComputeCurrentClip(const ClipNode* clip_node,
+ const TransformTree& transform_tree,
+ int target_transform_id) {
+ if (clip_node->data.transform_id != target_transform_id) {
+ return ComputeRectInTargetSpace(clip_node->data.clip, transform_tree,
+ clip_node->data.transform_id,
+ target_transform_id);
+ } else {
ajuma 2016/06/14 15:09:53 Here too, no need to use 'else' here since there's
weiliangc 2016/06/15 12:27:57 Done.
+ 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 ClipRect{true, current_clip};
+ }
+}
+
+static ClipRect 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;
+ bool is_clipped = false;
+
+ // 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 ClipRect{false, gfx::RectF()};
+
+ ClipRect current_clip =
+ ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
+ is_clipped = current_clip.is_clipped;
+ gfx::RectF accumulated_clip = current_clip.clip_rect;
+
+ while (parent_chain.size() > 0) {
+ clip_node = parent_chain.top();
+ parent_chain.pop();
+ if (!clip_node->data.applies_local_clip) {
+ continue;
+ }
+ ClipRect current_clip =
+ ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
+
+ if (!current_clip.is_clipped)
+ return ClipRect{false, gfx::RectF()};
+
+ is_clipped |= current_clip.is_clipped;
+ accumulated_clip =
+ gfx::IntersectRects(accumulated_clip, current_clip.clip_rect);
+ }
+
+ return ClipRect{is_clipped,
+ accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip};
+}
+
template <typename LayerType>
void CalculateClipRects(
const typename LayerType::LayerListType& visible_layer_list,
@@ -184,11 +291,35 @@ void CalculateVisibleRects(
for (auto& layer : visible_layer_list) {
gfx::Size layer_bounds = layer->bounds();
- const EffectNode* effect_node =
- effect_tree.Node(layer->effect_tree_index());
- if (effect_node->data.has_copy_request &&
- effect_node->owner_id == layer->id()) {
- layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
+ int effect_ancestor_with_copy_request =
+ effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index());
+ if (effect_ancestor_with_copy_request > 1) {
+ // Non root copy request.
+ ClipRect accumulated_clip_rect = ComputeAccumulatedClip(
+ clip_tree, layer->clip_tree_index(), effect_tree,
+ effect_ancestor_with_copy_request, transform_tree);
+ if (!accumulated_clip_rect.is_clipped) {
+ layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
+ continue;
+ }
+
+ gfx::RectF accumulated_clip_in_copy_request_space =
+ accumulated_clip_rect.clip_rect;
+ const EffectNode* copy_request_effect_node =
+ effect_tree.Node(effect_ancestor_with_copy_request);
+ ClipRect clip_in_layer_space = ComputeRectInTargetSpace(
+ accumulated_clip_in_copy_request_space, transform_tree,
+ copy_request_effect_node->data.transform_id,
+ layer->transform_tree_index());
+ if (clip_in_layer_space.is_clipped) {
ajuma 2016/06/14 15:09:53 Since accumulated_clip_rect.is_clipped is true her
weiliangc 2016/06/15 12:27:57 Yes I think so.
+ gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
+ clip_rect.Offset(-layer->offset_to_transform_parent());
+ gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
+ visible_rect.Intersect(gfx::Rect(layer_bounds));
+ layer->set_visible_layer_rect(visible_rect);
+ } else {
+ layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
+ }
continue;
}
@@ -678,94 +809,6 @@ 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;
@@ -784,9 +827,10 @@ static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) {
EffectNode* effect_node = effect_tree->Node(i);
const EffectNode* target_node =
effect_tree->Node(effect_node->data.target_id);
- gfx::RectF accumulated_clip =
+ ClipRect accumulated_clip_rect =
ComputeAccumulatedClip(*clip_tree, effect_node->data.clip_id,
*effect_tree, target_node->id, *transform_tree);
+ gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect;
const RenderSurfaceImpl* render_surface = effect_node->data.render_surface;
if (render_surface && render_surface->is_clipped()) {
DCHECK(gfx::ToEnclosingRect(accumulated_clip) ==
@@ -815,10 +859,12 @@ static void ComputeLayerClipRect(const PropertyTrees* property_trees,
target_node = effect_tree->Node(1);
}
- gfx::RectF accumulated_clip =
+ ClipRect accumulated_clip_rect =
ComputeAccumulatedClip(*clip_tree, layer->clip_tree_index(), *effect_tree,
target_node->id, *transform_tree);
+ gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect;
+
if ((!property_trees->non_root_surfaces_enabled &&
clip_tree->Node(layer->clip_tree_index())
->data.layers_are_clipped_when_surfaces_disabled) ||
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | cc/trees/layer_tree_host_common_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698