OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/trees/layer_tree_host_common.h" | 5 #include "cc/trees/layer_tree_host_common.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "cc/base/math_util.h" | 10 #include "cc/base/math_util.h" |
(...skipping 2508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2519 | 2519 |
2520 found_layer = current_layer; | 2520 found_layer = current_layer; |
2521 break; | 2521 break; |
2522 } | 2522 } |
2523 | 2523 |
2524 // This can potentially return NULL, which means the screen_space_point did | 2524 // This can potentially return NULL, which means the screen_space_point did |
2525 // not successfully hit test any layers, not even the root layer. | 2525 // not successfully hit test any layers, not even the root layer. |
2526 return found_layer; | 2526 return found_layer; |
2527 } | 2527 } |
2528 | 2528 |
2529 // This may be generalized in the future, but we know at the very least that | |
2530 // hits cannot pass through scrolling nor opaque layers. | |
2531 static bool OpaqueToHitTesting(const LayerImpl* layer) { | |
2532 return layer->scrollable() || layer->contents_opaque(); | |
2533 } | |
2534 | |
2535 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( | 2529 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( |
2536 const gfx::PointF& screen_space_point, | 2530 const gfx::PointF& screen_space_point, |
2537 const LayerImplList& render_surface_layer_list) { | 2531 const LayerImplList& render_surface_layer_list) { |
2538 typedef LayerIterator<LayerImpl> LayerIteratorType; | 2532 typedef LayerIterator<LayerImpl> LayerIteratorType; |
2539 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); | 2533 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); |
2540 for (LayerIteratorType it = | 2534 for (LayerIteratorType it = |
2541 LayerIteratorType::Begin(&render_surface_layer_list); | 2535 LayerIteratorType::Begin(&render_surface_layer_list); |
2542 it != end; | 2536 it != end; |
2543 ++it) { | 2537 ++it) { |
2544 // We don't want to consider render_surfaces for hit testing. | 2538 // We don't want to consider render_surfaces for hit testing. |
2545 if (!it.represents_itself()) | 2539 if (!it.represents_itself()) |
2546 continue; | 2540 continue; |
2547 | 2541 |
2548 LayerImpl* current_layer = (*it); | 2542 LayerImpl* current_layer = (*it); |
2549 if (!PointHitsLayer(current_layer, screen_space_point)) | 2543 if (!PointHitsLayer(current_layer, screen_space_point)) |
2550 continue; | 2544 continue; |
2551 | 2545 |
2552 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(screen_space_point, | 2546 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(screen_space_point, |
2553 current_layer)) | 2547 current_layer)) |
2554 return current_layer; | 2548 return current_layer; |
2555 | 2549 |
2556 if (OpaqueToHitTesting(current_layer)) | 2550 // Note that we could stop searching if we hit a layer we know to be |
2557 break; | 2551 // opaque to hit-testing, but knowing that reliably is tricky (eg. due to |
| 2552 // CSS pointer-events: none). Also blink has an optimization for the |
| 2553 // common case of an entire document having handlers where it doesn't |
| 2554 // report any rects for child layers (since it knows they can't exceed |
| 2555 // the document bounds). |
2558 } | 2556 } |
2559 return NULL; | 2557 return NULL; |
2560 } | 2558 } |
2561 | 2559 |
2562 bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt( | 2560 bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt( |
2563 const gfx::PointF& screen_space_point, | 2561 const gfx::PointF& screen_space_point, |
2564 LayerImpl* layer_impl) { | 2562 LayerImpl* layer_impl) { |
2565 if (layer_impl->touch_event_handler_region().IsEmpty()) | 2563 if (layer_impl->touch_event_handler_region().IsEmpty()) |
2566 return false; | 2564 return false; |
2567 | 2565 |
2568 if (!PointHitsRegion(screen_space_point, | 2566 if (!PointHitsRegion(screen_space_point, |
2569 layer_impl->screen_space_transform(), | 2567 layer_impl->screen_space_transform(), |
2570 layer_impl->touch_event_handler_region(), | 2568 layer_impl->touch_event_handler_region(), |
2571 layer_impl->contents_scale_x(), | 2569 layer_impl->contents_scale_x(), |
2572 layer_impl->contents_scale_y())) | 2570 layer_impl->contents_scale_y())) |
2573 return false; | 2571 return false; |
2574 | 2572 |
2575 // At this point, we think the point does hit the touch event handler region | 2573 // At this point, we think the point does hit the touch event handler region |
2576 // on the layer, but we need to walk up the parents to ensure that the layer | 2574 // on the layer, but we need to walk up the parents to ensure that the layer |
2577 // was not clipped in such a way that the hit point actually should not hit | 2575 // was not clipped in such a way that the hit point actually should not hit |
2578 // the layer. | 2576 // the layer. |
2579 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) | 2577 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) |
2580 return false; | 2578 return false; |
2581 | 2579 |
2582 return true; | 2580 return true; |
2583 } | 2581 } |
2584 } // namespace cc | 2582 } // namespace cc |
OLD | NEW |