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 9932a33be03d59d47c6ea65ad437c8a46b4e76a6..38dd5e61126341fecabe12ce8b8b8ae76d3d98cb 100644 |
| --- a/cc/trees/layer_tree_impl.cc |
| +++ b/cc/trees/layer_tree_impl.cc |
| @@ -119,6 +119,8 @@ void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { |
| outer_viewport_scroll_layer_ = NULL; |
| page_scale_layer_ = NULL; |
| + ClearSelection(); |
| + |
| layer_tree_host_impl_->OnCanDrawStateChangedForTree(); |
| } |
| @@ -178,6 +180,8 @@ scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() { |
| page_scale_layer_ = NULL; |
| currently_scrolling_layer_ = NULL; |
| + ClearSelection(); |
| + |
| render_surface_layer_list_.clear(); |
| set_needs_update_draw_properties(); |
| return root_layer_.Pass(); |
| @@ -209,6 +213,13 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { |
| } else { |
| target_tree->ClearViewportLayers(); |
| } |
| + |
| + target_tree->RegisterSelection( |
| + start_selection_layer_ ? start_selection_layer_->id() : 0, |
| + start_selection_handle_, |
| + end_selection_layer_ ? end_selection_layer_->id() : 0, |
| + end_selection_handle_); |
| + |
| // This should match the property synchronization in |
| // LayerTreeHost::finishCommitOnImplThread(). |
| target_tree->set_source_frame_number(source_frame_number()); |
| @@ -1017,6 +1028,10 @@ void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) { |
| ReleaseResourcesRecursive(current->children()[i]); |
| } |
| +void LayerTreeImpl::ClearSelection() { |
| + RegisterSelection(0, SelectionHandle(), 0, SelectionHandle()); |
| +} |
| + |
| template <typename LayerType> |
| static inline bool LayerClipsSubtree(LayerType* layer) { |
| return layer->masks_to_bounds() || layer->mask_layer(); |
| @@ -1097,8 +1112,8 @@ static bool PointHitsRegion(const gfx::PointF& screen_space_point, |
| static bool PointIsClippedBySurfaceOrClipRect( |
| const gfx::PointF& screen_space_point, |
| - LayerImpl* layer) { |
| - LayerImpl* current_layer = layer; |
| + const LayerImpl* layer) { |
| + const LayerImpl* current_layer = layer; |
| // Walk up the layer tree and hit-test any render_surfaces and any layer |
| // clip rects that are active. |
| @@ -1114,7 +1129,7 @@ static bool PointIsClippedBySurfaceOrClipRect( |
| // Note that drawable content rects are actually in target surface space, so |
| // the transform we have to provide is the target surface's |
| // screen_space_transform. |
| - LayerImpl* render_target = current_layer->render_target(); |
| + const LayerImpl* render_target = current_layer->render_target(); |
| if (LayerClipsSubtree(current_layer) && |
| !PointHitsRect( |
| screen_space_point, |
| @@ -1131,7 +1146,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()); |
| @@ -1275,4 +1290,57 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion( |
| return data_for_recursion.closest_match; |
| } |
| +void LayerTreeImpl::RegisterSelection(int start_layer_id, |
| + const SelectionHandle& start_handle, |
| + int end_layer_id, |
| + const SelectionHandle& end_handle) { |
| + start_selection_layer_ = start_layer_id ? LayerById(start_layer_id) : NULL; |
| + end_selection_layer_ = end_layer_id ? LayerById(end_layer_id) : NULL; |
| + start_selection_handle_ = start_handle; |
| + end_selection_handle_ = end_handle; |
| +} |
| + |
| +static SelectionHandle ComputeSelectionVisibility(const SelectionHandle& handle, |
| + const LayerImpl* layer, |
| + float device_scale_factor) { |
| + if (!layer || handle.type == SelectionHandle::NONE || |
| + handle.type == SelectionHandle::IGNORED) |
| + return handle; |
| + |
| + SelectionHandle result = handle; |
| + |
| + gfx::QuadF layer_scaled_quad(gfx::ScaleRect( |
| + handle.bounds, layer->contents_scale_x(), layer->contents_scale_y())); |
| + bool handle_clipped = false; |
| + gfx::QuadF screen_quad = MathUtil::ProjectQuad( |
| + layer->screen_space_transform(), layer_scaled_quad, &handle_clipped); |
| + screen_quad.Scale(1.f / device_scale_factor); |
| + result.bounds = screen_quad.BoundingBox(); |
| + |
| + // Use the bottom-left coordinate as the visibility anchor point. |
| + result.visible = !handle_clipped && |
|
jdduke (slow)
2014/06/02 20:06:01
Bah, figured it out, need to be doing the clip tes
|
| + !PointIsClippedBySurfaceOrClipRect(screen_quad.p4(), layer); |
| + |
| + return result; |
| +} |
| + |
| +void LayerTreeImpl::GetViewportSelection(SelectionHandle* start_handle, |
| + SelectionHandle* end_handle) { |
| + DCHECK(!needs_update_draw_properties_); |
| + DCHECK(start_handle); |
| + DCHECK(end_handle); |
| + |
| + *start_handle = ComputeSelectionVisibility( |
| + start_selection_handle_, start_selection_layer_, device_scale_factor()); |
| + |
| + if (start_handle->type == SelectionHandle::CENTER || |
| + start_handle->type == SelectionHandle::NONE || |
| + start_handle->type == SelectionHandle::IGNORED) { |
| + *end_handle = *start_handle; |
| + } else { |
| + *end_handle = ComputeSelectionVisibility( |
| + end_selection_handle_, end_selection_layer_, device_scale_factor()); |
| + } |
| +} |
| + |
| } // namespace cc |