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
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host_impl.h"
9 #include "base/basictypes.h"
10 #include "base/debug/trace_event.h"
11 #include "base/json/json_writer.h"
12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h"
14 #include "base/stringprintf.h"
15 #include "cc/animation/scrollbar_animation_controller.h"
16 #include "cc/animation/timing_function.h"
17 #include "cc/base/math_util.h"
18 #include "cc/base/util.h"
19 #include "cc/debug/debug_rect_history.h"
20 #include "cc/debug/frame_rate_counter.h"
21 #include "cc/debug/overdraw_metrics.h"
22 #include "cc/debug/paint_time_counter.h"
23 #include "cc/debug/rendering_stats_instrumentation.h"
24 #include "cc/input/page_scale_animation.h"
25 #include "cc/input/top_controls_manager.h"
26 #include "cc/layers/append_quads_data.h"
27 #include "cc/layers/heads_up_display_layer_impl.h"
28 #include "cc/layers/layer_impl.h"
29 #include "cc/layers/layer_iterator.h"
30 #include "cc/layers/render_surface_impl.h"
31 #include "cc/layers/scrollbar_layer_impl.h"
32 #include "cc/output/compositor_frame_metadata.h"
33 #include "cc/output/delegating_renderer.h"
34 #include "cc/output/gl_renderer.h"
35 #include "cc/output/software_renderer.h"
36 #include "cc/quads/render_pass_draw_quad.h"
37 #include "cc/quads/shared_quad_state.h"
38 #include "cc/quads/solid_color_draw_quad.h"
39 #include "cc/resources/memory_history.h"
40 #include "cc/resources/picture_layer_tiling.h"
41 #include "cc/resources/prioritized_resource_manager.h"
42 #include "cc/scheduler/delay_based_time_source.h"
43 #include "cc/scheduler/texture_uploader.h"
44 #include "cc/trees/damage_tracker.h"
45 #include "cc/trees/layer_tree_host.h"
46 #include "cc/trees/layer_tree_host_common.h"
47 #include "cc/trees/layer_tree_impl.h"
48 #include "cc/trees/quad_culler.h"
49 #include "cc/trees/single_thread_proxy.h"
50 #include "cc/trees/tree_synchronizer.h"
51 #include "ui/gfx/size_conversions.h"
52 #include "ui/gfx/vector2d_conversions.h"
56 void DidVisibilityChange(cc::LayerTreeHostImpl
* id
, bool visible
) {
58 TRACE_EVENT_ASYNC_BEGIN1("webkit",
59 "LayerTreeHostImpl::SetVisible",
66 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id
);
69 std::string
ValueToString(scoped_ptr
<base::Value
> value
) {
71 base::JSONWriter::Write(value
.get(), &str
);
79 class LayerTreeHostImplTimeSourceAdapter
: public TimeSourceClient
{
81 static scoped_ptr
<LayerTreeHostImplTimeSourceAdapter
> Create(
82 LayerTreeHostImpl
* layer_tree_host_impl
,
83 scoped_refptr
<DelayBasedTimeSource
> time_source
) {
84 return make_scoped_ptr(
85 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl
,
88 virtual ~LayerTreeHostImplTimeSourceAdapter() {
89 time_source_
->SetClient(NULL
);
90 time_source_
->SetActive(false);
93 virtual void OnTimerTick() OVERRIDE
{
94 // In single threaded mode we attempt to simulate changing the current
95 // thread by maintaining a fake thread id. When we switch from one
96 // thread to another, we construct DebugScopedSetXXXThread objects that
97 // update the thread id. This lets DCHECKS that ensure we're on the
98 // right thread to work correctly in single threaded mode. The problem
99 // here is that the timer tasks are run via the message loop, and when
100 // they run, we've had no chance to construct a DebugScopedSetXXXThread
101 // object. The result is that we report that we're running on the main
102 // thread. In multi-threaded mode, this timer is run on the compositor
103 // thread, so to keep this consistent in single-threaded mode, we'll
104 // construct a DebugScopedSetImplThread object. There is no need to do
105 // this in multi-threaded mode since the real thread id's will be
106 // correct. In fact, setting fake thread id's interferes with the real
107 // thread id's and causes breakage.
108 scoped_ptr
<DebugScopedSetImplThread
> set_impl_thread
;
109 if (!layer_tree_host_impl_
->proxy()->HasImplThread()) {
110 set_impl_thread
.reset(
111 new DebugScopedSetImplThread(layer_tree_host_impl_
->proxy()));
114 layer_tree_host_impl_
->ActivatePendingTreeIfNeeded();
115 layer_tree_host_impl_
->Animate(
116 layer_tree_host_impl_
->CurrentFrameTimeTicks(),
117 layer_tree_host_impl_
->CurrentFrameTime());
118 layer_tree_host_impl_
->UpdateBackgroundAnimateTicking(true);
119 bool start_ready_animations
= true;
120 layer_tree_host_impl_
->UpdateAnimationState(start_ready_animations
);
121 layer_tree_host_impl_
->BeginNextFrame();
124 void SetActive(bool active
) {
125 if (active
!= time_source_
->Active())
126 time_source_
->SetActive(active
);
130 LayerTreeHostImplTimeSourceAdapter(
131 LayerTreeHostImpl
* layer_tree_host_impl
,
132 scoped_refptr
<DelayBasedTimeSource
> time_source
)
133 : layer_tree_host_impl_(layer_tree_host_impl
),
134 time_source_(time_source
) {
135 time_source_
->SetClient(this);
138 LayerTreeHostImpl
* layer_tree_host_impl_
;
139 scoped_refptr
<DelayBasedTimeSource
> time_source_
;
141 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter
);
144 LayerTreeHostImpl::FrameData::FrameData()
145 : contains_incomplete_tile(false), has_no_damage(false) {}
147 LayerTreeHostImpl::FrameData::~FrameData() {}
149 scoped_ptr
<LayerTreeHostImpl
> LayerTreeHostImpl::Create(
150 const LayerTreeSettings
& settings
,
151 LayerTreeHostImplClient
* client
,
153 RenderingStatsInstrumentation
* rendering_stats_instrumentation
) {
154 return make_scoped_ptr(
155 new LayerTreeHostImpl(settings
,
158 rendering_stats_instrumentation
));
161 LayerTreeHostImpl::LayerTreeHostImpl(
162 const LayerTreeSettings
& settings
,
163 LayerTreeHostImplClient
* client
,
165 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
168 did_lock_scrolling_layer_(false),
169 should_bubble_scrolls_(false),
170 wheel_scrolling_(false),
172 overdraw_bottom_height_(0.f
),
173 device_scale_factor_(1.f
),
175 managed_memory_policy_(
176 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
177 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
,
179 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING
),
180 pinch_gesture_active_(false),
181 fps_counter_(FrameRateCounter::Create(proxy_
->HasImplThread())),
182 paint_time_counter_(PaintTimeCounter::Create()),
183 memory_history_(MemoryHistory::Create()),
184 debug_rect_history_(DebugRectHistory::Create()),
185 max_memory_needed_bytes_(0),
186 last_sent_memory_visible_bytes_(0),
187 last_sent_memory_visible_and_nearby_bytes_(0),
188 last_sent_memory_use_bytes_(0),
189 animation_registrar_(AnimationRegistrar::Create()),
190 rendering_stats_instrumentation_(rendering_stats_instrumentation
) {
191 DCHECK(proxy_
->IsImplThread());
192 DidVisibilityChange(this, visible_
);
194 SetDebugState(settings
.initial_debug_state
);
196 if (settings
.calculate_top_controls_position
) {
197 top_controls_manager_
=
198 TopControlsManager::Create(this,
199 settings
.top_controls_height
,
200 settings
.top_controls_show_threshold
,
201 settings
.top_controls_hide_threshold
);
204 SetDebugState(settings
.initial_debug_state
);
206 // LTHI always has an active tree.
207 active_tree_
= LayerTreeImpl::create(this);
210 LayerTreeHostImpl::~LayerTreeHostImpl() {
211 DCHECK(proxy_
->IsImplThread());
212 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
214 if (active_tree_
->root_layer()) {
215 ClearRenderSurfaces();
216 // The layer trees must be destroyed before the layer tree host. We've
217 // made a contract with our animation controllers that the registrar
218 // will outlive them, and we must make good.
219 recycle_tree_
.reset();
220 pending_tree_
.reset();
221 active_tree_
.reset();
225 void LayerTreeHostImpl::BeginCommit() {}
227 void LayerTreeHostImpl::CommitComplete() {
228 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
230 // Impl-side painting needs an update immediately post-commit to have the
231 // opportunity to create tilings. Other paths can call UpdateDrawProperties
232 // more lazily when needed prior to drawing.
233 if (settings_
.impl_side_painting
) {
234 pending_tree_
->set_needs_update_draw_properties();
235 pending_tree_
->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE
);
237 active_tree_
->set_needs_update_draw_properties();
240 client_
->SendManagedMemoryStats();
243 bool LayerTreeHostImpl::CanDraw() {
244 // Note: If you are changing this function or any other function that might
245 // affect the result of CanDraw, make sure to call
246 // client_->OnCanDrawStateChanged in the proper places and update the
247 // NotifyIfCanDrawChanged test.
249 if (!active_tree_
->root_layer()) {
250 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
251 TRACE_EVENT_SCOPE_THREAD
);
254 if (device_viewport_size_
.IsEmpty()) {
255 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
256 TRACE_EVENT_SCOPE_THREAD
);
259 if (active_tree_
->ViewportSizeInvalid()) {
260 TRACE_EVENT_INSTANT0(
261 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed",
262 TRACE_EVENT_SCOPE_THREAD
);
266 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer",
267 TRACE_EVENT_SCOPE_THREAD
);
270 if (active_tree_
->ContentsTexturesPurged()) {
271 TRACE_EVENT_INSTANT0(
272 "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
273 TRACE_EVENT_SCOPE_THREAD
);
279 void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time
,
280 base::Time wall_clock_time
) {
281 AnimatePageScale(monotonic_time
);
282 AnimateLayers(monotonic_time
, wall_clock_time
);
283 AnimateScrollbars(monotonic_time
);
284 AnimateTopControls(monotonic_time
);
287 void LayerTreeHostImpl::ManageTiles() {
288 DCHECK(tile_manager_
);
289 tile_manager_
->ManageTiles();
291 size_t memory_required_bytes
;
292 size_t memory_nice_to_have_bytes
;
293 size_t memory_used_bytes
;
294 tile_manager_
->GetMemoryStats(&memory_required_bytes
,
295 &memory_nice_to_have_bytes
,
297 SendManagedMemoryStats(memory_required_bytes
,
298 memory_nice_to_have_bytes
,
302 void LayerTreeHostImpl::SetAnticipatedDrawTime(base::TimeTicks time
) {
304 tile_manager_
->SetAnticipatedDrawTime(time
);
307 void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset
,
310 base::TimeTicks start_time
,
311 base::TimeDelta duration
) {
312 if (!RootScrollLayer())
315 gfx::Vector2dF scroll_total
=
316 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
317 gfx::SizeF scaled_scrollable_size
= active_tree_
->ScrollableSize();
318 gfx::SizeF viewport_size
= VisibleViewportSize();
320 double start_time_seconds
= (start_time
- base::TimeTicks()).InSecondsF();
322 // Easing constants experimentally determined.
323 scoped_ptr
<TimingFunction
> timing_function
=
324 CubicBezierTimingFunction::Create(.8, 0, .3, .9).PassAs
<TimingFunction
>();
326 page_scale_animation_
=
327 PageScaleAnimation::Create(scroll_total
,
328 active_tree_
->total_page_scale_factor(),
330 scaled_scrollable_size
,
332 timing_function
.Pass());
335 gfx::Vector2dF
anchor(target_offset
);
336 page_scale_animation_
->ZoomWithAnchor(anchor
,
338 duration
.InSecondsF());
340 gfx::Vector2dF scaled_target_offset
= target_offset
;
341 page_scale_animation_
->ZoomTo(scaled_target_offset
,
343 duration
.InSecondsF());
346 client_
->SetNeedsRedrawOnImplThread();
347 client_
->SetNeedsCommitOnImplThread();
348 client_
->RenewTreePriority();
351 void LayerTreeHostImpl::ScheduleAnimation() {
352 client_
->SetNeedsRedrawOnImplThread();
355 bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point
) {
356 if (!EnsureRenderSurfaceLayerList())
359 gfx::PointF device_viewport_point
=
360 gfx::ScalePoint(viewport_point
, device_scale_factor_
);
362 // First find out which layer was hit from the saved list of visible layers
363 // in the most recent frame.
364 LayerImpl
* layer_impl
= LayerTreeHostCommon::FindLayerThatIsHitByPoint(
365 device_viewport_point
,
366 active_tree_
->RenderSurfaceLayerList());
368 // Walk up the hierarchy and look for a layer with a touch event handler
369 // region that the given point hits.
370 for (; layer_impl
; layer_impl
= layer_impl
->parent()) {
371 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point
,
379 void LayerTreeHostImpl::DidReceiveLastInputEventForVSync(
380 base::TimeTicks frame_time
) {
381 client_
->DidReceiveLastInputEventForVSync(frame_time
);
384 void LayerTreeHostImpl::TrackDamageForAllSurfaces(
385 LayerImpl
* root_draw_layer
,
386 const LayerImplList
& render_surface_layer_list
) {
387 // For now, we use damage tracking to compute a global scissor. To do this, we
388 // must compute all damage tracking before drawing anything, so that we know
389 // the root damage rect. The root damage rect is then used to scissor each
392 for (int surface_index
= render_surface_layer_list
.size() - 1;
395 LayerImpl
* render_surface_layer
= render_surface_layer_list
[surface_index
];
396 RenderSurfaceImpl
* render_surface
= render_surface_layer
->render_surface();
397 DCHECK(render_surface
);
398 render_surface
->damage_tracker()->UpdateDamageTrackingState(
399 render_surface
->layer_list(),
400 render_surface_layer
->id(),
401 render_surface
->SurfacePropertyChangedOnlyFromDescendant(),
402 render_surface
->content_rect(),
403 render_surface_layer
->mask_layer(),
404 render_surface_layer
->filters(),
405 render_surface_layer
->filter().get());
409 void LayerTreeHostImpl::FrameData::AppendRenderPass(
410 scoped_ptr
<RenderPass
> render_pass
) {
411 render_passes_by_id
[render_pass
->id
] = render_pass
.get();
412 render_passes
.push_back(render_pass
.Pass());
415 static void AppendQuadsForLayer(RenderPass
* target_render_pass
,
417 const OcclusionTrackerImpl
& occlusion_tracker
,
418 AppendQuadsData
* append_quads_data
) {
419 bool for_surface
= false;
420 QuadCuller
quad_culler(&target_render_pass
->quad_list
,
421 &target_render_pass
->shared_quad_state_list
,
424 layer
->ShowDebugBorders(),
426 layer
->AppendQuads(&quad_culler
, append_quads_data
);
429 static void AppendQuadsForRenderSurfaceLayer(
430 RenderPass
* target_render_pass
,
432 const RenderPass
* contributing_render_pass
,
433 const OcclusionTrackerImpl
& occlusion_tracker
,
434 AppendQuadsData
* append_quads_data
) {
435 bool for_surface
= true;
436 QuadCuller
quad_culler(&target_render_pass
->quad_list
,
437 &target_render_pass
->shared_quad_state_list
,
440 layer
->ShowDebugBorders(),
443 bool is_replica
= false;
444 layer
->render_surface()->AppendQuads(&quad_culler
,
447 contributing_render_pass
->id
);
449 // Add replica after the surface so that it appears below the surface.
450 if (layer
->has_replica()) {
452 layer
->render_surface()->AppendQuads(&quad_culler
,
455 contributing_render_pass
->id
);
459 static void AppendQuadsToFillScreen(
460 RenderPass
* target_render_pass
,
461 LayerImpl
* root_layer
,
462 SkColor screen_background_color
,
463 const OcclusionTrackerImpl
& occlusion_tracker
) {
464 if (!root_layer
|| !SkColorGetA(screen_background_color
))
467 Region fill_region
= occlusion_tracker
.ComputeVisibleRegionInScreen();
468 if (fill_region
.IsEmpty())
471 bool for_surface
= false;
472 QuadCuller
quad_culler(&target_render_pass
->quad_list
,
473 &target_render_pass
->shared_quad_state_list
,
476 root_layer
->ShowDebugBorders(),
479 // Manually create the quad state for the gutter quads, as the root layer
480 // doesn't have any bounds and so can't generate this itself.
481 // TODO(danakj): Make the gutter quads generated by the solid color layer
482 // (make it smarter about generating quads to fill unoccluded areas).
484 gfx::Rect root_target_rect
= root_layer
->render_surface()->content_rect();
486 SharedQuadState
* shared_quad_state
=
487 quad_culler
.UseSharedQuadState(SharedQuadState::Create());
488 shared_quad_state
->SetAll(root_layer
->draw_transform(),
489 root_target_rect
.size(),
495 AppendQuadsData append_quads_data
;
497 gfx::Transform
transform_to_layer_space(gfx::Transform::kSkipInitialization
);
498 bool did_invert
= root_layer
->screen_space_transform().GetInverse(
499 &transform_to_layer_space
);
501 for (Region::Iterator
fill_rects(fill_region
);
502 fill_rects
.has_rect();
504 // The root layer transform is composed of translations and scales only,
505 // no perspective, so mapping is sufficient (as opposed to projecting).
506 gfx::Rect layer_rect
=
507 MathUtil::MapClippedRect(transform_to_layer_space
, fill_rects
.rect());
508 // Skip the quad culler and just append the quads directly to avoid
510 scoped_ptr
<SolidColorDrawQuad
> quad
= SolidColorDrawQuad::Create();
511 quad
->SetNew(shared_quad_state
, layer_rect
, screen_background_color
);
512 quad_culler
.Append(quad
.PassAs
<DrawQuad
>(), &append_quads_data
);
516 bool LayerTreeHostImpl::CalculateRenderPasses(FrameData
* frame
) {
517 DCHECK(frame
->render_passes
.empty());
519 if (!CanDraw() || !active_tree_
->root_layer())
522 TrackDamageForAllSurfaces(active_tree_
->root_layer(),
523 *frame
->render_surface_layer_list
);
525 // If the root render surface has no visible damage, then don't generate a
527 RenderSurfaceImpl
* root_surface
=
528 active_tree_
->root_layer()->render_surface();
529 bool root_surface_has_no_visible_damage
=
530 !root_surface
->damage_tracker()->current_damage_rect().Intersects(
531 root_surface
->content_rect());
532 bool root_surface_has_contributing_layers
=
533 !root_surface
->layer_list().empty();
534 if (root_surface_has_contributing_layers
&&
535 root_surface_has_no_visible_damage
) {
537 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
538 frame
->has_no_damage
= true;
543 "LayerTreeHostImpl::CalculateRenderPasses",
544 "render_surface_layer_list.size()",
545 static_cast<uint64
>(frame
->render_surface_layer_list
->size()));
547 // Create the render passes in dependency order.
548 for (int surface_index
= frame
->render_surface_layer_list
->size() - 1;
551 LayerImpl
* render_surface_layer
=
552 (*frame
->render_surface_layer_list
)[surface_index
];
553 render_surface_layer
->render_surface()->AppendRenderPasses(frame
);
556 bool record_metrics_for_frame
=
557 settings_
.show_overdraw_in_tracing
&&
558 base::debug::TraceLog::GetInstance() &&
559 base::debug::TraceLog::GetInstance()->IsEnabled();
560 OcclusionTrackerImpl
occlusion_tracker(
561 active_tree_
->root_layer()->render_surface()->content_rect(),
562 record_metrics_for_frame
);
563 occlusion_tracker
.set_minimum_tracking_size(
564 settings_
.minimum_occlusion_tracking_size
);
566 if (debug_state_
.show_occluding_rects
) {
567 occlusion_tracker
.set_occluding_screen_space_rects_container(
568 &frame
->occluding_screen_space_rects
);
570 if (debug_state_
.show_non_occluding_rects
) {
571 occlusion_tracker
.set_non_occluding_screen_space_rects_container(
572 &frame
->non_occluding_screen_space_rects
);
575 // Add quads to the Render passes in FrontToBack order to allow for testing
576 // occlusion and performing culling during the tree walk.
577 typedef LayerIterator
<LayerImpl
,
580 LayerIteratorActions::FrontToBack
> LayerIteratorType
;
582 // Typically when we are missing a texture and use a checkerboard quad, we
583 // still draw the frame. However when the layer being checkerboarded is moving
584 // due to an impl-animation, we drop the frame to avoid flashing due to the
585 // texture suddenly appearing in the future.
586 bool draw_frame
= true;
587 // When we have a copy request for a layer, we need to draw no matter
588 // what, as the layer may disappear after this frame.
589 bool have_copy_request
= false;
591 int layers_drawn
= 0;
593 LayerIteratorType end
=
594 LayerIteratorType::End(frame
->render_surface_layer_list
);
595 for (LayerIteratorType it
=
596 LayerIteratorType::Begin(frame
->render_surface_layer_list
);
599 RenderPass::Id target_render_pass_id
=
600 it
.target_render_surface_layer()->render_surface()->RenderPassId();
601 RenderPass
* target_render_pass
=
602 frame
->render_passes_by_id
[target_render_pass_id
];
604 bool prevent_occlusion
=
605 it
.target_render_surface_layer()->HasRequestCopyCallback();
606 occlusion_tracker
.EnterLayer(it
, prevent_occlusion
);
608 AppendQuadsData
append_quads_data(target_render_pass
->id
);
610 if (it
.represents_target_render_surface()) {
611 if (it
->HasRequestCopyCallback()) {
612 have_copy_request
= true;
613 it
->TakeRequestCopyCallbacks(&target_render_pass
->copy_callbacks
);
615 } else if (it
.represents_contributing_render_surface()) {
616 RenderPass::Id contributing_render_pass_id
=
617 it
->render_surface()->RenderPassId();
618 RenderPass
* contributing_render_pass
=
619 frame
->render_passes_by_id
[contributing_render_pass_id
];
620 AppendQuadsForRenderSurfaceLayer(target_render_pass
,
622 contributing_render_pass
,
625 } else if (it
.represents_itself() &&
626 !it
->visible_content_rect().IsEmpty()) {
627 bool has_occlusion_from_outside_target_surface
;
628 bool impl_draw_transform_is_unknown
= false;
629 if (occlusion_tracker
.Occluded(
631 it
->visible_content_rect(),
632 it
->draw_transform(),
633 impl_draw_transform_is_unknown
,
636 &has_occlusion_from_outside_target_surface
)) {
637 append_quads_data
.had_occlusion_from_outside_target_surface
|=
638 has_occlusion_from_outside_target_surface
;
640 DCHECK_EQ(active_tree_
, it
->layer_tree_impl());
641 it
->WillDraw(resource_provider_
.get());
642 frame
->will_draw_layers
.push_back(*it
);
644 if (it
->HasContributingDelegatedRenderPasses()) {
645 RenderPass::Id contributing_render_pass_id
=
646 it
->FirstContributingRenderPassId();
647 while (frame
->render_passes_by_id
.find(contributing_render_pass_id
) !=
648 frame
->render_passes_by_id
.end()) {
649 RenderPass
* render_pass
=
650 frame
->render_passes_by_id
[contributing_render_pass_id
];
652 AppendQuadsData
append_quads_data(render_pass
->id
);
653 AppendQuadsForLayer(render_pass
,
658 contributing_render_pass_id
=
659 it
->NextContributingRenderPassId(contributing_render_pass_id
);
663 AppendQuadsForLayer(target_render_pass
,
672 if (append_quads_data
.had_occlusion_from_outside_target_surface
)
673 target_render_pass
->has_occlusion_from_outside_target_surface
= true;
675 if (append_quads_data
.num_missing_tiles
) {
676 rendering_stats_instrumentation_
->AddMissingTiles(
677 append_quads_data
.num_missing_tiles
);
678 bool layer_has_animating_transform
=
679 it
->screen_space_transform_is_animating() ||
680 it
->draw_transform_is_animating();
681 if (layer_has_animating_transform
)
685 if (append_quads_data
.had_incomplete_tile
)
686 frame
->contains_incomplete_tile
= true;
688 occlusion_tracker
.LeaveLayer(it
);
691 if (have_copy_request
)
694 rendering_stats_instrumentation_
->AddLayersDrawn(layers_drawn
);
697 for (size_t i
= 0; i
< frame
->render_passes
.size(); ++i
) {
698 for (size_t j
= 0; j
< frame
->render_passes
[i
]->quad_list
.size(); ++j
)
699 DCHECK(frame
->render_passes
[i
]->quad_list
[j
]->shared_quad_state
);
700 DCHECK(frame
->render_passes_by_id
.find(frame
->render_passes
[i
]->id
)
701 != frame
->render_passes_by_id
.end());
704 DCHECK(frame
->render_passes
.back()->output_rect
.origin().IsOrigin());
706 if (!active_tree_
->has_transparent_background()) {
707 frame
->render_passes
.back()->has_transparent_background
= false;
708 AppendQuadsToFillScreen(frame
->render_passes
.back(),
709 active_tree_
->root_layer(),
710 active_tree_
->background_color(),
715 occlusion_tracker
.overdraw_metrics()->RecordMetrics(this);
717 DCHECK(!have_copy_request
);
719 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame
);
720 renderer_
->DecideRenderPassAllocationsForFrame(frame
->render_passes
);
721 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_
.get()),
724 // If we're making a frame to draw, it better have at least one render pass.
725 DCHECK(!frame
->render_passes
.empty());
729 void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
730 bool should_background_tick
) {
731 bool enabled
= should_background_tick
&&
732 !animation_registrar_
->active_animation_controllers().empty();
734 // Lazily create the time_source adapter so that we can vary the interval for
736 if (!time_source_client_adapter_
) {
737 time_source_client_adapter_
= LayerTreeHostImplTimeSourceAdapter::Create(
739 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
740 proxy_
->CurrentThread()));
743 time_source_client_adapter_
->SetActive(enabled
);
746 void LayerTreeHostImpl::SetViewportDamage(gfx::Rect damage_rect
) {
747 viewport_damage_rect_
.Union(damage_rect
);
750 static inline RenderPass
* FindRenderPassById(
751 RenderPass::Id render_pass_id
,
752 const LayerTreeHostImpl::FrameData
& frame
) {
753 RenderPassIdHashMap::const_iterator it
=
754 frame
.render_passes_by_id
.find(render_pass_id
);
755 return it
!= frame
.render_passes_by_id
.end() ? it
->second
: NULL
;
758 static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id
,
759 LayerTreeHostImpl::FrameData
* frame
) {
760 RenderPass
* remove_render_pass
=
761 FindRenderPassById(remove_render_pass_id
, *frame
);
762 // The pass was already removed by another quad - probably the original, and
763 // we are the replica.
764 if (!remove_render_pass
)
766 RenderPassList
& render_passes
= frame
->render_passes
;
767 RenderPassList::iterator to_remove
= std::find(render_passes
.begin(),
771 DCHECK(to_remove
!= render_passes
.end());
773 scoped_ptr
<RenderPass
> removed_pass
= render_passes
.take(to_remove
);
774 frame
->render_passes
.erase(to_remove
);
775 frame
->render_passes_by_id
.erase(remove_render_pass_id
);
777 // Now follow up for all RenderPass quads and remove their RenderPasses
779 const QuadList
& quad_list
= removed_pass
->quad_list
;
780 QuadList::ConstBackToFrontIterator quad_list_iterator
=
781 quad_list
.BackToFrontBegin();
782 for (; quad_list_iterator
!= quad_list
.BackToFrontEnd();
783 ++quad_list_iterator
) {
784 DrawQuad
* current_quad
= (*quad_list_iterator
);
785 if (current_quad
->material
!= DrawQuad::RENDER_PASS
)
788 RenderPass::Id next_remove_render_pass_id
=
789 RenderPassDrawQuad::MaterialCast(current_quad
)->render_pass_id
;
790 RemoveRenderPassesRecursive(next_remove_render_pass_id
, frame
);
794 bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
795 ShouldRemoveRenderPass(const RenderPassDrawQuad
& quad
,
796 const FrameData
& frame
) const {
797 bool quad_has_damage
= !quad
.contents_changed_since_last_frame
.IsEmpty();
798 bool quad_has_cached_resource
=
799 renderer_
->HaveCachedResourcesForRenderPassId(quad
.render_pass_id
);
800 if (quad_has_damage
) {
801 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
803 } else if (!quad_has_cached_resource
) {
804 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
807 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
811 bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
812 const RenderPassDrawQuad
& quad
, const FrameData
& frame
) const {
813 const RenderPass
* render_pass
=
814 FindRenderPassById(quad
.render_pass_id
, frame
);
818 // If any quad or RenderPass draws into this RenderPass, then keep it.
819 const QuadList
& quad_list
= render_pass
->quad_list
;
820 for (QuadList::ConstBackToFrontIterator quad_list_iterator
=
821 quad_list
.BackToFrontBegin();
822 quad_list_iterator
!= quad_list
.BackToFrontEnd();
823 ++quad_list_iterator
) {
824 DrawQuad
* current_quad
= *quad_list_iterator
;
826 if (current_quad
->material
!= DrawQuad::RENDER_PASS
)
829 const RenderPass
* contributing_pass
= FindRenderPassById(
830 RenderPassDrawQuad::MaterialCast(current_quad
)->render_pass_id
, frame
);
831 if (contributing_pass
)
837 // Defined for linking tests.
838 template CC_EXPORT
void LayerTreeHostImpl::RemoveRenderPasses
<
839 LayerTreeHostImpl::CullRenderPassesWithCachedTextures
>(
840 CullRenderPassesWithCachedTextures culler
, FrameData
* frame
);
841 template CC_EXPORT
void LayerTreeHostImpl::RemoveRenderPasses
<
842 LayerTreeHostImpl::CullRenderPassesWithNoQuads
>(
843 CullRenderPassesWithNoQuads culler
, FrameData
*);
846 template <typename RenderPassCuller
>
847 void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler
,
849 for (size_t it
= culler
.RenderPassListBegin(frame
->render_passes
);
850 it
!= culler
.RenderPassListEnd(frame
->render_passes
);
851 it
= culler
.RenderPassListNext(it
)) {
852 const RenderPass
* current_pass
= frame
->render_passes
[it
];
853 const QuadList
& quad_list
= current_pass
->quad_list
;
854 QuadList::ConstBackToFrontIterator quad_list_iterator
=
855 quad_list
.BackToFrontBegin();
857 for (; quad_list_iterator
!= quad_list
.BackToFrontEnd();
858 ++quad_list_iterator
) {
859 DrawQuad
* current_quad
= *quad_list_iterator
;
861 if (current_quad
->material
!= DrawQuad::RENDER_PASS
)
864 const RenderPassDrawQuad
* render_pass_quad
=
865 RenderPassDrawQuad::MaterialCast(current_quad
);
866 if (!culler
.ShouldRemoveRenderPass(*render_pass_quad
, *frame
))
869 // We are changing the vector in the middle of iteration. Because we
870 // delete render passes that draw into the current pass, we are
871 // guaranteed that any data from the iterator to the end will not
872 // change. So, capture the iterator position from the end of the
873 // list, and restore it after the change.
874 size_t position_from_end
= frame
->render_passes
.size() - it
;
875 RemoveRenderPassesRecursive(render_pass_quad
->render_pass_id
, frame
);
876 it
= frame
->render_passes
.size() - position_from_end
;
877 DCHECK_GE(frame
->render_passes
.size(), position_from_end
);
882 bool LayerTreeHostImpl::PrepareToDraw(FrameData
* frame
,
883 gfx::Rect device_viewport_damage_rect
) {
884 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
886 active_tree_
->UpdateDrawProperties(
887 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW
);
889 frame
->render_surface_layer_list
= &active_tree_
->RenderSurfaceLayerList();
890 frame
->render_passes
.clear();
891 frame
->render_passes_by_id
.clear();
892 frame
->will_draw_layers
.clear();
893 frame
->contains_incomplete_tile
= false;
894 frame
->has_no_damage
= false;
896 if (active_tree_
->root_layer()) {
897 device_viewport_damage_rect
.Union(viewport_damage_rect_
);
898 viewport_damage_rect_
= gfx::Rect();
900 active_tree_
->root_layer()->render_surface()->damage_tracker()->
901 AddDamageNextUpdate(device_viewport_damage_rect
);
904 if (!CalculateRenderPasses(frame
))
907 frame
->latency_info
= active_tree_
->GetLatencyInfo();
909 // If we return true, then we expect DrawLayers() to be called before this
910 // function is called again.
914 void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
915 const ManagedMemoryPolicy
& policy
) {
916 bool evicted_resources
= client_
->ReduceContentsTextureMemoryOnImplThread(
917 visible_
? policy
.bytes_limit_when_visible
918 : policy
.bytes_limit_when_not_visible
,
919 ManagedMemoryPolicy::PriorityCutoffToValue(
920 visible_
? policy
.priority_cutoff_when_visible
921 : policy
.priority_cutoff_when_not_visible
));
922 if (evicted_resources
) {
923 active_tree_
->SetContentsTexturesPurged();
925 pending_tree_
->SetContentsTexturesPurged();
926 client_
->SetNeedsCommitOnImplThread();
927 client_
->OnCanDrawStateChanged(CanDraw());
928 client_
->RenewTreePriority();
930 client_
->SendManagedMemoryStats();
933 GlobalStateThatImpactsTilePriority
new_state(tile_manager_
->GlobalState());
934 new_state
.memory_limit_in_bytes
= visible_
?
935 policy
.bytes_limit_when_visible
:
936 policy
.bytes_limit_when_not_visible
;
937 // TODO(reveman): We should avoid keeping around unused resources if
938 // possible. crbug.com/224475
939 new_state
.unused_memory_limit_in_bytes
= static_cast<size_t>(
940 (static_cast<int64
>(new_state
.memory_limit_in_bytes
) *
941 settings_
.max_unused_resource_memory_percentage
) / 100);
942 new_state
.memory_limit_policy
=
943 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
945 policy
.priority_cutoff_when_visible
:
946 policy
.priority_cutoff_when_not_visible
);
947 tile_manager_
->SetGlobalState(new_state
);
951 bool LayerTreeHostImpl::HasImplThread() const {
952 return proxy_
->HasImplThread();
955 void LayerTreeHostImpl::ScheduleManageTiles() {
957 client_
->SetNeedsManageTilesOnImplThread();
960 void LayerTreeHostImpl::DidInitializeVisibleTile() {
961 // TODO(reveman): Determine tiles that changed and only damage
963 SetFullRootLayerDamage();
965 client_
->DidInitializeVisibleTileOnImplThread();
968 bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
969 return settings_
.should_clear_root_render_pass
;
972 void LayerTreeHostImpl::SetManagedMemoryPolicy(
973 const ManagedMemoryPolicy
& policy
) {
974 if (managed_memory_policy_
== policy
)
977 // If there is already enough memory to draw everything imaginable and the
978 // new memory limit does not change this, then do not re-commit. Don't bother
979 // skipping commits if this is not visible (commits don't happen when not
980 // visible, there will almost always be a commit when this becomes visible).
981 bool needs_commit
= true;
983 policy
.bytes_limit_when_visible
>=
984 max_memory_needed_bytes_
&&
985 managed_memory_policy_
.bytes_limit_when_visible
>=
986 max_memory_needed_bytes_
&&
987 policy
.priority_cutoff_when_visible
==
988 managed_memory_policy_
.priority_cutoff_when_visible
) {
989 needs_commit
= false;
992 managed_memory_policy_
= policy
;
993 if (!proxy_
->HasImplThread()) {
994 // In single-thread mode, this can be called on the main thread by
995 // GLRenderer::OnMemoryAllocationChanged.
996 DebugScopedSetImplThread
impl_thread(proxy_
);
997 EnforceManagedMemoryPolicy(managed_memory_policy_
);
999 DCHECK(proxy_
->IsImplThread());
1000 EnforceManagedMemoryPolicy(managed_memory_policy_
);
1004 client_
->SetNeedsCommitOnImplThread();
1007 void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect
) {
1008 client_
->SetNeedsRedrawRectOnImplThread(damage_rect
);
1011 void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase
,
1012 base::TimeDelta interval
) {
1013 client_
->OnVSyncParametersChanged(timebase
, interval
);
1016 void LayerTreeHostImpl::DidVSync(base::TimeTicks frame_time
) {
1017 client_
->DidVSync(frame_time
);
1020 void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
1021 const CompositorFrameAck
& ack
) {
1025 // TODO(piman): We may need to do some validation on this ack before
1027 renderer_
->ReceiveCompositorFrameAck(ack
);
1029 // When using compositor frame data, the ack doubles as a swap complete ack.
1030 OnSwapBuffersComplete();
1033 void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
1034 client_
->OnCanDrawStateChanged(CanDraw());
1037 CompositorFrameMetadata
LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
1038 CompositorFrameMetadata metadata
;
1039 metadata
.device_scale_factor
= device_scale_factor_
;
1040 metadata
.page_scale_factor
= active_tree_
->total_page_scale_factor();
1041 metadata
.viewport_size
= active_tree_
->ScrollableViewportSize();
1042 metadata
.root_layer_size
= active_tree_
->ScrollableSize();
1043 metadata
.min_page_scale_factor
= active_tree_
->min_page_scale_factor();
1044 metadata
.max_page_scale_factor
= active_tree_
->max_page_scale_factor();
1045 if (top_controls_manager_
) {
1046 metadata
.location_bar_offset
=
1047 gfx::Vector2dF(0.f
, top_controls_manager_
->controls_top_offset());
1048 metadata
.location_bar_content_translation
=
1049 gfx::Vector2dF(0.f
, top_controls_manager_
->content_top_offset());
1050 metadata
.overdraw_bottom_height
= overdraw_bottom_height_
;
1053 if (!RootScrollLayer())
1056 metadata
.root_scroll_offset
= RootScrollLayer()->TotalScrollOffset();
1057 metadata
.latency_info
= active_tree_
->GetLatencyInfo();
1062 bool LayerTreeHostImpl::AllowPartialSwap() const {
1063 // We don't track damage on the HUD layer (it interacts with damage tracking
1064 // visualizations), so disable partial swaps to make the HUD layer display
1066 return !debug_state_
.ShowHudRects();
1069 void LayerTreeHostImpl::DrawLayers(FrameData
* frame
,
1070 base::TimeTicks frame_begin_time
) {
1071 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
1074 if (frame
->has_no_damage
)
1077 DCHECK(!frame
->render_passes
.empty());
1079 fps_counter_
->SaveTimeStamp(frame_begin_time
);
1081 rendering_stats_instrumentation_
->SetScreenFrameCount(
1082 fps_counter_
->current_frame_number());
1083 rendering_stats_instrumentation_
->SetDroppedFrameCount(
1084 fps_counter_
->dropped_frame_count());
1086 if (tile_manager_
) {
1087 memory_history_
->SaveEntry(
1088 tile_manager_
->memory_stats_from_last_assign());
1091 if (debug_state_
.ShowHudRects()) {
1092 debug_rect_history_
->SaveDebugRectsForCurrentFrame(
1093 active_tree_
->root_layer(),
1094 *frame
->render_surface_layer_list
,
1095 frame
->occluding_screen_space_rects
,
1096 frame
->non_occluding_screen_space_rects
,
1100 if (!settings_
.impl_side_painting
&& debug_state_
.continuous_painting
) {
1101 const RenderingStats
& stats
=
1102 rendering_stats_instrumentation_
->GetRenderingStats();
1103 paint_time_counter_
->SavePaintTime(stats
.total_paint_time
);
1106 if (debug_state_
.trace_all_rendered_frames
) {
1107 TRACE_EVENT_INSTANT1("cc.debug", "Frame", TRACE_EVENT_SCOPE_THREAD
,
1108 "frame", ValueToString(FrameStateAsValue()));
1111 // Because the contents of the HUD depend on everything else in the frame, the
1112 // contents of its texture are updated as the last thing before the frame is
1114 if (active_tree_
->hud_layer())
1115 active_tree_
->hud_layer()->UpdateHudTexture(resource_provider_
.get());
1117 renderer_
->DrawFrame(&frame
->render_passes
);
1118 // The render passes should be consumed by the renderer.
1119 DCHECK(frame
->render_passes
.empty());
1120 frame
->render_passes_by_id
.clear();
1122 // The next frame should start by assuming nothing has changed, and changes
1123 // are noted as they occur.
1124 for (size_t i
= 0; i
< frame
->render_surface_layer_list
->size(); i
++) {
1125 (*frame
->render_surface_layer_list
)[i
]->render_surface()->damage_tracker()->
1126 DidDrawDamagedArea();
1128 active_tree_
->root_layer()->ResetAllChangeTrackingForSubtree();
1131 void LayerTreeHostImpl::DidDrawAllLayers(const FrameData
& frame
) {
1132 for (size_t i
= 0; i
< frame
.will_draw_layers
.size(); ++i
)
1133 frame
.will_draw_layers
[i
]->DidDraw(resource_provider_
.get());
1135 // Once all layers have been drawn, pending texture uploads should no
1136 // longer block future uploads.
1137 resource_provider_
->MarkPendingUploadsAsNonBlocking();
1140 void LayerTreeHostImpl::FinishAllRendering() {
1142 renderer_
->Finish();
1145 bool LayerTreeHostImpl::IsContextLost() {
1146 DCHECK(proxy_
->IsImplThread());
1147 return renderer_
&& renderer_
->IsContextLost();
1150 const RendererCapabilities
& LayerTreeHostImpl::GetRendererCapabilities() const {
1151 return renderer_
->Capabilities();
1154 bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData
& frame
) {
1155 if (frame
.has_no_damage
)
1157 bool result
= renderer_
->SwapBuffers(frame
.latency_info
);
1159 active_tree_
->ClearLatencyInfo();
1163 void LayerTreeHostImpl::EnableVSyncNotification(bool enable
) {
1164 if (output_surface_
)
1165 output_surface_
->EnableVSyncNotification(enable
);
1168 gfx::Size
LayerTreeHostImpl::DeviceViewportSize() const {
1169 return device_viewport_size();
1172 gfx::SizeF
LayerTreeHostImpl::VisibleViewportSize() const {
1173 gfx::SizeF dip_size
=
1174 gfx::ScaleSize(DeviceViewportSize(), 1.f
/ device_scale_factor());
1176 // The clip layer should be used if non-overlay scrollbars may exist since
1177 // it adjusts for them.
1178 LayerImpl
* clip_layer
= active_tree_
->RootClipLayer();
1179 if (!Settings().solid_color_scrollbars
&& clip_layer
&&
1180 clip_layer
->masks_to_bounds())
1181 dip_size
= clip_layer
->bounds();
1184 top_controls_manager_
? top_controls_manager_
->content_top_offset() : 0.f
;
1185 return gfx::SizeF(dip_size
.width(),
1186 dip_size
.height() - top_offset
- overdraw_bottom_height_
);
1189 const LayerTreeSettings
& LayerTreeHostImpl::Settings() const {
1193 void LayerTreeHostImpl::DidLoseOutputSurface() {
1194 // TODO(jamesr): The renderer_ check is needed to make some of the
1195 // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or
1196 // important) in production. We should adjust the test to not need this.
1198 client_
->DidLoseOutputSurfaceOnImplThread();
1201 void LayerTreeHostImpl::OnSwapBuffersComplete() {
1202 client_
->OnSwapBuffersCompleteOnImplThread();
1205 void LayerTreeHostImpl::Readback(void* pixels
,
1206 gfx::Rect rect_in_device_viewport
) {
1208 renderer_
->GetFramebufferPixels(pixels
, rect_in_device_viewport
);
1211 bool LayerTreeHostImpl::HaveRootScrollLayer() const {
1212 return !!RootScrollLayer();
1215 LayerImpl
* LayerTreeHostImpl::RootLayer() const {
1216 return active_tree_
->root_layer();
1219 LayerImpl
* LayerTreeHostImpl::RootScrollLayer() const {
1220 return active_tree_
->RootScrollLayer();
1223 LayerImpl
* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1224 return active_tree_
->CurrentlyScrollingLayer();
1227 // Content layers can be either directly scrollable or contained in an outer
1228 // scrolling layer which applies the scroll transform. Given a content layer,
1229 // this function returns the associated scroll layer if any.
1230 static LayerImpl
* FindScrollLayerForContentLayer(LayerImpl
* layer_impl
) {
1234 if (layer_impl
->scrollable())
1237 if (layer_impl
->DrawsContent() &&
1238 layer_impl
->parent() &&
1239 layer_impl
->parent()->scrollable())
1240 return layer_impl
->parent();
1245 void LayerTreeHostImpl::CreatePendingTree() {
1246 CHECK(!pending_tree_
);
1248 recycle_tree_
.swap(pending_tree_
);
1250 pending_tree_
= LayerTreeImpl::create(this);
1251 client_
->OnCanDrawStateChanged(CanDraw());
1252 client_
->OnHasPendingTreeStateChanged(pending_tree_
);
1253 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_
.get());
1254 TRACE_EVENT_ASYNC_STEP0("cc",
1255 "PendingTree", pending_tree_
.get(), "waiting");
1258 void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1259 DCHECK(!client_
->IsInsideDraw()) <<
1260 "Checking for completed uploads within a draw may trigger "
1261 "spurious redraws.";
1263 tile_manager_
->CheckForCompletedTileUploads();
1266 bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1270 CHECK(tile_manager_
);
1272 pending_tree_
->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE
);
1274 TRACE_EVENT_ASYNC_STEP1("cc",
1275 "PendingTree", pending_tree_
.get(), "activate",
1276 "state", ValueToString(ActivationStateAsValue()));
1278 // Activate once all visible resources in pending tree are ready.
1279 if (!pending_tree_
->AreVisibleResourcesReady())
1282 ActivatePendingTree();
1286 void LayerTreeHostImpl::ActivatePendingTree() {
1287 CHECK(pending_tree_
);
1288 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_
.get());
1290 active_tree_
->PushPersistedState(pending_tree_
.get());
1291 if (pending_tree_
->needs_full_tree_sync()) {
1292 active_tree_
->SetRootLayer(
1293 TreeSynchronizer::SynchronizeTrees(pending_tree_
->root_layer(),
1294 active_tree_
->DetachLayerTree(),
1295 active_tree_
.get()));
1297 TreeSynchronizer::PushProperties(pending_tree_
->root_layer(),
1298 active_tree_
->root_layer());
1299 DCHECK(!recycle_tree_
);
1301 pending_tree_
->PushPropertiesTo(active_tree_
.get());
1303 // Now that we've synced everything from the pending tree to the active
1304 // tree, rename the pending tree the recycle tree so we can reuse it on the
1306 pending_tree_
.swap(recycle_tree_
);
1307 recycle_tree_
->ClearRenderSurfaces();
1309 active_tree_
->DidBecomeActive();
1311 // Reduce wasted memory now that unlinked resources are guaranteed not
1313 client_
->ReduceWastedContentsTextureMemoryOnImplThread();
1315 client_
->OnCanDrawStateChanged(CanDraw());
1316 client_
->OnHasPendingTreeStateChanged(pending_tree_
);
1317 client_
->SetNeedsRedrawOnImplThread();
1318 client_
->RenewTreePriority();
1320 if (debug_state_
.continuous_painting
) {
1321 const RenderingStats
& stats
=
1322 rendering_stats_instrumentation_
->GetRenderingStats();
1323 paint_time_counter_
->SavePaintTime(
1324 stats
.total_paint_time
+ stats
.total_record_time
+
1325 stats
.total_rasterize_time_for_now_bins_on_pending_tree
);
1329 void LayerTreeHostImpl::SetVisible(bool visible
) {
1330 DCHECK(proxy_
->IsImplThread());
1332 if (visible_
== visible
)
1335 DidVisibilityChange(this, visible_
);
1336 EnforceManagedMemoryPolicy(managed_memory_policy_
);
1341 renderer_
->SetVisible(visible
);
1344 bool LayerTreeHostImpl::InitializeRenderer(
1345 scoped_ptr
<OutputSurface
> output_surface
) {
1346 // Since we will create a new resource provider, we cannot continue to use
1347 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1348 // before we destroy the old resource provider.
1349 if (active_tree_
->root_layer())
1350 ClearRenderSurfaces();
1351 if (active_tree_
->root_layer())
1352 SendDidLoseOutputSurfaceRecursive(active_tree_
->root_layer());
1353 if (pending_tree_
&& pending_tree_
->root_layer())
1354 SendDidLoseOutputSurfaceRecursive(pending_tree_
->root_layer());
1355 if (recycle_tree_
&& recycle_tree_
->root_layer())
1356 SendDidLoseOutputSurfaceRecursive(recycle_tree_
->root_layer());
1357 if (resource_provider_
)
1358 resource_provider_
->DidLoseOutputSurface();
1360 // Note: order is important here.
1362 tile_manager_
.reset();
1363 resource_provider_
.reset();
1364 output_surface_
.reset();
1366 if (!output_surface
->BindToClient(this))
1369 scoped_ptr
<ResourceProvider
> resource_provider
= ResourceProvider::Create(
1370 output_surface
.get(), settings_
.highp_threshold_min
);
1371 if (!resource_provider
)
1374 if (settings_
.impl_side_painting
) {
1375 tile_manager_
.reset(new TileManager(this,
1376 resource_provider
.get(),
1377 settings_
.num_raster_threads
,
1378 settings_
.use_cheapness_estimator
,
1379 settings_
.use_color_estimator
,
1380 settings_
.prediction_benchmarking
,
1381 rendering_stats_instrumentation_
));
1384 if (output_surface
->capabilities().has_parent_compositor
) {
1385 renderer_
= DelegatingRenderer::Create(this, output_surface
.get(),
1386 resource_provider
.get());
1387 } else if (output_surface
->context3d()) {
1388 renderer_
= GLRenderer::Create(this,
1389 output_surface
.get(),
1390 resource_provider
.get(),
1391 settings_
.highp_threshold_min
);
1392 } else if (output_surface
->software_device()) {
1393 renderer_
= SoftwareRenderer::Create(this,
1394 output_surface
.get(),
1395 resource_provider
.get());
1400 resource_provider_
= resource_provider
.Pass();
1401 output_surface_
= output_surface
.Pass();
1404 renderer_
->SetVisible(visible_
);
1406 client_
->OnCanDrawStateChanged(CanDraw());
1408 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1409 // to be initialized to get max texture size.
1410 active_tree_
->set_needs_update_draw_properties();
1412 pending_tree_
->set_needs_update_draw_properties();
1417 void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size
) {
1418 if (device_viewport_size
== device_viewport_size_
)
1421 if (pending_tree_
&& device_viewport_size_
!= device_viewport_size
)
1422 active_tree_
->SetViewportSizeInvalid();
1424 device_viewport_size_
= device_viewport_size
;
1426 UpdateMaxScrollOffset();
1429 renderer_
->ViewportChanged();
1431 client_
->OnCanDrawStateChanged(CanDraw());
1432 SetFullRootLayerDamage();
1435 void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height
) {
1436 if (overdraw_bottom_height
== overdraw_bottom_height_
)
1438 overdraw_bottom_height_
= overdraw_bottom_height
;
1440 UpdateMaxScrollOffset();
1441 SetFullRootLayerDamage();
1444 void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor
) {
1445 if (device_scale_factor
== device_scale_factor_
)
1447 device_scale_factor_
= device_scale_factor
;
1449 UpdateMaxScrollOffset();
1450 SetFullRootLayerDamage();
1453 void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1454 active_tree_
->UpdateMaxScrollOffset();
1457 void LayerTreeHostImpl::DidChangeTopControlsPosition() {
1458 client_
->SetNeedsRedrawOnImplThread();
1459 active_tree_
->set_needs_update_draw_properties();
1460 SetFullRootLayerDamage();
1463 bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1464 active_tree_
->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE
);
1465 return !active_tree_
->RenderSurfaceLayerList().empty();
1468 InputHandlerClient::ScrollStatus
LayerTreeHostImpl::ScrollBegin(
1469 gfx::Point viewport_point
, InputHandlerClient::ScrollInputType type
) {
1470 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
1472 if (top_controls_manager_
)
1473 top_controls_manager_
->ScrollBegin();
1475 DCHECK(!CurrentlyScrollingLayer());
1476 ClearCurrentlyScrollingLayer();
1478 if (!EnsureRenderSurfaceLayerList())
1479 return ScrollIgnored
;
1481 gfx::PointF device_viewport_point
= gfx::ScalePoint(viewport_point
,
1482 device_scale_factor_
);
1484 // First find out which layer was hit from the saved list of visible layers
1485 // in the most recent frame.
1486 LayerImpl
* layer_impl
= LayerTreeHostCommon::FindLayerThatIsHitByPoint(
1487 device_viewport_point
, active_tree_
->RenderSurfaceLayerList());
1489 // Walk up the hierarchy and look for a scrollable layer.
1490 LayerImpl
* potentially_scrolling_layer_impl
= 0;
1491 for (; layer_impl
; layer_impl
= layer_impl
->parent()) {
1492 // The content layer can also block attempts to scroll outside the main
1494 ScrollStatus status
= layer_impl
->TryScroll(device_viewport_point
, type
);
1495 if (status
== ScrollOnMainThread
) {
1496 rendering_stats_instrumentation_
->IncrementMainThreadScrolls();
1497 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
1498 active_tree()->DidBeginScroll();
1499 return ScrollOnMainThread
;
1502 LayerImpl
* scroll_layer_impl
= FindScrollLayerForContentLayer(layer_impl
);
1503 if (!scroll_layer_impl
)
1506 status
= scroll_layer_impl
->TryScroll(device_viewport_point
, type
);
1508 // If any layer wants to divert the scroll event to the main thread, abort.
1509 if (status
== ScrollOnMainThread
) {
1510 rendering_stats_instrumentation_
->IncrementMainThreadScrolls();
1511 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
1512 active_tree()->DidBeginScroll();
1513 return ScrollOnMainThread
;
1516 if (status
== ScrollStarted
&& !potentially_scrolling_layer_impl
)
1517 potentially_scrolling_layer_impl
= scroll_layer_impl
;
1520 // When hiding top controls is enabled and the controls are hidden or
1521 // overlaying the content, force scrolls to be enabled on the root layer to
1522 // allow bringing the top controls back into view.
1523 if (!potentially_scrolling_layer_impl
&& top_controls_manager_
&&
1524 top_controls_manager_
->content_top_offset() !=
1525 settings_
.top_controls_height
) {
1526 potentially_scrolling_layer_impl
= RootScrollLayer();
1529 if (potentially_scrolling_layer_impl
) {
1530 active_tree_
->SetCurrentlyScrollingLayer(
1531 potentially_scrolling_layer_impl
);
1532 should_bubble_scrolls_
= (type
!= NonBubblingGesture
);
1533 wheel_scrolling_
= (type
== Wheel
);
1534 rendering_stats_instrumentation_
->IncrementImplThreadScrolls();
1535 client_
->RenewTreePriority();
1536 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
1537 active_tree()->DidBeginScroll();
1538 return ScrollStarted
;
1540 return ScrollIgnored
;
1543 gfx::Vector2dF
LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1544 LayerImpl
* layer_impl
,
1545 float scale_from_viewport_to_screen_space
,
1546 gfx::PointF viewport_point
,
1547 gfx::Vector2dF viewport_delta
) {
1548 // Layers with non-invertible screen space transforms should not have passed
1549 // the scroll hit test in the first place.
1550 DCHECK(layer_impl
->screen_space_transform().IsInvertible());
1551 gfx::Transform
inverse_screen_space_transform(
1552 gfx::Transform::kSkipInitialization
);
1553 bool did_invert
= layer_impl
->screen_space_transform().GetInverse(
1554 &inverse_screen_space_transform
);
1555 // TODO(shawnsingh): With the advent of impl-side crolling for non-root
1556 // layers, we may need to explicitly handle uninvertible transforms here.
1559 gfx::PointF screen_space_point
=
1560 gfx::ScalePoint(viewport_point
, scale_from_viewport_to_screen_space
);
1562 gfx::Vector2dF screen_space_delta
= viewport_delta
;
1563 screen_space_delta
.Scale(scale_from_viewport_to_screen_space
);
1565 // First project the scroll start and end points to local layer space to find
1566 // the scroll delta in layer coordinates.
1567 bool start_clipped
, end_clipped
;
1568 gfx::PointF screen_space_end_point
= screen_space_point
+ screen_space_delta
;
1569 gfx::PointF local_start_point
=
1570 MathUtil::ProjectPoint(inverse_screen_space_transform
,
1573 gfx::PointF local_end_point
=
1574 MathUtil::ProjectPoint(inverse_screen_space_transform
,
1575 screen_space_end_point
,
1578 // In general scroll point coordinates should not get clipped.
1579 DCHECK(!start_clipped
);
1580 DCHECK(!end_clipped
);
1581 if (start_clipped
|| end_clipped
)
1582 return gfx::Vector2dF();
1584 // local_start_point and local_end_point are in content space but we want to
1585 // move them to layer space for scrolling.
1586 float width_scale
= 1.f
/ layer_impl
->contents_scale_x();
1587 float height_scale
= 1.f
/ layer_impl
->contents_scale_y();
1588 local_start_point
.Scale(width_scale
, height_scale
);
1589 local_end_point
.Scale(width_scale
, height_scale
);
1591 // Apply the scroll delta.
1592 gfx::Vector2dF previous_delta
= layer_impl
->scroll_delta();
1593 layer_impl
->ScrollBy(local_end_point
- local_start_point
);
1595 // Get the end point in the layer's content space so we can apply its
1596 // ScreenSpaceTransform.
1597 gfx::PointF actual_local_end_point
= local_start_point
+
1598 layer_impl
->scroll_delta() -
1600 gfx::PointF actual_local_content_end_point
=
1601 gfx::ScalePoint(actual_local_end_point
,
1603 1.f
/ height_scale
);
1605 // Calculate the applied scroll delta in viewport space coordinates.
1606 gfx::PointF actual_screen_space_end_point
=
1607 MathUtil::MapPoint(layer_impl
->screen_space_transform(),
1608 actual_local_content_end_point
,
1610 DCHECK(!end_clipped
);
1612 return gfx::Vector2dF();
1613 gfx::PointF actual_viewport_end_point
=
1614 gfx::ScalePoint(actual_screen_space_end_point
,
1615 1.f
/ scale_from_viewport_to_screen_space
);
1616 return actual_viewport_end_point
- viewport_point
;
1619 static gfx::Vector2dF
ScrollLayerWithLocalDelta(LayerImpl
* layer_impl
,
1620 gfx::Vector2dF local_delta
) {
1621 gfx::Vector2dF
previous_delta(layer_impl
->scroll_delta());
1622 layer_impl
->ScrollBy(local_delta
);
1623 return layer_impl
->scroll_delta() - previous_delta
;
1626 bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point
,
1627 gfx::Vector2dF scroll_delta
) {
1628 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1629 if (!CurrentlyScrollingLayer())
1632 gfx::Vector2dF pending_delta
= scroll_delta
;
1633 bool did_scroll
= false;
1634 bool consume_by_top_controls
= top_controls_manager_
&&
1635 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta
.y() < 0);
1637 for (LayerImpl
* layer_impl
= CurrentlyScrollingLayer();
1639 layer_impl
= layer_impl
->parent()) {
1640 if (!layer_impl
->scrollable())
1643 // Only allow bubble scrolling when the scroll is in the direction to make
1644 // the top controls visible.
1645 if (consume_by_top_controls
&& layer_impl
== RootScrollLayer()) {
1646 pending_delta
= top_controls_manager_
->ScrollBy(pending_delta
);
1647 UpdateMaxScrollOffset();
1650 gfx::Vector2dF applied_delta
;
1651 // Gesture events need to be transformed from viewport coordinates to local
1652 // layer coordinates so that the scrolling contents exactly follow the
1653 // user's finger. In contrast, wheel events represent a fixed amount of
1654 // scrolling so we can just apply them directly.
1655 if (!wheel_scrolling_
) {
1656 float scale_from_viewport_to_screen_space
= device_scale_factor_
;
1658 ScrollLayerWithViewportSpaceDelta(layer_impl
,
1659 scale_from_viewport_to_screen_space
,
1660 viewport_point
, pending_delta
);
1662 applied_delta
= ScrollLayerWithLocalDelta(layer_impl
, pending_delta
);
1665 // If the layer wasn't able to move, try the next one in the hierarchy.
1666 float move_threshold_squared
= 0.1f
* 0.1f
;
1667 if (applied_delta
.LengthSquared() < move_threshold_squared
) {
1668 if (should_bubble_scrolls_
|| !did_lock_scrolling_layer_
)
1674 did_lock_scrolling_layer_
= true;
1675 if (!should_bubble_scrolls_
) {
1676 active_tree_
->SetCurrentlyScrollingLayer(layer_impl
);
1680 // If the applied delta is within 45 degrees of the input delta, bail out to
1681 // make it easier to scroll just one layer in one direction without
1682 // affecting any of its parents.
1683 float angle_threshold
= 45;
1684 if (MathUtil::SmallestAngleBetweenVectors(
1685 applied_delta
, pending_delta
) < angle_threshold
) {
1686 pending_delta
= gfx::Vector2d();
1690 // Allow further movement only on an axis perpendicular to the direction in
1691 // which the layer moved.
1692 gfx::Vector2dF
perpendicular_axis(-applied_delta
.y(), applied_delta
.x());
1693 pending_delta
= MathUtil::ProjectVector(pending_delta
, perpendicular_axis
);
1695 if (gfx::ToFlooredVector2d(pending_delta
).IsZero())
1699 active_tree()->DidUpdateScroll();
1701 client_
->SetNeedsCommitOnImplThread();
1702 client_
->SetNeedsRedrawOnImplThread();
1703 client_
->RenewTreePriority();
1708 // This implements scrolling by page as described here:
1709 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel
1710 // for events with WHEEL_PAGESCROLL set.
1711 bool LayerTreeHostImpl::ScrollVerticallyByPage(
1712 gfx::Point viewport_point
,
1713 WebKit::WebScrollbar::ScrollDirection direction
) {
1714 DCHECK(wheel_scrolling_
);
1716 for (LayerImpl
* layer_impl
= CurrentlyScrollingLayer();
1718 layer_impl
= layer_impl
->parent()) {
1719 if (!layer_impl
->scrollable())
1722 if (!layer_impl
->vertical_scrollbar_layer())
1725 float height
= layer_impl
->vertical_scrollbar_layer()->bounds().height();
1727 // These magical values match WebKit and are designed to scroll nearly the
1728 // entire visible content height but leave a bit of overlap.
1729 float page
= std::max(height
* 0.875f
, 1.f
);
1730 if (direction
== WebKit::WebScrollbar::ScrollBackward
)
1733 gfx::Vector2dF delta
= gfx::Vector2dF(0.f
, page
);
1735 gfx::Vector2dF applied_delta
= ScrollLayerWithLocalDelta(layer_impl
, delta
);
1737 if (!applied_delta
.IsZero()) {
1738 active_tree()->DidUpdateScroll();
1739 client_
->SetNeedsCommitOnImplThread();
1740 client_
->SetNeedsRedrawOnImplThread();
1741 client_
->RenewTreePriority();
1745 active_tree_
->SetCurrentlyScrollingLayer(layer_impl
);
1751 void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1752 active_tree_
->ClearCurrentlyScrollingLayer();
1753 did_lock_scrolling_layer_
= false;
1756 void LayerTreeHostImpl::ScrollEnd() {
1757 if (top_controls_manager_
)
1758 top_controls_manager_
->ScrollEnd();
1759 ClearCurrentlyScrollingLayer();
1760 active_tree()->DidEndScroll();
1761 StartScrollbarAnimation(CurrentFrameTimeTicks());
1764 InputHandlerClient::ScrollStatus
LayerTreeHostImpl::FlingScrollBegin() {
1765 if (active_tree_
->CurrentlyScrollingLayer())
1766 return ScrollStarted
;
1768 return ScrollIgnored
;
1771 void LayerTreeHostImpl::PinchGestureBegin() {
1772 pinch_gesture_active_
= true;
1773 previous_pinch_anchor_
= gfx::Point();
1774 client_
->RenewTreePriority();
1777 void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta
,
1778 gfx::Point anchor
) {
1779 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
1781 if (!RootScrollLayer())
1784 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1785 // position over the course of the magnify.
1786 float page_scale_delta
= active_tree_
->page_scale_delta();
1787 gfx::PointF previous_scale_anchor
=
1788 gfx::ScalePoint(anchor
, 1.f
/ page_scale_delta
);
1789 active_tree_
->SetPageScaleDelta(page_scale_delta
* magnify_delta
);
1790 page_scale_delta
= active_tree_
->page_scale_delta();
1791 gfx::PointF new_scale_anchor
=
1792 gfx::ScalePoint(anchor
, 1.f
/ page_scale_delta
);
1793 gfx::Vector2dF move
= previous_scale_anchor
- new_scale_anchor
;
1795 previous_pinch_anchor_
= anchor
;
1797 move
.Scale(1 / active_tree_
->page_scale_factor());
1799 RootScrollLayer()->ScrollBy(move
);
1801 client_
->SetNeedsCommitOnImplThread();
1802 client_
->SetNeedsRedrawOnImplThread();
1803 client_
->RenewTreePriority();
1806 void LayerTreeHostImpl::PinchGestureEnd() {
1807 pinch_gesture_active_
= false;
1808 client_
->SetNeedsCommitOnImplThread();
1811 static void CollectScrollDeltas(ScrollAndScaleSet
* scroll_info
,
1812 LayerImpl
* layer_impl
) {
1816 gfx::Vector2d scroll_delta
=
1817 gfx::ToFlooredVector2d(layer_impl
->scroll_delta());
1818 if (!scroll_delta
.IsZero()) {
1819 LayerTreeHostCommon::ScrollUpdateInfo scroll
;
1820 scroll
.layer_id
= layer_impl
->id();
1821 scroll
.scroll_delta
= scroll_delta
;
1822 scroll_info
->scrolls
.push_back(scroll
);
1823 layer_impl
->SetSentScrollDelta(scroll_delta
);
1826 for (size_t i
= 0; i
< layer_impl
->children().size(); ++i
)
1827 CollectScrollDeltas(scroll_info
, layer_impl
->children()[i
]);
1830 scoped_ptr
<ScrollAndScaleSet
> LayerTreeHostImpl::ProcessScrollDeltas() {
1831 scoped_ptr
<ScrollAndScaleSet
> scroll_info(new ScrollAndScaleSet());
1833 CollectScrollDeltas(scroll_info
.get(), active_tree_
->root_layer());
1834 scroll_info
->page_scale_delta
= active_tree_
->page_scale_delta();
1835 active_tree_
->set_sent_page_scale_delta(scroll_info
->page_scale_delta
);
1837 return scroll_info
.Pass();
1840 void LayerTreeHostImpl::SetFullRootLayerDamage() {
1841 SetViewportDamage(gfx::Rect(device_viewport_size_
));
1844 void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time
) {
1845 if (!page_scale_animation_
|| !RootScrollLayer())
1848 double monotonic_time
= (time
- base::TimeTicks()).InSecondsF();
1849 gfx::Vector2dF scroll_total
= RootScrollLayer()->scroll_offset() +
1850 RootScrollLayer()->scroll_delta();
1852 active_tree_
->SetPageScaleDelta(
1853 page_scale_animation_
->PageScaleFactorAtTime(monotonic_time
) /
1854 active_tree_
->page_scale_factor());
1855 gfx::Vector2dF next_scroll
=
1856 page_scale_animation_
->ScrollOffsetAtTime(monotonic_time
);
1858 RootScrollLayer()->ScrollBy(next_scroll
- scroll_total
);
1859 client_
->SetNeedsRedrawOnImplThread();
1861 if (page_scale_animation_
->IsAnimationCompleteAtTime(monotonic_time
)) {
1862 page_scale_animation_
.reset();
1863 client_
->SetNeedsCommitOnImplThread();
1864 client_
->RenewTreePriority();
1868 void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time
) {
1869 if (!top_controls_manager_
|| !RootScrollLayer())
1871 gfx::Vector2dF scroll
= top_controls_manager_
->Animate(time
);
1872 UpdateMaxScrollOffset();
1873 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1874 scroll
, 1.f
/ active_tree_
->total_page_scale_factor()));
1877 void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time
,
1878 base::Time wall_clock_time
) {
1879 if (!settings_
.accelerated_animation_enabled
||
1880 animation_registrar_
->active_animation_controllers().empty() ||
1881 !active_tree_
->root_layer())
1884 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1886 last_animation_time_
= wall_clock_time
;
1887 double monotonic_seconds
= (monotonic_time
- base::TimeTicks()).InSecondsF();
1889 AnimationRegistrar::AnimationControllerMap copy
=
1890 animation_registrar_
->active_animation_controllers();
1891 for (AnimationRegistrar::AnimationControllerMap::iterator iter
= copy
.begin();
1894 (*iter
).second
->Animate(monotonic_seconds
);
1896 client_
->SetNeedsRedrawOnImplThread();
1899 void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations
) {
1900 if (!settings_
.accelerated_animation_enabled
||
1901 animation_registrar_
->active_animation_controllers().empty() ||
1902 !active_tree_
->root_layer())
1905 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1906 scoped_ptr
<AnimationEventsVector
> events
=
1907 make_scoped_ptr(new AnimationEventsVector
);
1908 AnimationRegistrar::AnimationControllerMap copy
=
1909 animation_registrar_
->active_animation_controllers();
1910 for (AnimationRegistrar::AnimationControllerMap::iterator iter
= copy
.begin();
1913 (*iter
).second
->UpdateState(start_ready_animations
, events
.get());
1915 if (!events
->empty()) {
1916 client_
->PostAnimationEventsToMainThreadOnImplThread(events
.Pass(),
1917 last_animation_time_
);
1921 base::TimeDelta
LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1922 return base::TimeDelta::FromSeconds(1);
1925 void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl
* current
) {
1927 current
->DidLoseOutputSurface();
1928 if (current
->mask_layer())
1929 SendDidLoseOutputSurfaceRecursive(current
->mask_layer());
1930 if (current
->replica_layer())
1931 SendDidLoseOutputSurfaceRecursive(current
->replica_layer());
1932 for (size_t i
= 0; i
< current
->children().size(); ++i
)
1933 SendDidLoseOutputSurfaceRecursive(current
->children()[i
]);
1936 void LayerTreeHostImpl::ClearRenderSurfaces() {
1937 active_tree_
->ClearRenderSurfaces();
1939 pending_tree_
->ClearRenderSurfaces();
1942 std::string
LayerTreeHostImpl::LayerTreeAsText() const {
1944 if (active_tree_
->root_layer()) {
1945 str
= active_tree_
->root_layer()->LayerTreeAsText();
1946 str
+= "RenderSurfaces:\n";
1947 DumpRenderSurfaces(&str
, 1, active_tree_
->root_layer());
1952 std::string
LayerTreeHostImpl::LayerTreeAsJson() const {
1954 if (active_tree_
->root_layer()) {
1955 scoped_ptr
<base::Value
> json(active_tree_
->root_layer()->LayerTreeAsJson());
1956 base::JSONWriter::WriteWithOptions(
1957 json
.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT
, &str
);
1962 void LayerTreeHostImpl::DumpRenderSurfaces(std::string
* str
,
1964 const LayerImpl
* layer
) const {
1965 if (layer
->render_surface())
1966 layer
->render_surface()->DumpSurface(str
, indent
);
1968 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
1969 DumpRenderSurfaces(str
, indent
, layer
->children()[i
]);
1972 int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
1973 return fps_counter_
->current_frame_number();
1976 void LayerTreeHostImpl::SendManagedMemoryStats(
1977 size_t memory_visible_bytes
,
1978 size_t memory_visible_and_nearby_bytes
,
1979 size_t memory_use_bytes
) {
1983 // Round the numbers being sent up to the next 8MB, to throttle the rate
1984 // at which we spam the GPU process.
1985 static const size_t rounding_step
= 8 * 1024 * 1024;
1986 memory_visible_bytes
= RoundUp(memory_visible_bytes
, rounding_step
);
1987 memory_visible_and_nearby_bytes
= RoundUp(memory_visible_and_nearby_bytes
,
1989 memory_use_bytes
= RoundUp(memory_use_bytes
, rounding_step
);
1990 if (last_sent_memory_visible_bytes_
== memory_visible_bytes
&&
1991 last_sent_memory_visible_and_nearby_bytes_
==
1992 memory_visible_and_nearby_bytes
&&
1993 last_sent_memory_use_bytes_
== memory_use_bytes
) {
1996 last_sent_memory_visible_bytes_
= memory_visible_bytes
;
1997 last_sent_memory_visible_and_nearby_bytes_
= memory_visible_and_nearby_bytes
;
1998 last_sent_memory_use_bytes_
= memory_use_bytes
;
2000 renderer_
->SendManagedMemoryStats(last_sent_memory_visible_bytes_
,
2001 last_sent_memory_visible_and_nearby_bytes_
,
2002 last_sent_memory_use_bytes_
);
2005 void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time
) {
2006 AnimateScrollbarsRecursive(active_tree_
->root_layer(), time
);
2009 void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl
* layer
,
2010 base::TimeTicks time
) {
2014 ScrollbarAnimationController
* scrollbar_controller
=
2015 layer
->scrollbar_animation_controller();
2016 if (scrollbar_controller
&& scrollbar_controller
->Animate(time
)) {
2017 TRACE_EVENT_INSTANT0(
2018 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
2019 TRACE_EVENT_SCOPE_THREAD
);
2020 client_
->SetNeedsRedrawOnImplThread();
2023 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
2024 AnimateScrollbarsRecursive(layer
->children()[i
], time
);
2027 void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time
) {
2028 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
2029 StartScrollbarAnimationRecursive(RootLayer(), time
);
2032 void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl
* layer
,
2033 base::TimeTicks time
) {
2037 ScrollbarAnimationController
* scrollbar_controller
=
2038 layer
->scrollbar_animation_controller();
2039 if (scrollbar_controller
&& scrollbar_controller
->IsAnimating()) {
2040 base::TimeDelta delay
= scrollbar_controller
->DelayBeforeStart(time
);
2041 if (delay
> base::TimeDelta())
2042 client_
->RequestScrollbarAnimationOnImplThread(delay
);
2043 else if (scrollbar_controller
->Animate(time
))
2044 client_
->SetNeedsRedrawOnImplThread();
2047 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
2048 StartScrollbarAnimationRecursive(layer
->children()[i
], time
);
2051 void LayerTreeHostImpl::SetTreePriority(TreePriority priority
) {
2055 GlobalStateThatImpactsTilePriority
new_state(tile_manager_
->GlobalState());
2056 if (new_state
.tree_priority
== priority
)
2059 new_state
.tree_priority
= priority
;
2060 tile_manager_
->SetGlobalState(new_state
);
2063 void LayerTreeHostImpl::BeginNextFrame() {
2064 current_frame_timeticks_
= base::TimeTicks();
2065 current_frame_time_
= base::Time();
2068 static void UpdateCurrentFrameTime(base::TimeTicks
* ticks
, base::Time
* now
) {
2069 if (ticks
->is_null()) {
2070 DCHECK(now
->is_null());
2071 *ticks
= base::TimeTicks::Now();
2072 *now
= base::Time::Now();
2076 base::TimeTicks
LayerTreeHostImpl::CurrentFrameTimeTicks() {
2077 UpdateCurrentFrameTime(¤t_frame_timeticks_
, ¤t_frame_time_
);
2078 return current_frame_timeticks_
;
2081 base::Time
LayerTreeHostImpl::CurrentFrameTime() {
2082 UpdateCurrentFrameTime(¤t_frame_timeticks_
, ¤t_frame_time_
);
2083 return current_frame_time_
;
2086 scoped_ptr
<base::Value
> LayerTreeHostImpl::AsValue() const {
2087 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue());
2088 state
->Set("activation_state", ActivationStateAsValue().release());
2089 state
->Set("frame_state", FrameStateAsValue().release());
2090 return state
.PassAs
<base::Value
>();
2093 scoped_ptr
<base::Value
> LayerTreeHostImpl::ActivationStateAsValue() const {
2094 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue());
2095 state
->SetString("lthi_id", base::StringPrintf("%p", this));
2096 state
->SetBoolean("visible_resources_ready",
2097 pending_tree_
->AreVisibleResourcesReady());
2098 state
->Set("tile_manager", tile_manager_
->BasicStateAsValue().release());
2099 return state
.PassAs
<base::Value
>();
2102 scoped_ptr
<base::Value
> LayerTreeHostImpl::FrameStateAsValue() const {
2103 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue());
2104 state
->SetString("lthi_id", base::StringPrintf("%p", this));
2105 state
->Set("device_viewport_size",
2106 MathUtil::AsValue(device_viewport_size_
).release());
2108 state
->Set("tiles", tile_manager_
->AllTilesAsValue().release());
2109 state
->Set("active_tree", active_tree_
->AsValue().release());
2110 return state
.PassAs
<base::Value
>();
2114 LayerImpl
* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
2119 if (layer
->DrawsContent())
2122 for (LayerImplList::const_iterator it
= layer
->children().begin();
2123 it
!= layer
->children().end(); ++it
) {
2124 LayerImpl
* nccr
= GetNonCompositedContentLayerRecursive(*it
);
2132 skia::RefPtr
<SkPicture
> LayerTreeHostImpl::CapturePicture() {
2133 LayerTreeImpl
* tree
=
2134 pending_tree_
? pending_tree_
.get() : active_tree_
.get();
2135 LayerImpl
* layer
= GetNonCompositedContentLayerRecursive(tree
->root_layer());
2136 return layer
? layer
->GetPicture() : skia::RefPtr
<SkPicture
>();
2139 void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState
& debug_state
) {
2140 if (debug_state_
.continuous_painting
!= debug_state
.continuous_painting
)
2141 paint_time_counter_
->ClearHistory();
2143 debug_state_
= debug_state
;