Index: cc/trees/layer_tree_host_impl.cc |
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc |
index 398ef81895ae08bc199b823c30c9bd27861a3c29..672ffe80b30be64a8033a4d6b7d24b884582ac14 100644 |
--- a/cc/trees/layer_tree_host_impl.cc |
+++ b/cc/trees/layer_tree_host_impl.cc |
@@ -116,18 +116,14 @@ class ViewportAnchor { |
gfx::ScrollOffset viewport_in_content_coordinates_; |
}; |
- |
void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { |
if (visible) { |
- TRACE_EVENT_ASYNC_BEGIN1("webkit", |
- "LayerTreeHostImpl::SetVisible", |
- id, |
- "LayerTreeHostImpl", |
- id); |
+ TRACE_EVENT_ASYNC_BEGIN1("cc", "LayerTreeHostImpl::SetVisible", id, |
+ "LayerTreeHostImpl", id); |
return; |
} |
- TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id); |
+ TRACE_EVENT_ASYNC_END0("cc", "LayerTreeHostImpl::SetVisible", id); |
} |
size_t GetMaxTransferBufferUsageBytes( |
@@ -229,7 +225,8 @@ LayerTreeHostImpl::LayerTreeHostImpl( |
gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
id_(id), |
requires_high_res_to_draw_(false), |
- is_likely_to_require_a_draw_(false) { |
+ is_likely_to_require_a_draw_(false), |
+ frame_timing_tracker_(FrameTimingTracker::Create()) { |
DCHECK(proxy_->IsImplThread()); |
DidVisibilityChange(this, visible_); |
animation_registrar_->set_supports_scroll_animations( |
@@ -469,16 +466,39 @@ bool LayerTreeHostImpl::HaveWheelEventHandlersAt( |
return layer_impl != NULL; |
} |
-bool LayerTreeHostImpl::HaveTouchEventHandlersAt( |
- const gfx::Point& viewport_point) { |
+static LayerImpl* NextScrollLayer(LayerImpl* layer) { |
+ if (LayerImpl* scroll_parent = layer->scroll_parent()) |
+ return scroll_parent; |
+ return layer->parent(); |
+} |
+ |
+static ScrollBlocksOn EffectiveScrollBlocksOn(LayerImpl* layer) { |
+ ScrollBlocksOn blocks = ScrollBlocksOnNone; |
+ for (; layer; layer = NextScrollLayer(layer)) { |
+ blocks |= layer->scroll_blocks_on(); |
+ } |
+ return blocks; |
+} |
+bool LayerTreeHostImpl::DoTouchEventsBlockScrollAt( |
+ const gfx::Point& viewport_point) { |
gfx::PointF device_viewport_point = |
gfx::ScalePoint(viewport_point, device_scale_factor_); |
+ // First check if scrolling at this point is required to block on any |
+ // touch event handlers. Note that we must start at the innermost layer |
+ // (as opposed to only the layer found to contain a touch handler region |
+ // below) to ensure all relevant scroll-blocks-on values are applied. |
LayerImpl* layer_impl = |
- active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( |
- device_viewport_point); |
+ active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
+ ScrollBlocksOn blocking = EffectiveScrollBlocksOn(layer_impl); |
+ if (!(blocking & ScrollBlocksOnStartTouch)) |
+ return false; |
+ // Now determine if there are actually any handlers at that point. |
+ // TODO(rbyers): Consider also honoring touch-action (crbug.com/347272). |
+ layer_impl = active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( |
+ device_viewport_point); |
return layer_impl != NULL; |
} |
@@ -674,6 +694,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( |
if (root_surface_has_contributing_layers && |
root_surface_has_no_visible_damage && |
active_tree_->LayersWithCopyOutputRequest().empty() && |
+ !output_surface_->capabilities().can_force_reclaim_resources && |
!hud_wants_to_draw_) { |
TRACE_EVENT0("cc", |
"LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); |
@@ -813,6 +834,18 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( |
*it, |
occlusion_tracker, |
&append_quads_data); |
+ |
+ // For layers that represent themselves, add composite frame timing |
+ // requests if the visible rect intersects the requested rect. |
+ for (const auto& request : it->frame_timing_requests()) { |
+ const gfx::Rect& request_content_rect = |
+ it->LayerRectToContentRect(request.rect()); |
+ if (request_content_rect.Intersects(it->visible_content_rect())) { |
+ frame->composite_events.push_back( |
+ FrameTimingTracker::FrameAndRectIds( |
+ active_tree_->source_frame_number(), request.id())); |
+ } |
+ } |
} |
++layers_drawn; |
@@ -1438,6 +1471,11 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame, |
TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); |
DCHECK(CanDraw()); |
+ if (!frame->composite_events.empty()) { |
+ frame_timing_tracker_->SaveTimeStamps(frame_begin_time, |
+ frame->composite_events); |
+ } |
+ |
if (frame->has_no_damage) { |
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); |
DCHECK(!output_surface_->capabilities() |
@@ -1577,6 +1615,7 @@ void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { |
DestroyTileManager(); |
CreateAndSetTileManager(); |
} |
+ RecreateTreeResources(); |
// We have released tilings for both active and pending tree. |
// We would not have any content to draw until the pending tree is activated. |
@@ -1895,6 +1934,14 @@ void LayerTreeHostImpl::ReleaseTreeResources() { |
EvictAllUIResources(); |
} |
+void LayerTreeHostImpl::RecreateTreeResources() { |
+ active_tree_->RecreateResources(); |
+ if (pending_tree_) |
+ pending_tree_->RecreateResources(); |
+ if (recycle_tree_) |
+ recycle_tree_->RecreateResources(); |
+} |
+ |
void LayerTreeHostImpl::CreateAndSetRenderer() { |
DCHECK(!renderer_); |
DCHECK(output_surface_); |
@@ -1959,7 +2006,8 @@ scoped_ptr<Rasterizer> LayerTreeHostImpl::CreateRasterizer() { |
ContextProvider* context_provider = output_surface_->context_provider(); |
if (use_gpu_rasterization_ && context_provider) { |
return GpuRasterizer::Create(context_provider, resource_provider_.get(), |
- settings_.use_distance_field_text, false, |
+ settings_.use_distance_field_text, |
+ settings_.threaded_gpu_rasterization_enabled, |
settings_.gpu_rasterization_msaa_sample_count); |
} |
return SoftwareRasterizer::Create(); |
@@ -2085,8 +2133,12 @@ bool LayerTreeHostImpl::InitializeRenderer( |
resource_provider_ = nullptr; |
output_surface_ = nullptr; |
- if (!output_surface->BindToClient(this)) |
+ if (!output_surface->BindToClient(this)) { |
+ // Avoid recreating tree resources because we might not have enough |
+ // information to do this yet (eg. we don't have a TileManager at this |
+ // point). |
return false; |
+ } |
output_surface_ = output_surface.Pass(); |
resource_provider_ = ResourceProvider::Create( |
@@ -2103,6 +2155,7 @@ bool LayerTreeHostImpl::InitializeRenderer( |
if (settings_.impl_side_painting) |
CreateAndSetTileManager(); |
+ RecreateTreeResources(); |
// Initialize vsync parameters to sane values. |
const base::TimeDelta display_refresh_interval = |
@@ -2152,6 +2205,7 @@ void LayerTreeHostImpl::DeferredInitialize() { |
CreateAndSetRenderer(); |
EnforceZeroBudget(false); |
CreateAndSetTileManager(); |
+ RecreateTreeResources(); |
client_->SetNeedsCommitOnImplThread(); |
} |
@@ -2171,6 +2225,7 @@ void LayerTreeHostImpl::ReleaseGL() { |
CreateAndSetRenderer(); |
EnforceZeroBudget(true); |
CreateAndSetTileManager(); |
+ RecreateTreeResources(); |
client_->SetNeedsCommitOnImplThread(); |
} |
@@ -2178,6 +2233,10 @@ void LayerTreeHostImpl::ReleaseGL() { |
void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { |
if (device_viewport_size == device_viewport_size_) |
return; |
+ TRACE_EVENT_INSTANT2("cc", "LayerTreeHostImpl::SetViewportSize", |
+ TRACE_EVENT_SCOPE_THREAD, "width", |
+ device_viewport_size.width(), "height", |
+ device_viewport_size.height()); |
if (pending_tree_) |
active_tree_->SetViewportSizeInvalid(); |
@@ -2255,12 +2314,6 @@ void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { |
input_handler_client_ = client; |
} |
-static LayerImpl* NextScrollLayer(LayerImpl* layer) { |
- if (LayerImpl* scroll_parent = layer->scroll_parent()) |
- return scroll_parent; |
- return layer->parent(); |
-} |
- |
LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
const gfx::PointF& device_viewport_point, |
InputHandler::ScrollInputType type, |
@@ -2269,12 +2322,15 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
bool* optional_has_ancestor_scroll_handler) const { |
DCHECK(scroll_on_main_thread); |
+ ScrollBlocksOn block_mode = EffectiveScrollBlocksOn(layer_impl); |
+ |
// Walk up the hierarchy and look for a scrollable layer. |
LayerImpl* potentially_scrolling_layer_impl = NULL; |
for (; layer_impl; layer_impl = NextScrollLayer(layer_impl)) { |
// The content layer can also block attempts to scroll outside the main |
// thread. |
- ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); |
+ ScrollStatus status = |
+ layer_impl->TryScroll(device_viewport_point, type, block_mode); |
if (status == ScrollOnMainThread) { |
*scroll_on_main_thread = true; |
return NULL; |
@@ -2284,7 +2340,8 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
if (!scroll_layer_impl) |
continue; |
- status = scroll_layer_impl->TryScroll(device_viewport_point, type); |
+ status = |
+ scroll_layer_impl->TryScroll(device_viewport_point, type, block_mode); |
// If any layer wants to divert the scroll event to the main thread, abort. |
if (status == ScrollOnMainThread) { |
*scroll_on_main_thread = true; |
@@ -2988,7 +3045,7 @@ static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, |
if (!scroll_delta.IsZero()) { |
LayerTreeHostCommon::ScrollUpdateInfo scroll; |
scroll.layer_id = layer_impl->id(); |
- scroll.scroll_delta = gfx::Vector2d(scroll_delta.x(), scroll_delta.y()); |
+ scroll.scroll_delta = gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); |
scroll_info->scrolls.push_back(scroll); |
} |