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

Unified Diff: cc/trees/layer_tree_impl.cc

Issue 300323005: Route selection bounds updates through the compositor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 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/layer_tree_impl.cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 2c0efdd594f52f1e8fba4be3f1c8e3dbe806b661..2266ded80803fdff636f158f2f0f3f9e45cd2b9f 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -121,6 +121,8 @@ void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
outer_viewport_scroll_layer_ = NULL;
page_scale_layer_ = NULL;
+ ClearSelection();
aelias_OOO_until_Jul13 2014/06/28 00:02:17 I suggest removing this call. We may eventually w
jdduke (slow) 2014/06/28 00:29:10 Done.
+
layer_tree_host_impl_->OnCanDrawStateChangedForTree();
}
@@ -180,6 +182,8 @@ scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
page_scale_layer_ = NULL;
currently_scrolling_layer_ = NULL;
+ ClearSelection();
aelias_OOO_until_Jul13 2014/06/28 00:02:17 Likewise, please remove this call.
jdduke (slow) 2014/06/28 00:29:10 Done.
+
render_surface_layer_list_.clear();
set_needs_update_draw_properties();
return root_layer_.Pass();
@@ -210,6 +214,9 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
} else {
target_tree->ClearViewportLayers();
}
+
+ target_tree->RegisterSelection(selection_anchor_, selection_focus_);
+
// This should match the property synchronization in
// LayerTreeHost::finishCommitOnImplThread().
target_tree->set_source_frame_number(source_frame_number());
@@ -1044,6 +1051,10 @@ void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) {
ReleaseResourcesRecursive(current->children()[i]);
}
+void LayerTreeImpl::ClearSelection() {
+ RegisterSelection(LayerSelectionBound(), LayerSelectionBound());
+}
+
template <typename LayerType>
static inline bool LayerClipsSubtree(LayerType* layer) {
return layer->masks_to_bounds() || layer->mask_layer();
@@ -1122,7 +1133,7 @@ static bool PointHitsRegion(const gfx::PointF& screen_space_point,
gfx::ToRoundedPoint(hit_test_point_in_layer_space));
}
-static LayerImpl* GetNextClippingLayer(LayerImpl* layer) {
+static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
if (layer->scroll_parent())
return layer->scroll_parent();
if (layer->clip_parent())
@@ -1132,7 +1143,7 @@ static LayerImpl* GetNextClippingLayer(LayerImpl* layer) {
static bool PointIsClippedBySurfaceOrClipRect(
const gfx::PointF& screen_space_point,
- LayerImpl* layer) {
+ const LayerImpl* layer) {
// Walk up the layer tree and hit-test any render_surfaces and any layer
// clip rects that are active.
for (; layer; layer = GetNextClippingLayer(layer)) {
@@ -1156,7 +1167,7 @@ static bool PointIsClippedBySurfaceOrClipRect(
return false;
}
-static bool PointHitsLayer(LayerImpl* layer,
+static bool PointHitsLayer(const LayerImpl* layer,
const gfx::PointF& screen_space_point,
float* distance_to_intersection) {
gfx::RectF content_rect(layer->content_bounds());
@@ -1308,6 +1319,74 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
return data_for_recursion.closest_match;
}
+void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& anchor,
+ const LayerSelectionBound& focus) {
+ selection_anchor_ = anchor;
+ selection_focus_ = focus;
+}
+
+static ViewportSelectionBound ComputeViewportSelection(
+ const LayerSelectionBound& bound,
+ LayerImpl* layer,
+ float device_scale_factor) {
+ ViewportSelectionBound result;
+ result.type = bound.type;
+
+ if (!layer || bound.type == SELECTION_BOUND_EMPTY)
+ return result;
+
+ gfx::RectF layer_scaled_rect = gfx::ScaleRect(
+ bound.layer_rect, layer->contents_scale_x(), layer->contents_scale_y());
+ gfx::RectF screen_rect = MathUtil::ProjectClippedRect(
+ layer->screen_space_transform(), layer_scaled_rect);
+
+ // The bottom left of the bound is used for visibility because 1) the bound
+ // edge rect is one-dimensional (no width), and 2) the bottom is the logical
+ // focal point for bound selection handles (this may change in the future).
+ const gfx::PointF visibility_anchor = screen_rect.bottom_left();
+
+ // Using a small inclusive slop region for visibility prevents visibility
aelias_OOO_until_Jul13 2014/06/28 00:02:17 Won't you still get jitter when the edge of the sl
jdduke (slow) 2014/06/28 00:29:10 Yes, agreed. In fact I changed this just this afte
+ // "jitter" from floating point scaling error if a handle is on a boundary.
+ const float visibility_slop = device_scale_factor;
+ const gfx::RectF visibility_rect(visibility_anchor.x() - visibility_slop,
+ visibility_anchor.y() - visibility_slop,
+ visibility_slop * 2.f,
+ visibility_slop * 2.f);
+
+ float intersect_dist = 0.f;
+ result.visible =
+ PointHitsLayer(layer, visibility_rect.origin(), &intersect_dist) ||
+ PointHitsLayer(layer, visibility_rect.top_right(), &intersect_dist) ||
+ PointHitsLayer(layer, visibility_rect.bottom_left(), &intersect_dist) ||
+ PointHitsLayer(layer, visibility_rect.bottom_right(), &intersect_dist);
+
+ screen_rect.Scale(1.f / device_scale_factor);
+ result.viewport_rect = screen_rect;
+
+ return result;
+}
+
+void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* anchor,
+ ViewportSelectionBound* focus) {
+ DCHECK(!needs_update_draw_properties_);
+ DCHECK(anchor);
+ DCHECK(focus);
+
+ *anchor = ComputeViewportSelection(
+ selection_anchor_,
+ selection_anchor_.layer_id ? LayerById(selection_anchor_.layer_id) : NULL,
+ device_scale_factor());
+ if (anchor->type == SELECTION_BOUND_CENTER ||
+ anchor->type == SELECTION_BOUND_EMPTY) {
+ *focus = *anchor;
+ } else {
+ *focus = ComputeViewportSelection(
+ selection_focus_,
+ selection_focus_.layer_id ? LayerById(selection_focus_.layer_id) : NULL,
+ device_scale_factor());
+ }
+}
+
void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
layer_tree_host_impl_->RegisterPictureLayerImpl(layer);
}

Powered by Google App Engine
This is Rietveld 408576698