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 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 &accumulated_surface_state); | 2238 &accumulated_surface_state); |
2239 | 2239 |
2240 // The dummy layer list should not have been used. | 2240 // The dummy layer list should not have been used. |
2241 DCHECK_EQ(0u, dummy_layer_list.size()); | 2241 DCHECK_EQ(0u, dummy_layer_list.size()); |
2242 // A root layer render_surface should always exist after | 2242 // A root layer render_surface should always exist after |
2243 // CalculateDrawProperties. | 2243 // CalculateDrawProperties. |
2244 DCHECK(inputs->root_layer->render_surface()); | 2244 DCHECK(inputs->root_layer->render_surface()); |
2245 } | 2245 } |
2246 | 2246 |
2247 static bool PointHitsRect( | 2247 static bool PointHitsRect( |
2248 gfx::PointF screen_space_point, | 2248 const gfx::PointF& screen_space_point, |
2249 const gfx::Transform& local_space_to_screen_space_transform, | 2249 const gfx::Transform& local_space_to_screen_space_transform, |
2250 const gfx::RectF& local_space_rect) { | 2250 const gfx::RectF& local_space_rect) { |
2251 // If the transform is not invertible, then assume that this point doesn't hit | 2251 // If the transform is not invertible, then assume that this point doesn't hit |
2252 // this rect. | 2252 // this rect. |
2253 gfx::Transform inverse_local_space_to_screen_space( | 2253 gfx::Transform inverse_local_space_to_screen_space( |
2254 gfx::Transform::kSkipInitialization); | 2254 gfx::Transform::kSkipInitialization); |
2255 if (!local_space_to_screen_space_transform.GetInverse( | 2255 if (!local_space_to_screen_space_transform.GetInverse( |
2256 &inverse_local_space_to_screen_space)) | 2256 &inverse_local_space_to_screen_space)) |
2257 return false; | 2257 return false; |
2258 | 2258 |
2259 // Transform the hit test point from screen space to the local space of the | 2259 // Transform the hit test point from screen space to the local space of the |
2260 // given rect. | 2260 // given rect. |
2261 bool clipped = false; | 2261 bool clipped = false; |
2262 gfx::PointF hit_test_point_in_local_space = MathUtil::ProjectPoint( | 2262 gfx::PointF hit_test_point_in_local_space = MathUtil::ProjectPoint( |
2263 inverse_local_space_to_screen_space, screen_space_point, &clipped); | 2263 inverse_local_space_to_screen_space, screen_space_point, &clipped); |
2264 | 2264 |
2265 // If ProjectPoint could not project to a valid value, then we assume that | 2265 // If ProjectPoint could not project to a valid value, then we assume that |
2266 // this point doesn't hit this rect. | 2266 // this point doesn't hit this rect. |
2267 if (clipped) | 2267 if (clipped) |
2268 return false; | 2268 return false; |
2269 | 2269 |
2270 return local_space_rect.Contains(hit_test_point_in_local_space); | 2270 return local_space_rect.Contains(hit_test_point_in_local_space); |
2271 } | 2271 } |
2272 | 2272 |
2273 static bool PointHitsRegion(gfx::PointF screen_space_point, | 2273 static bool PointHitsRegion(const gfx::PointF& screen_space_point, |
2274 const gfx::Transform& screen_space_transform, | 2274 const gfx::Transform& screen_space_transform, |
2275 const Region& layer_space_region, | 2275 const Region& layer_space_region, |
2276 float layer_content_scale_x, | 2276 float layer_content_scale_x, |
2277 float layer_content_scale_y) { | 2277 float layer_content_scale_y) { |
2278 // If the transform is not invertible, then assume that this point doesn't hit | 2278 // If the transform is not invertible, then assume that this point doesn't hit |
2279 // this region. | 2279 // this region. |
2280 gfx::Transform inverse_screen_space_transform( | 2280 gfx::Transform inverse_screen_space_transform( |
2281 gfx::Transform::kSkipInitialization); | 2281 gfx::Transform::kSkipInitialization); |
2282 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform)) | 2282 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform)) |
2283 return false; | 2283 return false; |
(...skipping 10 matching lines...) Expand all Loading... |
2294 | 2294 |
2295 // If ProjectPoint could not project to a valid value, then we assume that | 2295 // If ProjectPoint could not project to a valid value, then we assume that |
2296 // this point doesn't hit this region. | 2296 // this point doesn't hit this region. |
2297 if (clipped) | 2297 if (clipped) |
2298 return false; | 2298 return false; |
2299 | 2299 |
2300 return layer_space_region.Contains( | 2300 return layer_space_region.Contains( |
2301 gfx::ToRoundedPoint(hit_test_point_in_layer_space)); | 2301 gfx::ToRoundedPoint(hit_test_point_in_layer_space)); |
2302 } | 2302 } |
2303 | 2303 |
2304 static bool PointIsClippedBySurfaceOrClipRect(gfx::PointF screen_space_point, | 2304 static bool PointIsClippedBySurfaceOrClipRect( |
2305 LayerImpl* layer) { | 2305 const gfx::PointF& screen_space_point, |
| 2306 LayerImpl* layer) { |
2306 LayerImpl* current_layer = layer; | 2307 LayerImpl* current_layer = layer; |
2307 | 2308 |
2308 // Walk up the layer tree and hit-test any render_surfaces and any layer | 2309 // Walk up the layer tree and hit-test any render_surfaces and any layer |
2309 // clip rects that are active. | 2310 // clip rects that are active. |
2310 while (current_layer) { | 2311 while (current_layer) { |
2311 if (current_layer->render_surface() && | 2312 if (current_layer->render_surface() && |
2312 !PointHitsRect( | 2313 !PointHitsRect( |
2313 screen_space_point, | 2314 screen_space_point, |
2314 current_layer->render_surface()->screen_space_transform(), | 2315 current_layer->render_surface()->screen_space_transform(), |
2315 current_layer->render_surface()->content_rect())) | 2316 current_layer->render_surface()->content_rect())) |
(...skipping 12 matching lines...) Expand all Loading... |
2328 | 2329 |
2329 current_layer = current_layer->parent(); | 2330 current_layer = current_layer->parent(); |
2330 } | 2331 } |
2331 | 2332 |
2332 // If we have finished walking all ancestors without having already exited, | 2333 // If we have finished walking all ancestors without having already exited, |
2333 // then the point is not clipped by any ancestors. | 2334 // then the point is not clipped by any ancestors. |
2334 return false; | 2335 return false; |
2335 } | 2336 } |
2336 | 2337 |
2337 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPoint( | 2338 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPoint( |
2338 gfx::PointF screen_space_point, | 2339 const gfx::PointF& screen_space_point, |
2339 const LayerImplList& render_surface_layer_list) { | 2340 const LayerImplList& render_surface_layer_list) { |
2340 LayerImpl* found_layer = NULL; | 2341 LayerImpl* found_layer = NULL; |
2341 | 2342 |
2342 typedef LayerIterator<LayerImpl, | 2343 typedef LayerIterator<LayerImpl, |
2343 LayerImplList, | 2344 LayerImplList, |
2344 RenderSurfaceImpl, | 2345 RenderSurfaceImpl, |
2345 LayerIteratorActions::FrontToBack> LayerIteratorType; | 2346 LayerIteratorActions::FrontToBack> LayerIteratorType; |
2346 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); | 2347 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); |
2347 | 2348 |
2348 for (LayerIteratorType | 2349 for (LayerIteratorType |
(...skipping 25 matching lines...) Expand all Loading... |
2374 found_layer = current_layer; | 2375 found_layer = current_layer; |
2375 break; | 2376 break; |
2376 } | 2377 } |
2377 | 2378 |
2378 // This can potentially return NULL, which means the screen_space_point did | 2379 // This can potentially return NULL, which means the screen_space_point did |
2379 // not successfully hit test any layers, not even the root layer. | 2380 // not successfully hit test any layers, not even the root layer. |
2380 return found_layer; | 2381 return found_layer; |
2381 } | 2382 } |
2382 | 2383 |
2383 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( | 2384 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion( |
2384 gfx::PointF screen_space_point, | 2385 const gfx::PointF& screen_space_point, |
2385 const LayerImplList& render_surface_layer_list) { | 2386 const LayerImplList& render_surface_layer_list) { |
2386 // First find out which layer was hit from the saved list of visible layers | 2387 // First find out which layer was hit from the saved list of visible layers |
2387 // in the most recent frame. | 2388 // in the most recent frame. |
2388 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint( | 2389 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint( |
2389 screen_space_point, | 2390 screen_space_point, |
2390 render_surface_layer_list); | 2391 render_surface_layer_list); |
2391 | 2392 |
2392 // Walk up the hierarchy and look for a layer with a touch event handler | 2393 // Walk up the hierarchy and look for a layer with a touch event handler |
2393 // region that the given point hits. | 2394 // region that the given point hits. |
2394 // This walk may not be necessary anymore: http://crbug.com/310817 | 2395 // This walk may not be necessary anymore: http://crbug.com/310817 |
2395 for (; layer_impl; layer_impl = layer_impl->parent()) { | 2396 for (; layer_impl; layer_impl = layer_impl->parent()) { |
2396 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(screen_space_point, | 2397 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(screen_space_point, |
2397 layer_impl)) | 2398 layer_impl)) |
2398 break; | 2399 break; |
2399 } | 2400 } |
2400 return layer_impl; | 2401 return layer_impl; |
2401 } | 2402 } |
2402 | 2403 |
2403 bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt( | 2404 bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt( |
2404 gfx::PointF screen_space_point, | 2405 const gfx::PointF& screen_space_point, |
2405 LayerImpl* layer_impl) { | 2406 LayerImpl* layer_impl) { |
2406 if (layer_impl->touch_event_handler_region().IsEmpty()) | 2407 if (layer_impl->touch_event_handler_region().IsEmpty()) |
2407 return false; | 2408 return false; |
2408 | 2409 |
2409 if (!PointHitsRegion(screen_space_point, | 2410 if (!PointHitsRegion(screen_space_point, |
2410 layer_impl->screen_space_transform(), | 2411 layer_impl->screen_space_transform(), |
2411 layer_impl->touch_event_handler_region(), | 2412 layer_impl->touch_event_handler_region(), |
2412 layer_impl->contents_scale_x(), | 2413 layer_impl->contents_scale_x(), |
2413 layer_impl->contents_scale_y())) | 2414 layer_impl->contents_scale_y())) |
2414 return false; | 2415 return false; |
2415 | 2416 |
2416 // At this point, we think the point does hit the touch event handler region | 2417 // At this point, we think the point does hit the touch event handler region |
2417 // on the layer, but we need to walk up the parents to ensure that the layer | 2418 // on the layer, but we need to walk up the parents to ensure that the layer |
2418 // was not clipped in such a way that the hit point actually should not hit | 2419 // was not clipped in such a way that the hit point actually should not hit |
2419 // the layer. | 2420 // the layer. |
2420 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) | 2421 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) |
2421 return false; | 2422 return false; |
2422 | 2423 |
2423 return true; | 2424 return true; |
2424 } | 2425 } |
2425 } // namespace cc | 2426 } // namespace cc |
OLD | NEW |