Chromium Code Reviews| 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); |
| } |