blob: 7c42e04cd510eeff164871359a0d7849f51a1233 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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.
4
[email protected]55a124d02012-10-22 03:07:135#include "cc/layer_tree_host_impl.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]ac7c7f52012-11-08 06:26:507#include <algorithm>
8
[email protected]ad5d1422012-10-19 13:40:299#include "base/basictypes.h"
[email protected]4456eee22012-10-19 18:16:3810#include "base/debug/trace_event.h"
[email protected]4a23c374c2012-12-08 08:38:5511#include "base/json/json_writer.h"
[email protected]f5864912013-02-01 03:18:1412#include "base/metrics/histogram.h"
[email protected]de4afb5e2012-12-20 00:11:3413#include "base/stl_util.h"
[email protected]131a0c22013-02-12 18:31:0814#include "base/stringprintf.h"
[email protected]aa0a9d32012-10-24 01:58:1015#include "cc/append_quads_data.h"
[email protected]bf189f62012-12-18 03:42:1116#include "cc/compositor_frame_metadata.h"
[email protected]aa0a9d32012-10-24 01:58:1017#include "cc/damage_tracker.h"
18#include "cc/debug_rect_history.h"
19#include "cc/delay_based_time_source.h"
[email protected]ea9d8f22012-12-08 03:39:2920#include "cc/delegating_renderer.h"
[email protected]aa0a9d32012-10-24 01:58:1021#include "cc/frame_rate_counter.h"
[email protected]c4040a522012-10-21 15:01:4022#include "cc/gl_renderer.h"
[email protected]d50c6862012-10-23 02:08:3123#include "cc/heads_up_display_layer_impl.h"
24#include "cc/layer_iterator.h"
25#include "cc/layer_tree_host.h"
26#include "cc/layer_tree_host_common.h"
[email protected]8bef40572012-12-11 21:38:0827#include "cc/layer_tree_impl.h"
[email protected]55a124d02012-10-22 03:07:1328#include "cc/math_util.h"
[email protected]1191d9d2013-02-02 06:00:3329#include "cc/memory_history.h"
[email protected]55a124d02012-10-22 03:07:1330#include "cc/overdraw_metrics.h"
31#include "cc/page_scale_animation.h"
[email protected]0edbfbe9f2013-01-17 03:33:0332#include "cc/paint_time_counter.h"
[email protected]131a0c22013-02-12 18:31:0833#include "cc/picture_layer_tiling.h"
[email protected]3b10a302012-11-07 21:16:4034#include "cc/prioritized_resource_manager.h"
[email protected]f57bbc02012-11-21 07:02:1535#include "cc/quad_culler.h"
[email protected]55a124d02012-10-22 03:07:1336#include "cc/render_pass_draw_quad.h"
[email protected]c4040a522012-10-21 15:01:4037#include "cc/rendering_stats.h"
38#include "cc/scrollbar_animation_controller.h"
39#include "cc/scrollbar_layer_impl.h"
[email protected]f57bbc02012-11-21 07:02:1540#include "cc/shared_quad_state.h"
[email protected]4456eee22012-10-19 18:16:3841#include "cc/single_thread_proxy.h"
[email protected]c4040a522012-10-21 15:01:4042#include "cc/software_renderer.h"
[email protected]f57bbc02012-11-21 07:02:1543#include "cc/solid_color_draw_quad.h"
[email protected]a8461d82012-10-16 21:11:1444#include "cc/texture_uploader.h"
[email protected]3ba4cae2013-01-16 03:58:3845#include "cc/top_controls_manager.h"
[email protected]48871fc2013-01-23 07:36:5146#include "cc/tree_synchronizer.h"
[email protected]d3afa112012-12-08 06:24:2847#include "cc/util.h"
[email protected]d455d552012-11-02 00:19:0648#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1349#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1450
[email protected]94f206c12012-08-25 00:09:1451namespace {
52
[email protected]c1bb5af2013-03-13 19:06:2753void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) {
54 if (visible) {
55 TRACE_EVENT_ASYNC_BEGIN1("webkit",
56 "LayerTreeHostImpl::SetVisible",
57 id,
58 "LayerTreeHostImpl",
59 id);
60 return;
61 }
[email protected]94f206c12012-08-25 00:09:1462
[email protected]c1bb5af2013-03-13 19:06:2763 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id);
[email protected]94f206c12012-08-25 00:09:1464}
65
[email protected]c1bb5af2013-03-13 19:06:2766std::string ValueToString(scoped_ptr<base::Value> value) {
67 std::string str;
68 base::JSONWriter::Write(value.get(), &str);
69 return str;
[email protected]131a0c22013-02-12 18:31:0870}
71
[email protected]c1bb5af2013-03-13 19:06:2772} // namespace
[email protected]94f206c12012-08-25 00:09:1473
[email protected]9c88e562012-09-14 22:21:3074namespace cc {
[email protected]94f206c12012-08-25 00:09:1475
[email protected]96baf3e2012-10-22 23:09:5576class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]c1bb5af2013-03-13 19:06:2777 public:
78 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
79 LayerTreeHostImpl* layer_tree_host_impl,
80 scoped_refptr<DelayBasedTimeSource> time_source) {
81 return make_scoped_ptr(
82 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
83 time_source));
84 }
85 virtual ~LayerTreeHostImplTimeSourceAdapter() {
86 time_source_->setClient(NULL);
87 time_source_->setActive(false);
88 }
89
90 virtual void onTimerTick() OVERRIDE {
91 // In single threaded mode we attempt to simulate changing the current
92 // thread by maintaining a fake thread id. When we switch from one
93 // thread to another, we construct DebugScopedSetXXXThread objects that
94 // update the thread id. This lets DCHECKS that ensure we're on the
95 // right thread to work correctly in single threaded mode. The problem
96 // here is that the timer tasks are run via the message loop, and when
97 // they run, we've had no chance to construct a DebugScopedSetXXXThread
98 // object. The result is that we report that we're running on the main
99 // thread. In multi-threaded mode, this timer is run on the compositor
100 // thread, so to keep this consistent in single-threaded mode, we'll
101 // construct a DebugScopedSetImplThread object. There is no need to do
102 // this in multi-threaded mode since the real thread id's will be
103 // correct. In fact, setting fake thread id's interferes with the real
104 // thread id's and causes breakage.
105 scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
106 if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
107 set_impl_thread.reset(
108 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
[email protected]94f206c12012-08-25 00:09:14109 }
110
[email protected]c1bb5af2013-03-13 19:06:27111 layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
112 layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now());
113 layer_tree_host_impl_->BeginNextFrame();
114 }
[email protected]373974232013-01-10 22:20:50115
[email protected]c1bb5af2013-03-13 19:06:27116 void SetActive(bool active) {
117 if (active != time_source_->active())
118 time_source_->setActive(active);
119 }
[email protected]94f206c12012-08-25 00:09:14120
[email protected]c1bb5af2013-03-13 19:06:27121 private:
122 LayerTreeHostImplTimeSourceAdapter(
123 LayerTreeHostImpl* layer_tree_host_impl,
124 scoped_refptr<DelayBasedTimeSource> time_source)
125 : layer_tree_host_impl_(layer_tree_host_impl),
126 time_source_(time_source) {
127 time_source_->setClient(this);
128 }
[email protected]94f206c12012-08-25 00:09:14129
[email protected]c1bb5af2013-03-13 19:06:27130 LayerTreeHostImpl* layer_tree_host_impl_;
131 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14132
[email protected]c1bb5af2013-03-13 19:06:27133 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14134};
135
[email protected]96baf3e2012-10-22 23:09:55136LayerTreeHostImpl::FrameData::FrameData()
[email protected]c1bb5af2013-03-13 19:06:27137 : contains_incomplete_tile(false) {}
138
139LayerTreeHostImpl::FrameData::~FrameData() {}
140
141scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
142 const LayerTreeSettings& settings,
143 LayerTreeHostImplClient* client,
144 Proxy* proxy) {
145 return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy));
[email protected]493067512012-09-19 23:34:10146}
147
[email protected]c1bb5af2013-03-13 19:06:27148LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings,
149 LayerTreeHostImplClient* client,
150 Proxy* proxy)
151 : client_(client),
152 proxy_(proxy),
153 did_lock_scrolling_layer_(false),
154 should_bubble_scrolls_(false),
155 wheel_scrolling_(false),
156 settings_(settings),
157 device_scale_factor_(1.f),
158 visible_(true),
159 managed_memory_policy_(
160 PrioritizedResourceManager::defaultMemoryAllocationLimit(),
161 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
162 0,
163 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
164 pinch_gesture_active_(false),
165 fps_counter_(FrameRateCounter::create(proxy_->HasImplThread())),
166 paint_time_counter_(PaintTimeCounter::create()),
167 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02168 debug_rect_history_(DebugRectHistory::Create()),
[email protected]c1bb5af2013-03-13 19:06:27169 num_impl_thread_scrolls_(0),
170 num_main_thread_scrolls_(0),
171 cumulative_num_layers_drawn_(0),
172 cumulative_num_missing_tiles_(0),
173 last_sent_memory_visible_bytes_(0),
174 last_sent_memory_visible_and_nearby_bytes_(0),
175 last_sent_memory_use_bytes_(0),
176 animation_registrar_(AnimationRegistrar::create()) {
177 DCHECK(proxy_->IsImplThread());
178 DidVisibilityChange(this, visible_);
179
180 SetDebugState(settings.initialDebugState);
181
182 if (settings.calculateTopControlsPosition) {
183 top_controls_manager_ =
184 TopControlsManager::Create(this,
185 settings.topControlsHeight,
186 settings.topControlsShowThreshold,
187 settings.topControlsHideThreshold);
188 }
189
190 SetDebugState(settings.initialDebugState);
191
192 // LTHI always has an active tree.
193 active_tree_ = LayerTreeImpl::create(this);
[email protected]493067512012-09-19 23:34:10194}
195
[email protected]c1bb5af2013-03-13 19:06:27196LayerTreeHostImpl::~LayerTreeHostImpl() {
197 DCHECK(proxy_->IsImplThread());
198 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
199
200 if (active_tree_->root_layer()) {
201 ClearRenderSurfaces();
202 // The layer trees must be destroyed before the layer tree host. We've
203 // made a contract with our animation controllers that the registrar
204 // will outlive them, and we must make good.
205 recycle_tree_.reset();
206 pending_tree_.reset();
207 active_tree_.reset();
208 }
[email protected]94f206c12012-08-25 00:09:14209}
210
[email protected]c1bb5af2013-03-13 19:06:27211void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29212
[email protected]c1bb5af2013-03-13 19:06:27213void LayerTreeHostImpl::CommitComplete() {
214 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08215
[email protected]c1bb5af2013-03-13 19:06:27216 // Impl-side painting needs an update immediately post-commit to have the
217 // opportunity to create tilings. Other paths can call UpdateDrawProperties
218 // more lazily when needed prior to drawing.
219 if (settings_.implSidePainting) {
220 pending_tree_->set_needs_update_draw_properties();
221 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
222 } else {
223 active_tree_->set_needs_update_draw_properties();
224 }
[email protected]3ba4cae2013-01-16 03:58:38225
[email protected]c1bb5af2013-03-13 19:06:27226 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14227}
228
[email protected]c1bb5af2013-03-13 19:06:27229bool LayerTreeHostImpl::CanDraw() {
230 // Note: If you are changing this function or any other function that might
231 // affect the result of CanDraw, make sure to call
232 // client_->OnCanDrawStateChanged in the proper places and update the
233 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14234
[email protected]c1bb5af2013-03-13 19:06:27235 if (!active_tree_->root_layer()) {
236 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer");
[email protected]2f1acc262012-11-16 21:42:22237 return false;
[email protected]c1bb5af2013-03-13 19:06:27238 }
239 if (device_viewport_size_.IsEmpty()) {
240 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport");
241 return false;
242 }
243 if (active_tree_->ViewportSizeInvalid()) {
244 TRACE_EVENT_INSTANT0(
245 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed");
246 return false;
247 }
248 if (!renderer_) {
249 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer");
250 return false;
251 }
252 if (active_tree_->ContentsTexturesPurged()) {
253 TRACE_EVENT_INSTANT0(
254 "cc", "LayerTreeHostImpl::CanDraw contents textures purged");
255 return false;
256 }
257 return true;
[email protected]2f1acc262012-11-16 21:42:22258}
259
[email protected]c1bb5af2013-03-13 19:06:27260void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
261 base::Time wall_clock_time) {
262 AnimatePageScale(monotonic_time);
263 AnimateLayers(monotonic_time, wall_clock_time);
264 AnimateScrollbars(monotonic_time);
265 if (top_controls_manager_)
266 top_controls_manager_->Animate(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14267}
268
[email protected]c1bb5af2013-03-13 19:06:27269void LayerTreeHostImpl::ManageTiles() {
270 DCHECK(tile_manager_);
271 tile_manager_->ManageTiles();
272
273 size_t memory_required_bytes;
274 size_t memory_nice_to_have_bytes;
275 size_t memory_used_bytes;
276 tile_manager_->GetMemoryStats(&memory_required_bytes,
277 &memory_nice_to_have_bytes,
278 &memory_used_bytes);
279 SendManagedMemoryStats(memory_required_bytes,
280 memory_nice_to_have_bytes,
281 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15282}
283
[email protected]c1bb5af2013-03-13 19:06:27284void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
285 bool anchor_point,
286 float page_scale,
287 base::TimeTicks start_time,
288 base::TimeDelta duration) {
289 if (!RootScrollLayer())
290 return;
291
292 gfx::Vector2dF scroll_total =
293 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
294 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
295 gfx::SizeF viewport_size =
296 gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor_);
297
298 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
299 page_scale_animation_ =
300 PageScaleAnimation::Create(scroll_total,
301 active_tree_->total_page_scale_factor(),
302 viewport_size,
303 scaled_scrollable_size,
304 start_time_seconds);
305
306 if (anchor_point) {
307 gfx::Vector2dF anchor(target_offset);
308 page_scale_animation_->ZoomWithAnchor(anchor,
309 page_scale,
310 duration.InSecondsF());
311 } else {
312 gfx::Vector2dF scaled_target_offset = target_offset;
313 page_scale_animation_->ZoomTo(scaled_target_offset,
314 page_scale,
315 duration.InSecondsF());
316 }
317
318 client_->SetNeedsRedrawOnImplThread();
319 client_->SetNeedsCommitOnImplThread();
320 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15321}
322
[email protected]c1bb5af2013-03-13 19:06:27323void LayerTreeHostImpl::ScheduleAnimation() {
324 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15325}
326
[email protected]c1bb5af2013-03-13 19:06:27327bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
328 if (!EnsureRenderSurfaceLayerList())
329 return false;
[email protected]f57bbc02012-11-21 07:02:15330
[email protected]c1bb5af2013-03-13 19:06:27331 gfx::PointF device_viewport_point =
332 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15333
[email protected]c1bb5af2013-03-13 19:06:27334 // First find out which layer was hit from the saved list of visible layers
335 // in the most recent frame.
336 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
337 device_viewport_point,
338 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15339
[email protected]c1bb5af2013-03-13 19:06:27340 // Walk up the hierarchy and look for a layer with a touch event handler
341 // region that the given point hits.
342 for (; layer_impl; layer_impl = layer_impl->parent()) {
343 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(device_viewport_point,
344 layer_impl))
345 return true;
346 }
[email protected]f57bbc02012-11-21 07:02:15347
[email protected]c1bb5af2013-03-13 19:06:27348 return false;
349}
350
351void LayerTreeHostImpl::TrackDamageForAllSurfaces(
352 LayerImpl* root_draw_layer,
353 const LayerList& render_surface_layer_list) {
354 // For now, we use damage tracking to compute a global scissor. To do this, we
355 // must compute all damage tracking before drawing anything, so that we know
356 // the root damage rect. The root damage rect is then used to scissor each
357 // surface.
358
359 for (int surface_index = render_surface_layer_list.size() - 1;
360 surface_index >= 0 ;
361 --surface_index) {
362 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
363 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
364 DCHECK(render_surface);
365 render_surface->damage_tracker()->UpdateDamageTrackingState(
366 render_surface->layer_list(),
367 render_surface_layer->id(),
368 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
369 render_surface->content_rect(),
370 render_surface_layer->mask_layer(),
371 render_surface_layer->filters(),
372 render_surface_layer->filter().get());
373 }
374}
375
376void LayerTreeHostImpl::FrameData::AppendRenderPass(
377 scoped_ptr<RenderPass> render_pass) {
378 render_passes_by_id[render_pass->id] = render_pass.get();
379 render_passes.push_back(render_pass.Pass());
380}
381
382static void AppendQuadsForLayer(RenderPass* target_render_pass,
383 LayerImpl* layer,
384 const OcclusionTrackerImpl& occlusion_tracker,
385 AppendQuadsData* append_quads_data) {
386 bool for_surface = false;
387 QuadCuller quad_culler(target_render_pass->quad_list,
388 target_render_pass->shared_quad_state_list,
389 layer,
390 occlusion_tracker,
391 layer->ShowDebugBorders(),
392 for_surface);
393 layer->AppendQuads(&quad_culler, append_quads_data);
394}
395
396static void AppendQuadsForRenderSurfaceLayer(
397 RenderPass* target_render_pass,
398 LayerImpl* layer,
399 const RenderPass* contributing_render_pass,
400 const OcclusionTrackerImpl& occlusion_tracker,
401 AppendQuadsData* append_quads_data) {
402 bool for_surface = true;
403 QuadCuller quad_culler(target_render_pass->quad_list,
404 target_render_pass->shared_quad_state_list,
405 layer,
406 occlusion_tracker,
407 layer->ShowDebugBorders(),
408 for_surface);
409
410 bool is_replica = false;
411 layer->render_surface()->AppendQuads(&quad_culler,
412 append_quads_data,
413 is_replica,
414 contributing_render_pass->id);
415
416 // Add replica after the surface so that it appears below the surface.
417 if (layer->has_replica()) {
418 is_replica = true;
419 layer->render_surface()->AppendQuads(&quad_culler,
420 append_quads_data,
421 is_replica,
422 contributing_render_pass->id);
423 }
424}
425
426static void AppendQuadsToFillScreen(
427 RenderPass* target_render_pass,
428 LayerImpl* root_layer,
429 SkColor screen_background_color,
430 const OcclusionTrackerImpl& occlusion_tracker) {
431 if (!root_layer || !SkColorGetA(screen_background_color))
432 return;
433
434 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
435 if (fill_region.IsEmpty())
436 return;
437
438 bool for_surface = false;
439 QuadCuller quad_culler(target_render_pass->quad_list,
440 target_render_pass->shared_quad_state_list,
441 root_layer,
442 occlusion_tracker,
443 root_layer->ShowDebugBorders(),
444 for_surface);
445
446 // Manually create the quad state for the gutter quads, as the root layer
447 // doesn't have any bounds and so can't generate this itself.
448 // TODO(danakj): Make the gutter quads generated by the solid color layer
449 // (make it smarter about generating quads to fill unoccluded areas).
450
451 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
452 float opacity = 1.f;
453 SharedQuadState* shared_quad_state =
454 quad_culler.useSharedQuadState(SharedQuadState::Create());
455 shared_quad_state->SetAll(root_layer->draw_transform(),
456 root_target_rect.size(),
457 root_target_rect,
458 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01459 false,
[email protected]f57bbc02012-11-21 07:02:15460 opacity);
461
[email protected]c1bb5af2013-03-13 19:06:27462 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17463
[email protected]c1bb5af2013-03-13 19:06:27464 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
465 bool did_invert = root_layer->screen_space_transform().GetInverse(
466 &transform_to_layer_space);
467 DCHECK(did_invert);
468 for (Region::Iterator fill_rects(fill_region);
469 fill_rects.has_rect();
470 fill_rects.next()) {
471 // The root layer transform is composed of translations and scales only,
472 // no perspective, so mapping is sufficient (as opposed to projecting).
473 gfx::Rect layer_rect =
474 MathUtil::mapClippedRect(transform_to_layer_space, fill_rects.rect());
475 // Skip the quad culler and just append the quads directly to avoid
476 // occlusion checks.
477 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
478 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
479 quad_culler.append(quad.PassAs<DrawQuad>(), &append_quads_data);
480 }
[email protected]467b3612012-08-28 07:41:16481}
482
[email protected]c1bb5af2013-03-13 19:06:27483bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
484 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14485
[email protected]c1bb5af2013-03-13 19:06:27486 if (!CanDraw() || !active_tree_->root_layer())
487 return false;
[email protected]2d692992012-12-19 01:19:32488
[email protected]c1bb5af2013-03-13 19:06:27489 TrackDamageForAllSurfaces(active_tree_->root_layer(),
490 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14491
[email protected]c1bb5af2013-03-13 19:06:27492 TRACE_EVENT1("cc",
493 "LayerTreeHostImpl::CalculateRenderPasses",
494 "render_surface_layer_list.size()",
495 static_cast<long long unsigned>(
496 frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14497
[email protected]c1bb5af2013-03-13 19:06:27498 // Create the render passes in dependency order.
499 for (int surface_index = frame->render_surface_layer_list->size() - 1;
500 surface_index >= 0 ;
501 --surface_index) {
502 LayerImpl* render_surface_layer =
503 (*frame->render_surface_layer_list)[surface_index];
504 render_surface_layer->render_surface()->AppendRenderPasses(frame);
505 }
[email protected]94f206c12012-08-25 00:09:14506
[email protected]c1bb5af2013-03-13 19:06:27507 bool record_metrics_for_frame =
508 settings_.showOverdrawInTracing &&
509 base::debug::TraceLog::GetInstance() &&
510 base::debug::TraceLog::GetInstance()->IsEnabled();
511 OcclusionTrackerImpl occlusion_tracker(
512 active_tree_->root_layer()->render_surface()->content_rect(),
513 record_metrics_for_frame);
514 occlusion_tracker.set_minimum_tracking_size(
515 settings_.minimumOcclusionTrackingSize);
[email protected]94f206c12012-08-25 00:09:14516
[email protected]c1bb5af2013-03-13 19:06:27517 if (debug_state_.showOccludingRects) {
518 occlusion_tracker.set_occluding_screen_space_rects_container(
519 &frame->occluding_screen_space_rects);
520 }
521 if (debug_state_.showNonOccludingRects) {
522 occlusion_tracker.set_non_occluding_screen_space_rects_container(
523 &frame->non_occluding_screen_space_rects);
524 }
[email protected]94f206c12012-08-25 00:09:14525
[email protected]c1bb5af2013-03-13 19:06:27526 // Add quads to the Render passes in FrontToBack order to allow for testing
527 // occlusion and performing culling during the tree walk.
528 typedef LayerIterator<LayerImpl,
529 std::vector<LayerImpl*>,
530 RenderSurfaceImpl,
531 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14532
[email protected]c1bb5af2013-03-13 19:06:27533 // Typically when we are missing a texture and use a checkerboard quad, we
534 // still draw the frame. However when the layer being checkerboarded is moving
535 // due to an impl-animation, we drop the frame to avoid flashing due to the
536 // texture suddenly appearing in the future.
537 bool draw_frame = true;
[email protected]94f206c12012-08-25 00:09:14538
[email protected]c1bb5af2013-03-13 19:06:27539 LayerIteratorType end =
540 LayerIteratorType::end(frame->render_surface_layer_list);
541 for (LayerIteratorType it =
542 LayerIteratorType::begin(frame->render_surface_layer_list);
543 it != end;
544 ++it) {
545 RenderPass::Id target_render_pass_id =
546 it.targetRenderSurfaceLayer()->render_surface()->RenderPassId();
547 RenderPass* target_render_pass =
548 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14549
[email protected]c1bb5af2013-03-13 19:06:27550 occlusion_tracker.EnterLayer(it);
[email protected]94f206c12012-08-25 00:09:14551
[email protected]c1bb5af2013-03-13 19:06:27552 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30553
[email protected]c1bb5af2013-03-13 19:06:27554 if (it.representsContributingRenderSurface()) {
555 RenderPass::Id contributing_render_pass_id =
556 it->render_surface()->RenderPassId();
557 RenderPass* contributing_render_pass =
558 frame->render_passes_by_id[contributing_render_pass_id];
559 AppendQuadsForRenderSurfaceLayer(target_render_pass,
560 *it,
561 contributing_render_pass,
562 occlusion_tracker,
563 &append_quads_data);
564 } else if (it.representsItself() && !it->visible_content_rect().IsEmpty()) {
565 bool has_occlusion_from_outside_target_surface;
566 bool impl_draw_transform_is_unknown = false;
567 if (occlusion_tracker.Occluded(
568 it->render_target(),
569 it->visible_content_rect(),
570 it->draw_transform(),
571 impl_draw_transform_is_unknown,
572 it->is_clipped(),
573 it->clip_rect(),
574 &has_occlusion_from_outside_target_surface)) {
575 append_quads_data.hadOcclusionFromOutsideTargetSurface |=
576 has_occlusion_from_outside_target_surface;
577 } else {
578 DCHECK_EQ(active_tree_, it->layer_tree_impl());
579 it->WillDraw(resource_provider_.get());
580 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57581
[email protected]c1bb5af2013-03-13 19:06:27582 if (it->HasContributingDelegatedRenderPasses()) {
583 RenderPass::Id contributing_render_pass_id =
584 it->FirstContributingRenderPassId();
585 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
586 frame->render_passes_by_id.end()) {
587 RenderPass* render_pass =
588 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14589
[email protected]c1bb5af2013-03-13 19:06:27590 AppendQuadsData append_quads_data(render_pass->id);
591 AppendQuadsForLayer(render_pass,
592 *it,
593 occlusion_tracker,
594 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57595
[email protected]c1bb5af2013-03-13 19:06:27596 contributing_render_pass_id =
597 it->NextContributingRenderPassId(contributing_render_pass_id);
598 }
[email protected]94f206c12012-08-25 00:09:14599 }
600
[email protected]c1bb5af2013-03-13 19:06:27601 AppendQuadsForLayer(target_render_pass,
602 *it,
603 occlusion_tracker,
604 &append_quads_data);
605 }
[email protected]89228202012-08-29 03:20:30606
[email protected]c1bb5af2013-03-13 19:06:27607 ++cumulative_num_layers_drawn_;
[email protected]94f206c12012-08-25 00:09:14608 }
609
[email protected]c1bb5af2013-03-13 19:06:27610 if (append_quads_data.hadOcclusionFromOutsideTargetSurface)
611 target_render_pass->has_occlusion_from_outside_target_surface = true;
612
613 if (append_quads_data.numMissingTiles) {
614 cumulative_num_missing_tiles_ += append_quads_data.numMissingTiles;
615 bool layer_has_animating_transform =
616 it->screen_space_transform_is_animating() ||
617 it->draw_transform_is_animating();
618 if (layer_has_animating_transform)
619 draw_frame = false;
620 }
621
622 if (append_quads_data.hadIncompleteTile)
623 frame->contains_incomplete_tile = true;
624
625 occlusion_tracker.LeaveLayer(it);
626 }
627
[email protected]1d993172012-10-18 18:15:04628#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27629 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
630 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
631 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
632 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
633 != frame->render_passes_by_id.end());
634 }
[email protected]94f206c12012-08-25 00:09:14635#endif
[email protected]c1bb5af2013-03-13 19:06:27636 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14637
[email protected]c1bb5af2013-03-13 19:06:27638 if (!active_tree_->has_transparent_background()) {
639 frame->render_passes.back()->has_transparent_background = false;
640 AppendQuadsToFillScreen(frame->render_passes.back(),
641 active_tree_->root_layer(),
642 active_tree_->background_color(),
643 occlusion_tracker);
644 }
[email protected]94f206c12012-08-25 00:09:14645
[email protected]c1bb5af2013-03-13 19:06:27646 if (draw_frame)
647 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]94f206c12012-08-25 00:09:14648
[email protected]c1bb5af2013-03-13 19:06:27649 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
650 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
651 RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame);
[email protected]94f206c12012-08-25 00:09:14652
[email protected]c1bb5af2013-03-13 19:06:27653 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14654}
655
[email protected]c1bb5af2013-03-13 19:06:27656void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) {
657 // Lazily create the time_source adapter so that we can vary the interval for
658 // testing.
659 if (!time_source_client_adapter_) {
660 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
661 this,
662 DelayBasedTimeSource::create(LowFrequencyAnimationInterval(),
663 proxy_->CurrentThread()));
664 }
[email protected]94f206c12012-08-25 00:09:14665
[email protected]c1bb5af2013-03-13 19:06:27666 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14667}
668
[email protected]c1bb5af2013-03-13 19:06:27669static inline RenderPass* FindRenderPassById(
670 RenderPass::Id render_pass_id,
671 const LayerTreeHostImpl::FrameData& frame) {
672 RenderPassIdHashMap::const_iterator it =
673 frame.render_passes_by_id.find(render_pass_id);
674 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14675}
676
[email protected]c1bb5af2013-03-13 19:06:27677static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
678 LayerTreeHostImpl::FrameData* frame) {
679 RenderPass* remove_render_pass =
680 FindRenderPassById(remove_render_pass_id, *frame);
681 // The pass was already removed by another quad - probably the original, and
682 // we are the replica.
683 if (!remove_render_pass)
684 return;
685 RenderPassList& render_passes = frame->render_passes;
686 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
687 render_passes.end(),
688 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14689
[email protected]c1bb5af2013-03-13 19:06:27690 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14691
[email protected]c1bb5af2013-03-13 19:06:27692 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
693 frame->render_passes.erase(to_remove);
694 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14695
[email protected]c1bb5af2013-03-13 19:06:27696 // Now follow up for all RenderPass quads and remove their RenderPasses
697 // recursively.
698 const QuadList& quad_list = removed_pass->quad_list;
699 QuadList::constBackToFrontIterator quad_list_iterator =
700 quad_list.backToFrontBegin();
701 for (; quad_list_iterator != quad_list.backToFrontEnd();
702 ++quad_list_iterator) {
703 DrawQuad* current_quad = (*quad_list_iterator);
704 if (current_quad->material != DrawQuad::RENDER_PASS)
705 continue;
[email protected]94f206c12012-08-25 00:09:14706
[email protected]c1bb5af2013-03-13 19:06:27707 RenderPass::Id next_remove_render_pass_id =
708 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
709 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
710 }
[email protected]94f206c12012-08-25 00:09:14711}
712
[email protected]c1bb5af2013-03-13 19:06:27713bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
714 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
715 const FrameData& frame) const {
716 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
717 bool quad_has_cached_resource =
718 renderer_.HaveCachedResourcesForRenderPassId(quad.render_pass_id);
719 if (quad_has_damage) {
720 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
721 return false;
722 } else if (!quad_has_cached_resource) {
723 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
724 return false;
725 }
726 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
727 return true;
[email protected]94f206c12012-08-25 00:09:14728}
729
[email protected]c1bb5af2013-03-13 19:06:27730bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
731 const RenderPassDrawQuad& quad, const FrameData& frame) const {
732 const RenderPass* render_pass =
733 FindRenderPassById(quad.render_pass_id, frame);
734 if (!render_pass)
735 return false;
[email protected]94f206c12012-08-25 00:09:14736
[email protected]c1bb5af2013-03-13 19:06:27737 // If any quad or RenderPass draws into this RenderPass, then keep it.
738 const QuadList& quad_list = render_pass->quad_list;
739 for (QuadList::constBackToFrontIterator quad_list_iterator =
740 quad_list.backToFrontBegin();
741 quad_list_iterator != quad_list.backToFrontEnd();
742 ++quad_list_iterator) {
743 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14744
[email protected]c1bb5af2013-03-13 19:06:27745 if (current_quad->material != DrawQuad::RENDER_PASS)
746 return false;
[email protected]94f206c12012-08-25 00:09:14747
[email protected]c1bb5af2013-03-13 19:06:27748 const RenderPass* contributing_pass = FindRenderPassById(
749 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
750 if (contributing_pass)
751 return false;
752 }
753 return true;
[email protected]94f206c12012-08-25 00:09:14754}
755
756// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27757template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
758 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
759 CullRenderPassesWithCachedTextures culler, FrameData* frame);
760template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
761 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
762 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14763
764// static
[email protected]c1bb5af2013-03-13 19:06:27765template <typename RenderPassCuller>
766void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
767 FrameData* frame) {
768 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
769 it != culler.RenderPassListEnd(frame->render_passes);
770 it = culler.RenderPassListNext(it)) {
771 const RenderPass* current_pass = frame->render_passes[it];
772 const QuadList& quad_list = current_pass->quad_list;
773 QuadList::constBackToFrontIterator quad_list_iterator =
774 quad_list.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14775
[email protected]c1bb5af2013-03-13 19:06:27776 for (; quad_list_iterator != quad_list.backToFrontEnd();
777 ++quad_list_iterator) {
778 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14779
[email protected]c1bb5af2013-03-13 19:06:27780 if (current_quad->material != DrawQuad::RENDER_PASS)
781 continue;
[email protected]94f206c12012-08-25 00:09:14782
[email protected]c1bb5af2013-03-13 19:06:27783 const RenderPassDrawQuad* render_pass_quad =
784 RenderPassDrawQuad::MaterialCast(current_quad);
785 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
786 continue;
[email protected]94f206c12012-08-25 00:09:14787
[email protected]c1bb5af2013-03-13 19:06:27788 // We are changing the vector in the middle of iteration. Because we
789 // delete render passes that draw into the current pass, we are
790 // guaranteed that any data from the iterator to the end will not
791 // change. So, capture the iterator position from the end of the
792 // list, and restore it after the change.
793 size_t position_from_end = frame->render_passes.size() - it;
794 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
795 it = frame->render_passes.size() - position_from_end;
796 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14797 }
[email protected]c1bb5af2013-03-13 19:06:27798 }
[email protected]94f206c12012-08-25 00:09:14799}
800
[email protected]c1bb5af2013-03-13 19:06:27801bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
802 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14803
[email protected]c1bb5af2013-03-13 19:06:27804 active_tree_->UpdateDrawProperties(
805 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27806
[email protected]c1bb5af2013-03-13 19:06:27807 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
808 frame->render_passes.clear();
809 frame->render_passes_by_id.clear();
810 frame->will_draw_layers.clear();
[email protected]94f206c12012-08-25 00:09:14811
[email protected]c1bb5af2013-03-13 19:06:27812 if (!CalculateRenderPasses(frame))
813 return false;
[email protected]94f206c12012-08-25 00:09:14814
[email protected]c1bb5af2013-03-13 19:06:27815 // If we return true, then we expect DrawLayers() to be called before this
816 // function is called again.
817 return true;
[email protected]94f206c12012-08-25 00:09:14818}
819
[email protected]c1bb5af2013-03-13 19:06:27820void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
821 const ManagedMemoryPolicy& policy) {
822 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
823 visible_ ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible,
824 ManagedMemoryPolicy::priorityCutoffToValue(
825 visible_ ?
826 policy.priorityCutoffWhenVisible :
827 policy.priorityCutoffWhenNotVisible));
828 if (evicted_resources) {
829 active_tree_->SetContentsTexturesPurged();
830 if (pending_tree_)
831 pending_tree_->SetContentsTexturesPurged();
832 client_->SetNeedsCommitOnImplThread();
833 client_->OnCanDrawStateChanged(CanDraw());
834 client_->RenewTreePriority();
835 }
836 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43837
[email protected]c1bb5af2013-03-13 19:06:27838 if (tile_manager_) {
839 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
840 new_state.memory_limit_in_bytes = visible_ ?
841 policy.bytesLimitWhenVisible :
842 policy.bytesLimitWhenNotVisible;
843 new_state.memory_limit_policy =
844 ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy(
845 visible_ ?
846 policy.priorityCutoffWhenVisible :
847 policy.priorityCutoffWhenNotVisible);
848 tile_manager_->SetGlobalState(new_state);
849 }
[email protected]94f206c12012-08-25 00:09:14850}
851
[email protected]c1bb5af2013-03-13 19:06:27852bool LayerTreeHostImpl::HasImplThread() const {
853 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44854}
855
[email protected]c1bb5af2013-03-13 19:06:27856void LayerTreeHostImpl::ScheduleManageTiles() {
857 if (client_)
858 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43859}
860
[email protected]c1bb5af2013-03-13 19:06:27861void LayerTreeHostImpl::DidUploadVisibleHighResolutionTile() {
862 if (client_)
863 client_->DidUploadVisibleHighResolutionTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47864}
865
[email protected]c1bb5af2013-03-13 19:06:27866bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
867 return settings_.shouldClearRootRenderPass;
[email protected]f35e2322012-12-15 21:45:52868}
869
[email protected]c1bb5af2013-03-13 19:06:27870void LayerTreeHostImpl::SetManagedMemoryPolicy(
871 const ManagedMemoryPolicy& policy) {
872 if (managed_memory_policy_ == policy)
873 return;
[email protected]61de5812012-11-08 07:03:44874
[email protected]c1bb5af2013-03-13 19:06:27875 managed_memory_policy_ = policy;
876 if (!proxy_->HasImplThread()) {
877 // TODO(ccameron): In single-thread mode, this can be called on the main
878 // thread by GLRenderer::OnMemoryAllocationChanged.
879 DebugScopedSetImplThread impl_thread(proxy_);
880 EnforceManagedMemoryPolicy(managed_memory_policy_);
881 } else {
882 DCHECK(proxy_->IsImplThread());
883 EnforceManagedMemoryPolicy(managed_memory_policy_);
884 }
885 // We always need to commit after changing the memory policy because the new
886 // limit can result in more or less content having texture allocated for it.
887 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:14888}
889
[email protected]c1bb5af2013-03-13 19:06:27890void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
891 base::TimeDelta interval) {
892 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14893}
894
[email protected]c1bb5af2013-03-13 19:06:27895void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
896 const CompositorFrameAck& ack) {
897 if (!renderer_)
898 return;
[email protected]b6f3d7e2012-12-08 00:11:21899
[email protected]c1bb5af2013-03-13 19:06:27900 // TODO(piman): We may need to do some validation on this ack before
901 // processing it.
902 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16903}
904
[email protected]c1bb5af2013-03-13 19:06:27905void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
906 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:29907}
908
[email protected]c1bb5af2013-03-13 19:06:27909CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
910 CompositorFrameMetadata metadata;
911 metadata.device_scale_factor = device_scale_factor_;
912 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
913 metadata.viewport_size = active_tree_->ScrollableViewportSize();
914 metadata.root_layer_size = active_tree_->ScrollableSize();
915 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
916 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
917 if (top_controls_manager_) {
918 metadata.location_bar_offset =
919 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
920 metadata.location_bar_content_translation =
921 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
922 }
[email protected]bf189f62012-12-18 03:42:11923
[email protected]c1bb5af2013-03-13 19:06:27924 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:11925 return metadata;
[email protected]c1bb5af2013-03-13 19:06:27926
927 metadata.root_scroll_offset = RootScrollLayer()->scroll_offset() +
928 RootScrollLayer()->scroll_delta();
929
930 return metadata;
[email protected]bf189f62012-12-18 03:42:11931}
932
[email protected]c1bb5af2013-03-13 19:06:27933void LayerTreeHostImpl::DrawLayers(FrameData* frame) {
934 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
935 DCHECK(CanDraw());
936 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14937
[email protected]c1bb5af2013-03-13 19:06:27938 // FIXME: use the frame begin time from the overall compositor scheduler.
939 // This value is currently inaccessible because it is up in Chromium's
940 // RenderWidget.
941 fps_counter_->saveTimeStamp(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:14942
[email protected]c1bb5af2013-03-13 19:06:27943 if (tile_manager_) {
944 memory_history_->SaveEntry(
945 tile_manager_->memory_stats_from_last_assign());
946 }
[email protected]1191d9d2013-02-02 06:00:33947
[email protected]c1bb5af2013-03-13 19:06:27948 if (debug_state_.showHudRects()) {
[email protected]d35992782013-03-14 14:54:02949 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:27950 active_tree_->root_layer(),
951 *frame->render_surface_layer_list,
952 frame->occluding_screen_space_rects,
953 frame->non_occluding_screen_space_rects,
954 debug_state_);
955 }
[email protected]94f206c12012-08-25 00:09:14956
[email protected]c1bb5af2013-03-13 19:06:27957 if (debug_state_.traceAllRenderedFrames) {
958 TRACE_EVENT_INSTANT1("cc.debug", "Frame",
959 "frame", ValueToString(FrameStateAsValue()));
960 }
[email protected]131a0c22013-02-12 18:31:08961
[email protected]c1bb5af2013-03-13 19:06:27962 // Because the contents of the HUD depend on everything else in the frame, the
963 // contents of its texture are updated as the last thing before the frame is
964 // drawn.
965 if (active_tree_->hud_layer())
966 active_tree_->hud_layer()->updateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:14967
[email protected]c1bb5af2013-03-13 19:06:27968 renderer_->DrawFrame(frame->render_passes);
969 // The render passes should be consumed by the renderer.
970 DCHECK(frame->render_passes.empty());
971 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:14972
[email protected]c1bb5af2013-03-13 19:06:27973 // The next frame should start by assuming nothing has changed, and changes
974 // are noted as they occur.
975 for (unsigned int i = 0; i < frame->render_surface_layer_list->size(); i++) {
976 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
977 DidDrawDamagedArea();
978 }
979 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
980 UpdateAnimationState();
[email protected]94f206c12012-08-25 00:09:14981}
982
[email protected]c1bb5af2013-03-13 19:06:27983void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
984 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
985 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:52986
[email protected]c1bb5af2013-03-13 19:06:27987 // Once all layers have been drawn, pending texture uploads should no
988 // longer block future uploads.
989 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:14990}
991
[email protected]c1bb5af2013-03-13 19:06:27992void LayerTreeHostImpl::FinishAllRendering() {
993 if (renderer_)
994 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:14995}
996
[email protected]c1bb5af2013-03-13 19:06:27997bool LayerTreeHostImpl::IsContextLost() {
998 DCHECK(proxy_->IsImplThread());
999 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141000}
1001
[email protected]c1bb5af2013-03-13 19:06:271002const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1003 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141004}
1005
[email protected]c1bb5af2013-03-13 19:06:271006bool LayerTreeHostImpl::SwapBuffers() {
1007 if (tile_manager_)
1008 tile_manager_->DidCompleteFrame();
1009 return renderer_->SwapBuffers();
[email protected]94f206c12012-08-25 00:09:141010}
1011
[email protected]c1bb5af2013-03-13 19:06:271012gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1013 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101014}
1015
[email protected]c1bb5af2013-03-13 19:06:271016const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1017 return settings();
[email protected]493067512012-09-19 23:34:101018}
1019
[email protected]c1bb5af2013-03-13 19:06:271020void LayerTreeHostImpl::DidLoseOutputSurface() {
1021 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141022}
1023
[email protected]c1bb5af2013-03-13 19:06:271024void LayerTreeHostImpl::OnSwapBuffersComplete() {
1025 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141026}
1027
[email protected]c1bb5af2013-03-13 19:06:271028void LayerTreeHostImpl::Readback(void* pixels,
1029 gfx::Rect rect_in_device_viewport) {
1030 DCHECK(renderer_);
1031 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141032}
1033
[email protected]69b50ec2013-01-19 04:58:011034bool LayerTreeHostImpl::haveRootScrollLayer() const {
[email protected]c1bb5af2013-03-13 19:06:271035 return RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011036}
1037
1038float LayerTreeHostImpl::rootScrollLayerTotalScrollY() const {
[email protected]c1bb5af2013-03-13 19:06:271039 if (LayerImpl* layer = RootScrollLayer())
[email protected]7aba6662013-03-12 10:17:341040 return layer->scroll_offset().y() + layer->scroll_delta().y();
[email protected]69b50ec2013-01-19 04:58:011041 return 0.0f;
1042}
1043
[email protected]c1bb5af2013-03-13 19:06:271044LayerImpl* LayerTreeHostImpl::RootLayer() const {
1045 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081046}
1047
[email protected]c1bb5af2013-03-13 19:06:271048LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1049 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081050}
1051
[email protected]c1bb5af2013-03-13 19:06:271052LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1053 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081054}
1055
[email protected]94f206c12012-08-25 00:09:141056// Content layers can be either directly scrollable or contained in an outer
1057// scrolling layer which applies the scroll transform. Given a content layer,
1058// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271059static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1060 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141061 return 0;
[email protected]c1bb5af2013-03-13 19:06:271062
1063 if (layer_impl->scrollable())
1064 return layer_impl;
1065
1066 if (layer_impl->DrawsContent() &&
1067 layer_impl->parent() &&
1068 layer_impl->parent()->scrollable())
1069 return layer_impl->parent();
1070
1071 return 0;
[email protected]94f206c12012-08-25 00:09:141072}
1073
[email protected]c1bb5af2013-03-13 19:06:271074void LayerTreeHostImpl::CreatePendingTree() {
1075 CHECK(!pending_tree_);
1076 if (recycle_tree_)
1077 recycle_tree_.swap(pending_tree_);
1078 else
1079 pending_tree_ = LayerTreeImpl::create(this);
1080 client_->OnCanDrawStateChanged(CanDraw());
1081 client_->OnHasPendingTreeStateChanged(pending_tree_);
1082 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1083 TRACE_EVENT_ASYNC_STEP0("cc",
1084 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271085}
1086
[email protected]c1bb5af2013-03-13 19:06:271087void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1088 DCHECK(!client_->IsInsideDraw()) <<
1089 "Checking for completed uploads within a draw may trigger "
1090 "spurious redraws.";
1091 if (tile_manager_)
1092 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481093}
1094
[email protected]c1bb5af2013-03-13 19:06:271095bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1096 if (!pending_tree_)
1097 return false;
[email protected]2e7ca422012-12-20 02:57:271098
[email protected]c1bb5af2013-03-13 19:06:271099 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091100
[email protected]c1bb5af2013-03-13 19:06:271101 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161102
[email protected]c1bb5af2013-03-13 19:06:271103 TRACE_EVENT_ASYNC_STEP1("cc",
1104 "PendingTree", pending_tree_.get(), "activate",
1105 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271106
[email protected]c1bb5af2013-03-13 19:06:271107 // It's always fine to activate to an empty tree. Otherwise, only
1108 // activate once all visible resources in pending tree are ready
1109 // or tile manager has no work scheduled for pending tree.
1110 if (active_tree_->root_layer() &&
1111 !pending_tree_->AreVisibleResourcesReady()) {
1112 // In smoothness takes priority mode, the pending tree's priorities are
1113 // ignored, so the tile manager may not have work for it even though it
1114 // is simultaneously not ready to be activated.
1115 if (tile_manager_->GlobalState().tree_priority ==
1116 SMOOTHNESS_TAKES_PRIORITY ||
1117 tile_manager_->HasPendingWorkScheduled(PENDING_TREE)) {
1118 TRACE_EVENT_ASYNC_STEP0("cc",
1119 "PendingTree",
1120 pending_tree_.get(),
1121 "waiting");
1122 return false;
[email protected]131a0c22013-02-12 18:31:081123 }
[email protected]c1bb5af2013-03-13 19:06:271124 }
[email protected]2e7ca422012-12-20 02:57:271125
[email protected]c1bb5af2013-03-13 19:06:271126 ActivatePendingTree();
1127 return true;
[email protected]2e7ca422012-12-20 02:57:271128}
1129
[email protected]c1bb5af2013-03-13 19:06:271130void LayerTreeHostImpl::ActivatePendingTree() {
1131 CHECK(pending_tree_);
1132 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351133
[email protected]c1bb5af2013-03-13 19:06:271134 active_tree_->PushPersistedState(pending_tree_.get());
1135 if (pending_tree_->needs_full_tree_sync()) {
1136 active_tree_->SetRootLayer(
1137 TreeSynchronizer::synchronizeTrees(pending_tree_->root_layer(),
1138 active_tree_->DetachLayerTree(),
1139 active_tree_.get()));
1140 }
1141 TreeSynchronizer::pushProperties(pending_tree_->root_layer(),
1142 active_tree_->root_layer());
1143 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511144
[email protected]c1bb5af2013-03-13 19:06:271145 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511146
[email protected]c1bb5af2013-03-13 19:06:271147 // Now that we've synced everything from the pending tree to the active
1148 // tree, rename the pending tree the recycle tree so we can reuse it on the
1149 // next sync.
1150 pending_tree_.swap(recycle_tree_);
1151 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511152
[email protected]c1bb5af2013-03-13 19:06:271153 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221154
[email protected]c1bb5af2013-03-13 19:06:271155 // Reduce wasted memory now that unlinked resources are guaranteed not
1156 // to be used.
1157 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411158
[email protected]c1bb5af2013-03-13 19:06:271159 client_->OnCanDrawStateChanged(CanDraw());
1160 client_->OnHasPendingTreeStateChanged(pending_tree_);
1161 client_->SetNeedsRedrawOnImplThread();
1162 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241163
[email protected]c1bb5af2013-03-13 19:06:271164 if (tile_manager_ && debug_state_.continuousPainting) {
1165 RenderingStats stats;
1166 tile_manager_->GetRenderingStats(&stats);
1167 paint_time_counter_->SaveRasterizeTime(
1168 stats.totalRasterizeTimeForNowBinsOnPendingTree,
1169 active_tree_->source_frame_number());
1170 }
[email protected]2e7ca422012-12-20 02:57:271171}
1172
[email protected]c1bb5af2013-03-13 19:06:271173void LayerTreeHostImpl::SetVisible(bool visible) {
1174 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141175
[email protected]c1bb5af2013-03-13 19:06:271176 if (visible_ == visible)
1177 return;
1178 visible_ = visible;
1179 DidVisibilityChange(this, visible_);
1180 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141181
[email protected]c1bb5af2013-03-13 19:06:271182 if (!renderer_)
1183 return;
[email protected]94f206c12012-08-25 00:09:141184
[email protected]c1bb5af2013-03-13 19:06:271185 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141186
[email protected]c1bb5af2013-03-13 19:06:271187 SetBackgroundTickingEnabled(
1188 !visible_ &&
1189 !animation_registrar_->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141190}
1191
[email protected]c1bb5af2013-03-13 19:06:271192bool LayerTreeHostImpl::InitializeRenderer(
1193 scoped_ptr<OutputSurface> output_surface) {
1194 // Since we will create a new resource provider, we cannot continue to use
1195 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1196 // before we destroy the old resource provider.
1197 if (active_tree_->root_layer())
1198 ClearRenderSurfaces();
1199 if (active_tree_->root_layer())
1200 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1201 if (pending_tree_ && pending_tree_->root_layer())
1202 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1203 if (recycle_tree_ && recycle_tree_->root_layer())
1204 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]45c4b1e2013-01-16 02:19:401205
[email protected]c1bb5af2013-03-13 19:06:271206 // Note: order is important here.
1207 renderer_.reset();
1208 tile_manager_.reset();
1209 resource_provider_.reset();
1210 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141211
[email protected]c1bb5af2013-03-13 19:06:271212 if (!output_surface->BindToClient(this))
1213 return false;
[email protected]be3181652012-09-25 13:02:131214
[email protected]c1bb5af2013-03-13 19:06:271215 scoped_ptr<ResourceProvider> resource_provider =
1216 ResourceProvider::Create(output_surface.get());
1217 if (!resource_provider)
1218 return false;
[email protected]be3181652012-09-25 13:02:131219
[email protected]c1bb5af2013-03-13 19:06:271220 if (settings_.implSidePainting) {
1221 tile_manager_.reset(new TileManager(this,
1222 resource_provider.get(),
1223 settings_.numRasterThreads,
1224 settings_.useCheapnessEstimator,
1225 settings_.useColorEstimator,
1226 settings_.predictionBenchmarking));
1227 tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats());
1228 }
[email protected]8947cbe2012-11-28 05:27:431229
[email protected]c1bb5af2013-03-13 19:06:271230 if (output_surface->capabilities().has_parent_compositor) {
1231 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1232 resource_provider.get());
1233 } else if (output_surface->context3d()) {
1234 renderer_ = GLRenderer::Create(this,
1235 output_surface.get(),
1236 resource_provider.get());
1237 } else if (output_surface->software_device()) {
1238 renderer_ = SoftwareRenderer::Create(this,
1239 output_surface.get(),
1240 resource_provider.get());
1241 }
1242 if (!renderer_)
1243 return false;
[email protected]be3181652012-09-25 13:02:131244
[email protected]c1bb5af2013-03-13 19:06:271245 resource_provider_ = resource_provider.Pass();
1246 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141247
[email protected]c1bb5af2013-03-13 19:06:271248 if (!visible_)
1249 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141250
[email protected]c1bb5af2013-03-13 19:06:271251 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211252
[email protected]c1bb5af2013-03-13 19:06:271253 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1254 // to be initialized to get max texture size.
1255 active_tree_->set_needs_update_draw_properties();
1256 if (pending_tree_)
1257 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161258
[email protected]c1bb5af2013-03-13 19:06:271259 return true;
[email protected]94f206c12012-08-25 00:09:141260}
1261
[email protected]c1bb5af2013-03-13 19:06:271262void LayerTreeHostImpl::SetViewportSize(gfx::Size layout_viewport_size,
1263 gfx::Size device_viewport_size) {
1264 if (layout_viewport_size == layout_viewport_size_ &&
1265 device_viewport_size == device_viewport_size_)
1266 return;
[email protected]94f206c12012-08-25 00:09:141267
[email protected]c1bb5af2013-03-13 19:06:271268 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1269 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271270
[email protected]c1bb5af2013-03-13 19:06:271271 layout_viewport_size_ = layout_viewport_size;
1272 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141273
[email protected]c1bb5af2013-03-13 19:06:271274 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141275
[email protected]c1bb5af2013-03-13 19:06:271276 if (renderer_)
1277 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211278
[email protected]c1bb5af2013-03-13 19:06:271279 client_->OnCanDrawStateChanged(CanDraw());
[email protected]94f206c12012-08-25 00:09:141280}
1281
[email protected]c1bb5af2013-03-13 19:06:271282static void AdjustScrollsForPageScaleChange(LayerImpl* layer_impl,
1283 float page_scale_change) {
1284 if (!layer_impl)
1285 return;
[email protected]94f206c12012-08-25 00:09:141286
[email protected]c1bb5af2013-03-13 19:06:271287 if (layer_impl->scrollable()) {
1288 // We need to convert impl-side scroll deltas to page_scale space.
1289 gfx::Vector2dF scroll_delta = layer_impl->scroll_delta();
1290 scroll_delta.Scale(page_scale_change);
1291 layer_impl->SetScrollDelta(scroll_delta);
1292 }
[email protected]94f206c12012-08-25 00:09:141293
[email protected]c1bb5af2013-03-13 19:06:271294 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1295 AdjustScrollsForPageScaleChange(layer_impl->children()[i],
1296 page_scale_change);
[email protected]94f206c12012-08-25 00:09:141297}
1298
[email protected]c1bb5af2013-03-13 19:06:271299void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1300 if (device_scale_factor == device_scale_factor_)
1301 return;
1302 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271303
[email protected]c1bb5af2013-03-13 19:06:271304 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141305}
1306
[email protected]c1bb5af2013-03-13 19:06:271307void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1308 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141309}
1310
[email protected]c1bb5af2013-03-13 19:06:271311void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() {
1312 active_tree_->set_needs_update_draw_properties();
[email protected]3ba4cae2013-01-16 03:58:381313}
1314
[email protected]c1bb5af2013-03-13 19:06:271315void LayerTreeHostImpl::setNeedsRedraw() {
1316 client_->SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:141317}
1318
[email protected]c1bb5af2013-03-13 19:06:271319bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1320 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
1321 return active_tree_->RenderSurfaceLayerList().size();
[email protected]94f206c12012-08-25 00:09:141322}
1323
[email protected]c1bb5af2013-03-13 19:06:271324InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1325 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
1326 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin");
[email protected]94f206c12012-08-25 00:09:141327
[email protected]c1bb5af2013-03-13 19:06:271328 if (top_controls_manager_)
1329 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381330
[email protected]c1bb5af2013-03-13 19:06:271331 DCHECK(!CurrentlyScrollingLayer());
1332 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141333
[email protected]c1bb5af2013-03-13 19:06:271334 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141335 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141336
[email protected]c1bb5af2013-03-13 19:06:271337 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1338 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141339
[email protected]c1bb5af2013-03-13 19:06:271340 // First find out which layer was hit from the saved list of visible layers
1341 // in the most recent frame.
1342 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
1343 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521344
[email protected]c1bb5af2013-03-13 19:06:271345 // Walk up the hierarchy and look for a scrollable layer.
1346 LayerImpl* potentially_scrolling_layer_impl = 0;
1347 for (; layer_impl; layer_impl = layer_impl->parent()) {
1348 // The content layer can also block attempts to scroll outside the main
1349 // thread.
1350 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1351 if (status == ScrollOnMainThread) {
1352 num_main_thread_scrolls_++;
1353 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
1354 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141355 }
1356
[email protected]c1bb5af2013-03-13 19:06:271357 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1358 if (!scroll_layer_impl)
1359 continue;
[email protected]94f206c12012-08-25 00:09:141360
[email protected]c1bb5af2013-03-13 19:06:271361 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141362
[email protected]c1bb5af2013-03-13 19:06:271363 // If any layer wants to divert the scroll event to the main thread, abort.
1364 if (status == ScrollOnMainThread) {
1365 num_main_thread_scrolls_++;
1366 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
1367 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141368 }
1369
[email protected]c1bb5af2013-03-13 19:06:271370 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1371 potentially_scrolling_layer_impl = scroll_layer_impl;
1372 }
1373
1374 // When hiding top controls is enabled and the controls are hidden or
1375 // overlaying the content, force scrolls to be enabled on the root layer to
1376 // allow bringing the top controls back into view.
1377 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1378 top_controls_manager_->content_top_offset() !=
1379 settings_.topControlsHeight) {
1380 potentially_scrolling_layer_impl = RootScrollLayer();
1381 }
1382
1383 if (potentially_scrolling_layer_impl) {
1384 active_tree_->set_currently_scrolling_layer(
1385 potentially_scrolling_layer_impl);
1386 should_bubble_scrolls_ = (type != NonBubblingGesture);
1387 wheel_scrolling_ = (type == Wheel);
1388 num_impl_thread_scrolls_++;
1389 client_->RenewTreePriority();
1390 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
1391 return ScrollStarted;
1392 }
1393 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141394}
1395
[email protected]c1bb5af2013-03-13 19:06:271396gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1397 LayerImpl* layer_impl,
1398 float scale_from_viewport_to_screen_space,
1399 gfx::PointF viewport_point,
1400 gfx::Vector2dF viewport_delta) {
1401 // Layers with non-invertible screen space transforms should not have passed
1402 // the scroll hit test in the first place.
1403 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1404 gfx::Transform inverse_screen_space_transform(
1405 gfx::Transform::kSkipInitialization);
1406 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1407 &inverse_screen_space_transform);
1408 // TODO: With the advent of impl-side crolling for non-root layers, we may
1409 // need to explicitly handle uninvertible transforms here.
1410 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141411
[email protected]c1bb5af2013-03-13 19:06:271412 gfx::PointF screen_space_point =
1413 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141414
[email protected]c1bb5af2013-03-13 19:06:271415 gfx::Vector2dF screen_space_delta = viewport_delta;
1416 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1417
1418 // First project the scroll start and end points to local layer space to find
1419 // the scroll delta in layer coordinates.
1420 bool start_clipped, end_clipped;
1421 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1422 gfx::PointF local_start_point =
1423 MathUtil::projectPoint(inverse_screen_space_transform,
1424 screen_space_point,
1425 start_clipped);
1426 gfx::PointF local_end_point =
1427 MathUtil::projectPoint(inverse_screen_space_transform,
1428 screen_space_end_point,
1429 end_clipped);
1430
1431 // In general scroll point coordinates should not get clipped.
1432 DCHECK(!start_clipped);
1433 DCHECK(!end_clipped);
1434 if (start_clipped || end_clipped)
1435 return gfx::Vector2dF();
1436
1437 // local_start_point and local_end_point are in content space but we want to
1438 // move them to layer space for scrolling.
1439 float width_scale = 1.f / layer_impl->contents_scale_x();
1440 float height_scale = 1.f / layer_impl->contents_scale_y();
1441 local_start_point.Scale(width_scale, height_scale);
1442 local_end_point.Scale(width_scale, height_scale);
1443
1444 // Apply the scroll delta.
1445 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1446 layer_impl->ScrollBy(local_end_point - local_start_point);
1447
1448 // Get the end point in the layer's content space so we can apply its
1449 // ScreenSpaceTransform.
1450 gfx::PointF actual_local_end_point = local_start_point +
1451 layer_impl->scroll_delta() -
1452 previous_delta;
1453 gfx::PointF actual_local_content_end_point =
1454 gfx::ScalePoint(actual_local_end_point,
1455 1.f / width_scale,
1456 1.f / height_scale);
1457
1458 // Calculate the applied scroll delta in viewport space coordinates.
1459 gfx::PointF actual_screen_space_end_point =
1460 MathUtil::mapPoint(layer_impl->screen_space_transform(),
1461 actual_local_content_end_point,
1462 end_clipped);
1463 DCHECK(!end_clipped);
1464 if (end_clipped)
1465 return gfx::Vector2dF();
1466 gfx::PointF actual_viewport_end_point =
1467 gfx::ScalePoint(actual_screen_space_end_point,
1468 1.f / scale_from_viewport_to_screen_space);
1469 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141470}
1471
[email protected]c1bb5af2013-03-13 19:06:271472static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1473 gfx::Vector2dF local_delta) {
1474 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1475 layer_impl->ScrollBy(local_delta);
1476 return layer_impl->scroll_delta() - previous_delta;
1477}
1478
1479bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1480 gfx::Vector2dF scroll_delta) {
1481 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1482 if (!CurrentlyScrollingLayer())
1483 return false;
1484
1485 gfx::Vector2dF pending_delta = scroll_delta;
1486 bool did_scroll = false;
1487
1488 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1489 layer_impl;
1490 layer_impl = layer_impl->parent()) {
1491 if (!layer_impl->scrollable())
1492 continue;
1493
1494 gfx::Vector2dF applied_delta;
1495 if (top_controls_manager_ && layer_impl == RootScrollLayer())
1496 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
1497
1498 // Gesture events need to be transformed from viewport coordinates to local
1499 // layer coordinates so that the scrolling contents exactly follow the
1500 // user's finger. In contrast, wheel events represent a fixed amount of
1501 // scrolling so we can just apply them directly.
1502 if (!wheel_scrolling_) {
1503 float scale_from_viewport_to_screen_space = device_scale_factor_;
1504 applied_delta =
1505 ScrollLayerWithViewportSpaceDelta(layer_impl,
1506 scale_from_viewport_to_screen_space,
1507 viewport_point, pending_delta);
1508 } else {
1509 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141510 }
[email protected]94f206c12012-08-25 00:09:141511
[email protected]c1bb5af2013-03-13 19:06:271512 // If the layer wasn't able to move, try the next one in the hierarchy.
1513 float move_threshold_squared = 0.1f * 0.1f;
1514 if (applied_delta.LengthSquared() < move_threshold_squared) {
1515 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1516 continue;
1517 else
1518 break;
[email protected]94f206c12012-08-25 00:09:141519 }
[email protected]c1bb5af2013-03-13 19:06:271520 did_scroll = true;
1521 did_lock_scrolling_layer_ = true;
1522 if (!should_bubble_scrolls_) {
1523 active_tree_->set_currently_scrolling_layer(layer_impl);
1524 break;
[email protected]94f206c12012-08-25 00:09:141525 }
[email protected]94f206c12012-08-25 00:09:141526
[email protected]c1bb5af2013-03-13 19:06:271527 // If the applied delta is within 45 degrees of the input delta, bail out to
1528 // make it easier to scroll just one layer in one direction without
1529 // affecting any of its parents.
1530 float angle_threshold = 45;
1531 if (MathUtil::smallestAngleBetweenVectors(
1532 applied_delta, pending_delta) < angle_threshold) {
1533 pending_delta = gfx::Vector2d();
1534 break;
[email protected]4a23c374c2012-12-08 08:38:551535 }
[email protected]c1bb5af2013-03-13 19:06:271536
1537 // Allow further movement only on an axis perpendicular to the direction in
1538 // which the layer moved.
1539 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
1540 pending_delta = MathUtil::projectVector(pending_delta, perpendicular_axis);
1541
1542 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1543 break;
1544 }
1545
1546 if (did_scroll) {
1547 client_->SetNeedsCommitOnImplThread();
1548 client_->SetNeedsRedrawOnImplThread();
1549 client_->RenewTreePriority();
1550 }
1551 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551552}
1553
[email protected]c1bb5af2013-03-13 19:06:271554void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1555 active_tree_->ClearCurrentlyScrollingLayer();
1556 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141557}
1558
[email protected]c1bb5af2013-03-13 19:06:271559void LayerTreeHostImpl::ScrollEnd() {
1560 if (top_controls_manager_)
1561 top_controls_manager_->ScrollEnd();
1562 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141563}
1564
[email protected]c1bb5af2013-03-13 19:06:271565void LayerTreeHostImpl::PinchGestureBegin() {
1566 pinch_gesture_active_ = true;
1567 previous_pinch_anchor_ = gfx::Point();
1568 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141569}
1570
[email protected]c1bb5af2013-03-13 19:06:271571void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1572 gfx::Point anchor) {
1573 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281574
[email protected]c1bb5af2013-03-13 19:06:271575 if (!RootScrollLayer())
1576 return;
[email protected]d3afa112012-12-08 06:24:281577
[email protected]c1bb5af2013-03-13 19:06:271578 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1579 // position over the course of the magnify.
1580 float page_scale_delta = active_tree_->page_scale_delta();
1581 gfx::PointF previous_scale_anchor =
1582 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1583 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1584 page_scale_delta = active_tree_->page_scale_delta();
1585 gfx::PointF new_scale_anchor =
1586 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1587 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1588
1589 previous_pinch_anchor_ = anchor;
1590
1591 move.Scale(1 / active_tree_->page_scale_factor());
1592
1593 RootScrollLayer()->ScrollBy(move);
1594
1595 if (RootScrollLayer()->scrollbar_animation_controller()) {
1596 RootScrollLayer()->scrollbar_animation_controller()->
1597 didPinchGestureUpdate(base::TimeTicks::Now());
1598 }
1599
1600 client_->SetNeedsCommitOnImplThread();
1601 client_->SetNeedsRedrawOnImplThread();
1602 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281603}
1604
[email protected]c1bb5af2013-03-13 19:06:271605void LayerTreeHostImpl::PinchGestureEnd() {
1606 pinch_gesture_active_ = false;
1607
1608 if (RootScrollLayer() &&
1609 RootScrollLayer()->scrollbar_animation_controller()) {
1610 RootScrollLayer()->scrollbar_animation_controller()->
1611 didPinchGestureEnd(base::TimeTicks::Now());
1612 }
1613
1614 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141615}
1616
[email protected]c1bb5af2013-03-13 19:06:271617static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1618 LayerImpl* layer_impl) {
1619 if (!layer_impl)
1620 return;
[email protected]94f206c12012-08-25 00:09:141621
[email protected]c1bb5af2013-03-13 19:06:271622 gfx::Vector2d scroll_delta =
1623 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1624 if (!scroll_delta.IsZero()) {
1625 LayerTreeHostCommon::ScrollUpdateInfo scroll;
1626 scroll.layerId = layer_impl->id();
1627 scroll.scrollDelta = scroll_delta;
1628 scroll_info->scrolls.push_back(scroll);
1629 layer_impl->SetSentScrollDelta(scroll_delta);
1630 }
[email protected]94f206c12012-08-25 00:09:141631
[email protected]c1bb5af2013-03-13 19:06:271632 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1633 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141634}
1635
[email protected]c1bb5af2013-03-13 19:06:271636scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1637 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301638
[email protected]c1bb5af2013-03-13 19:06:271639 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
1640 scroll_info->pageScaleDelta = active_tree_->page_scale_delta();
1641 active_tree_->set_sent_page_scale_delta(scroll_info->pageScaleDelta);
[email protected]362f1e8b2013-01-21 16:54:301642
[email protected]c1bb5af2013-03-13 19:06:271643 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301644}
1645
[email protected]c1bb5af2013-03-13 19:06:271646void LayerTreeHostImpl::SetFullRootLayerDamage() {
1647 if (active_tree_->root_layer()) {
1648 RenderSurfaceImpl* render_surface =
1649 active_tree_->root_layer()->render_surface();
1650 if (render_surface)
1651 render_surface->damage_tracker()->ForceFullDamageNextUpdate();
1652 }
[email protected]829ad972013-01-28 23:36:101653}
1654
[email protected]c1bb5af2013-03-13 19:06:271655void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1656 if (!page_scale_animation_ || !RootScrollLayer())
1657 return;
1658
1659 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1660 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1661 RootScrollLayer()->scroll_delta();
1662
1663 active_tree_->SetPageScaleDelta(
1664 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1665 active_tree_->page_scale_factor());
1666 gfx::Vector2dF next_scroll =
1667 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1668
1669 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1670 client_->SetNeedsRedrawOnImplThread();
1671
1672 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1673 page_scale_animation_.reset();
1674 client_->SetNeedsCommitOnImplThread();
1675 client_->RenewTreePriority();
1676 }
[email protected]829ad972013-01-28 23:36:101677}
1678
[email protected]c1bb5af2013-03-13 19:06:271679void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1680 base::Time wall_clock_time) {
1681 if (!settings_.acceleratedAnimationEnabled ||
1682 animation_registrar_->active_animation_controllers().empty() ||
1683 !active_tree_->root_layer())
1684 return;
1685
1686 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1687
1688 last_animation_time_ = wall_clock_time;
1689 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1690
1691 AnimationRegistrar::AnimationControllerMap copy =
1692 animation_registrar_->active_animation_controllers();
1693 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1694 iter != copy.end();
1695 ++iter)
1696 (*iter).second->Animate(monotonic_seconds);
1697
1698 client_->SetNeedsRedrawOnImplThread();
1699 SetBackgroundTickingEnabled(
1700 !visible_ &&
1701 !animation_registrar_->active_animation_controllers().empty());
[email protected]131a0c22013-02-12 18:31:081702}
1703
[email protected]c1bb5af2013-03-13 19:06:271704void LayerTreeHostImpl::UpdateAnimationState() {
1705 if (!settings_.acceleratedAnimationEnabled ||
1706 animation_registrar_->active_animation_controllers().empty() ||
1707 !active_tree_->root_layer())
1708 return;
1709
1710 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1711 scoped_ptr<AnimationEventsVector> events =
1712 make_scoped_ptr(new AnimationEventsVector);
1713 AnimationRegistrar::AnimationControllerMap copy =
1714 animation_registrar_->active_animation_controllers();
1715 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1716 iter != copy.end();
1717 ++iter)
1718 (*iter).second->UpdateState(events.get());
1719
1720 if (!events->empty()) {
1721 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1722 last_animation_time_);
1723 }
[email protected]131a0c22013-02-12 18:31:081724}
1725
[email protected]c1bb5af2013-03-13 19:06:271726base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1727 return base::TimeDelta::FromSeconds(1);
1728}
1729
1730void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1731 DCHECK(current);
1732 current->DidLoseOutputSurface();
1733 if (current->mask_layer())
1734 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1735 if (current->replica_layer())
1736 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1737 for (size_t i = 0; i < current->children().size(); ++i)
1738 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1739}
1740
1741void LayerTreeHostImpl::ClearRenderSurfaces() {
1742 active_tree_->ClearRenderSurfaces();
1743 if (pending_tree_)
1744 pending_tree_->ClearRenderSurfaces();
1745}
1746
1747std::string LayerTreeHostImpl::LayerTreeAsText() const {
1748 std::string str;
1749 if (active_tree_->root_layer()) {
1750 str = active_tree_->root_layer()->LayerTreeAsText();
1751 str += "RenderSurfaces:\n";
1752 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1753 }
1754 return str;
1755}
1756
1757std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1758 std::string str;
1759 if (active_tree_->root_layer()) {
1760 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1761 base::JSONWriter::WriteWithOptions(
1762 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1763 }
1764 return str;
1765}
1766
1767void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1768 int indent,
1769 const LayerImpl* layer) const {
1770 if (layer->render_surface())
1771 layer->render_surface()->DumpSurface(str, indent);
1772
1773 for (size_t i = 0; i < layer->children().size(); ++i)
1774 DumpRenderSurfaces(str, indent, layer->children()[i]);
1775}
1776
1777int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
1778 return fps_counter_->currentFrameNumber();
1779}
1780
1781void LayerTreeHostImpl::CollectRenderingStats(RenderingStats* stats) const {
1782 stats->numFramesSentToScreen = fps_counter_->currentFrameNumber();
1783 stats->droppedFrameCount = fps_counter_->droppedFrameCount();
1784 stats->numImplThreadScrolls = num_impl_thread_scrolls_;
1785 stats->numMainThreadScrolls = num_main_thread_scrolls_;
1786 stats->numLayersDrawn = cumulative_num_layers_drawn_;
1787 stats->numMissingTiles = cumulative_num_missing_tiles_;
1788
1789 if (tile_manager_)
1790 tile_manager_->GetRenderingStats(stats);
1791}
1792
1793void LayerTreeHostImpl::SendManagedMemoryStats(
1794 size_t memory_visible_bytes,
1795 size_t memory_visible_and_nearby_bytes,
1796 size_t memory_use_bytes) {
1797 if (!renderer_)
1798 return;
1799
1800 // Round the numbers being sent up to the next 8MB, to throttle the rate
1801 // at which we spam the GPU process.
1802 static const size_t rounding_step = 8 * 1024 * 1024;
1803 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1804 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1805 rounding_step);
1806 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1807 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1808 last_sent_memory_visible_and_nearby_bytes_ ==
1809 memory_visible_and_nearby_bytes &&
1810 last_sent_memory_use_bytes_ == memory_use_bytes) {
1811 return;
1812 }
1813 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1814 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1815 last_sent_memory_use_bytes_ = memory_use_bytes;
1816
1817 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
1818 last_sent_memory_visible_and_nearby_bytes_,
1819 last_sent_memory_use_bytes_);
1820}
1821
1822void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
1823 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
1824}
1825
1826void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
1827 base::TimeTicks time) {
1828 if (!layer)
1829 return;
1830
1831 ScrollbarAnimationController* scrollbar_controller =
1832 layer->scrollbar_animation_controller();
1833 if (scrollbar_controller && scrollbar_controller->animate(time))
1834 client_->SetNeedsRedrawOnImplThread();
1835
1836 for (size_t i = 0; i < layer->children().size(); ++i)
1837 AnimateScrollbarsRecursive(layer->children()[i], time);
1838}
1839
1840void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
1841 if (!tile_manager_)
1842 return;
1843
1844 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
1845 if (new_state.tree_priority == priority)
1846 return;
1847
1848 new_state.tree_priority = priority;
1849 tile_manager_->SetGlobalState(new_state);
1850}
1851
1852void LayerTreeHostImpl::BeginNextFrame() {
1853 current_frame_time_ = base::TimeTicks();
1854}
1855
1856base::TimeTicks LayerTreeHostImpl::CurrentFrameTime() {
1857 if (current_frame_time_.is_null())
1858 current_frame_time_ = base::TimeTicks::Now();
1859 return current_frame_time_;
1860}
1861
1862scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
1863 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1864 state->Set("activation_state", ActivationStateAsValue().release());
1865 state->Set("frame_state", FrameStateAsValue().release());
1866 return state.PassAs<base::Value>();
1867}
1868
1869scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
1870 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1871 state->SetString("lthi_id", StringPrintf("%p", this));
1872 state->SetBoolean("visible_resources_ready",
1873 pending_tree_->AreVisibleResourcesReady());
1874 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
1875 return state.PassAs<base::Value>();
1876}
1877
1878scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
1879 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1880 state->SetString("lthi_id", StringPrintf("%p", this));
1881 state->Set("device_viewport_size",
1882 MathUtil::asValue(device_viewport_size_).release());
1883 if (tile_manager_)
1884 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
1885 state->Set("active_tree", active_tree_->AsValue().release());
1886 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:081887}
1888
[email protected]b9dcf43a2013-01-09 00:15:291889// static
[email protected]c1bb5af2013-03-13 19:06:271890LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
1891 LayerImpl* layer) {
1892 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:291893 return NULL;
[email protected]c1bb5af2013-03-13 19:06:271894
1895 if (layer->DrawsContent())
1896 return layer;
1897
1898 for (LayerImpl::LayerList::const_iterator it = layer->children().begin();
1899 it != layer->children().end(); ++it) {
1900 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
1901 if (nccr)
1902 return nccr;
1903 }
1904
1905 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:291906}
1907
[email protected]c1bb5af2013-03-13 19:06:271908skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
1909 LayerTreeImpl* tree =
1910 pending_tree_ ? pending_tree_.get() : active_tree_.get();
1911 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
1912 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:291913}
1914
[email protected]c1bb5af2013-03-13 19:06:271915void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
1916 if (debug_state_.continuousPainting != debug_state.continuousPainting)
1917 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:241918
[email protected]c1bb5af2013-03-13 19:06:271919 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:021920
[email protected]c1bb5af2013-03-13 19:06:271921 if (tile_manager_)
1922 tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats());
[email protected]d0d12192013-02-08 19:02:021923}
1924
[email protected]c1bb5af2013-03-13 19:06:271925void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time,
1926 int commit_number) {
1927 DCHECK(debug_state_.continuousPainting);
1928 paint_time_counter_->SavePaintTime(total_paint_time, commit_number);
[email protected]0edbfbe9f2013-01-17 03:33:031929}
1930
[email protected]d3143c732012-10-05 19:17:591931} // namespace cc