blob: b5d82f374f38fabad391fa418a4ddb1e9baeaafe [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),
[email protected]9e3594522013-03-18 00:57:36165 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29166 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27167 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);
[email protected]ffb2720f2013-03-15 19:18:37265 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14266}
267
[email protected]c1bb5af2013-03-13 19:06:27268void LayerTreeHostImpl::ManageTiles() {
269 DCHECK(tile_manager_);
270 tile_manager_->ManageTiles();
271
272 size_t memory_required_bytes;
273 size_t memory_nice_to_have_bytes;
274 size_t memory_used_bytes;
275 tile_manager_->GetMemoryStats(&memory_required_bytes,
276 &memory_nice_to_have_bytes,
277 &memory_used_bytes);
278 SendManagedMemoryStats(memory_required_bytes,
279 memory_nice_to_have_bytes,
280 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15281}
282
[email protected]c1bb5af2013-03-13 19:06:27283void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
284 bool anchor_point,
285 float page_scale,
286 base::TimeTicks start_time,
287 base::TimeDelta duration) {
288 if (!RootScrollLayer())
289 return;
290
291 gfx::Vector2dF scroll_total =
292 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
293 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
294 gfx::SizeF viewport_size =
295 gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor_);
296
297 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
298 page_scale_animation_ =
299 PageScaleAnimation::Create(scroll_total,
300 active_tree_->total_page_scale_factor(),
301 viewport_size,
302 scaled_scrollable_size,
303 start_time_seconds);
304
305 if (anchor_point) {
306 gfx::Vector2dF anchor(target_offset);
307 page_scale_animation_->ZoomWithAnchor(anchor,
308 page_scale,
309 duration.InSecondsF());
310 } else {
311 gfx::Vector2dF scaled_target_offset = target_offset;
312 page_scale_animation_->ZoomTo(scaled_target_offset,
313 page_scale,
314 duration.InSecondsF());
315 }
316
317 client_->SetNeedsRedrawOnImplThread();
318 client_->SetNeedsCommitOnImplThread();
319 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15320}
321
[email protected]c1bb5af2013-03-13 19:06:27322void LayerTreeHostImpl::ScheduleAnimation() {
323 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15324}
325
[email protected]c1bb5af2013-03-13 19:06:27326bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
327 if (!EnsureRenderSurfaceLayerList())
328 return false;
[email protected]f57bbc02012-11-21 07:02:15329
[email protected]c1bb5af2013-03-13 19:06:27330 gfx::PointF device_viewport_point =
331 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15332
[email protected]c1bb5af2013-03-13 19:06:27333 // First find out which layer was hit from the saved list of visible layers
334 // in the most recent frame.
335 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
336 device_viewport_point,
337 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15338
[email protected]c1bb5af2013-03-13 19:06:27339 // Walk up the hierarchy and look for a layer with a touch event handler
340 // region that the given point hits.
341 for (; layer_impl; layer_impl = layer_impl->parent()) {
342 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(device_viewport_point,
343 layer_impl))
344 return true;
345 }
[email protected]f57bbc02012-11-21 07:02:15346
[email protected]c1bb5af2013-03-13 19:06:27347 return false;
348}
349
350void LayerTreeHostImpl::TrackDamageForAllSurfaces(
351 LayerImpl* root_draw_layer,
352 const LayerList& render_surface_layer_list) {
353 // For now, we use damage tracking to compute a global scissor. To do this, we
354 // must compute all damage tracking before drawing anything, so that we know
355 // the root damage rect. The root damage rect is then used to scissor each
356 // surface.
357
358 for (int surface_index = render_surface_layer_list.size() - 1;
359 surface_index >= 0 ;
360 --surface_index) {
361 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
362 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
363 DCHECK(render_surface);
364 render_surface->damage_tracker()->UpdateDamageTrackingState(
365 render_surface->layer_list(),
366 render_surface_layer->id(),
367 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
368 render_surface->content_rect(),
369 render_surface_layer->mask_layer(),
370 render_surface_layer->filters(),
371 render_surface_layer->filter().get());
372 }
373}
374
375void LayerTreeHostImpl::FrameData::AppendRenderPass(
376 scoped_ptr<RenderPass> render_pass) {
377 render_passes_by_id[render_pass->id] = render_pass.get();
378 render_passes.push_back(render_pass.Pass());
379}
380
381static void AppendQuadsForLayer(RenderPass* target_render_pass,
382 LayerImpl* layer,
383 const OcclusionTrackerImpl& occlusion_tracker,
384 AppendQuadsData* append_quads_data) {
385 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49386 QuadCuller quad_culler(&target_render_pass->quad_list,
387 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27388 layer,
389 occlusion_tracker,
390 layer->ShowDebugBorders(),
391 for_surface);
392 layer->AppendQuads(&quad_culler, append_quads_data);
393}
394
395static void AppendQuadsForRenderSurfaceLayer(
396 RenderPass* target_render_pass,
397 LayerImpl* layer,
398 const RenderPass* contributing_render_pass,
399 const OcclusionTrackerImpl& occlusion_tracker,
400 AppendQuadsData* append_quads_data) {
401 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49402 QuadCuller quad_culler(&target_render_pass->quad_list,
403 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27404 layer,
405 occlusion_tracker,
406 layer->ShowDebugBorders(),
407 for_surface);
408
409 bool is_replica = false;
410 layer->render_surface()->AppendQuads(&quad_culler,
411 append_quads_data,
412 is_replica,
413 contributing_render_pass->id);
414
415 // Add replica after the surface so that it appears below the surface.
416 if (layer->has_replica()) {
417 is_replica = true;
418 layer->render_surface()->AppendQuads(&quad_culler,
419 append_quads_data,
420 is_replica,
421 contributing_render_pass->id);
422 }
423}
424
425static void AppendQuadsToFillScreen(
426 RenderPass* target_render_pass,
427 LayerImpl* root_layer,
428 SkColor screen_background_color,
429 const OcclusionTrackerImpl& occlusion_tracker) {
430 if (!root_layer || !SkColorGetA(screen_background_color))
431 return;
432
433 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
434 if (fill_region.IsEmpty())
435 return;
436
437 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49438 QuadCuller quad_culler(&target_render_pass->quad_list,
439 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27440 root_layer,
441 occlusion_tracker,
442 root_layer->ShowDebugBorders(),
443 for_surface);
444
445 // Manually create the quad state for the gutter quads, as the root layer
446 // doesn't have any bounds and so can't generate this itself.
447 // TODO(danakj): Make the gutter quads generated by the solid color layer
448 // (make it smarter about generating quads to fill unoccluded areas).
449
450 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
451 float opacity = 1.f;
452 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49453 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27454 shared_quad_state->SetAll(root_layer->draw_transform(),
455 root_target_rect.size(),
456 root_target_rect,
457 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01458 false,
[email protected]f57bbc02012-11-21 07:02:15459 opacity);
460
[email protected]c1bb5af2013-03-13 19:06:27461 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17462
[email protected]c1bb5af2013-03-13 19:06:27463 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
464 bool did_invert = root_layer->screen_space_transform().GetInverse(
465 &transform_to_layer_space);
466 DCHECK(did_invert);
467 for (Region::Iterator fill_rects(fill_region);
468 fill_rects.has_rect();
469 fill_rects.next()) {
470 // The root layer transform is composed of translations and scales only,
471 // no perspective, so mapping is sufficient (as opposed to projecting).
472 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21473 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27474 // Skip the quad culler and just append the quads directly to avoid
475 // occlusion checks.
476 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
477 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
[email protected]c7e95b42013-03-18 01:13:49478 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27479 }
[email protected]467b3612012-08-28 07:41:16480}
481
[email protected]c1bb5af2013-03-13 19:06:27482bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
483 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14484
[email protected]c1bb5af2013-03-13 19:06:27485 if (!CanDraw() || !active_tree_->root_layer())
486 return false;
[email protected]2d692992012-12-19 01:19:32487
[email protected]c1bb5af2013-03-13 19:06:27488 TrackDamageForAllSurfaces(active_tree_->root_layer(),
489 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14490
[email protected]c1bb5af2013-03-13 19:06:27491 TRACE_EVENT1("cc",
492 "LayerTreeHostImpl::CalculateRenderPasses",
493 "render_surface_layer_list.size()",
494 static_cast<long long unsigned>(
495 frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14496
[email protected]c1bb5af2013-03-13 19:06:27497 // Create the render passes in dependency order.
498 for (int surface_index = frame->render_surface_layer_list->size() - 1;
499 surface_index >= 0 ;
500 --surface_index) {
501 LayerImpl* render_surface_layer =
502 (*frame->render_surface_layer_list)[surface_index];
503 render_surface_layer->render_surface()->AppendRenderPasses(frame);
504 }
[email protected]94f206c12012-08-25 00:09:14505
[email protected]c1bb5af2013-03-13 19:06:27506 bool record_metrics_for_frame =
507 settings_.showOverdrawInTracing &&
508 base::debug::TraceLog::GetInstance() &&
509 base::debug::TraceLog::GetInstance()->IsEnabled();
510 OcclusionTrackerImpl occlusion_tracker(
511 active_tree_->root_layer()->render_surface()->content_rect(),
512 record_metrics_for_frame);
513 occlusion_tracker.set_minimum_tracking_size(
514 settings_.minimumOcclusionTrackingSize);
[email protected]94f206c12012-08-25 00:09:14515
[email protected]c1bb5af2013-03-13 19:06:27516 if (debug_state_.showOccludingRects) {
517 occlusion_tracker.set_occluding_screen_space_rects_container(
518 &frame->occluding_screen_space_rects);
519 }
520 if (debug_state_.showNonOccludingRects) {
521 occlusion_tracker.set_non_occluding_screen_space_rects_container(
522 &frame->non_occluding_screen_space_rects);
523 }
[email protected]94f206c12012-08-25 00:09:14524
[email protected]c1bb5af2013-03-13 19:06:27525 // Add quads to the Render passes in FrontToBack order to allow for testing
526 // occlusion and performing culling during the tree walk.
527 typedef LayerIterator<LayerImpl,
528 std::vector<LayerImpl*>,
529 RenderSurfaceImpl,
530 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14531
[email protected]c1bb5af2013-03-13 19:06:27532 // Typically when we are missing a texture and use a checkerboard quad, we
533 // still draw the frame. However when the layer being checkerboarded is moving
534 // due to an impl-animation, we drop the frame to avoid flashing due to the
535 // texture suddenly appearing in the future.
536 bool draw_frame = true;
[email protected]94f206c12012-08-25 00:09:14537
[email protected]c1bb5af2013-03-13 19:06:27538 LayerIteratorType end =
539 LayerIteratorType::end(frame->render_surface_layer_list);
540 for (LayerIteratorType it =
541 LayerIteratorType::begin(frame->render_surface_layer_list);
542 it != end;
543 ++it) {
544 RenderPass::Id target_render_pass_id =
545 it.targetRenderSurfaceLayer()->render_surface()->RenderPassId();
546 RenderPass* target_render_pass =
547 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14548
[email protected]c1bb5af2013-03-13 19:06:27549 occlusion_tracker.EnterLayer(it);
[email protected]94f206c12012-08-25 00:09:14550
[email protected]c1bb5af2013-03-13 19:06:27551 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30552
[email protected]c1bb5af2013-03-13 19:06:27553 if (it.representsContributingRenderSurface()) {
554 RenderPass::Id contributing_render_pass_id =
555 it->render_surface()->RenderPassId();
556 RenderPass* contributing_render_pass =
557 frame->render_passes_by_id[contributing_render_pass_id];
558 AppendQuadsForRenderSurfaceLayer(target_render_pass,
559 *it,
560 contributing_render_pass,
561 occlusion_tracker,
562 &append_quads_data);
563 } else if (it.representsItself() && !it->visible_content_rect().IsEmpty()) {
564 bool has_occlusion_from_outside_target_surface;
565 bool impl_draw_transform_is_unknown = false;
566 if (occlusion_tracker.Occluded(
567 it->render_target(),
568 it->visible_content_rect(),
569 it->draw_transform(),
570 impl_draw_transform_is_unknown,
571 it->is_clipped(),
572 it->clip_rect(),
573 &has_occlusion_from_outside_target_surface)) {
574 append_quads_data.hadOcclusionFromOutsideTargetSurface |=
575 has_occlusion_from_outside_target_surface;
576 } else {
577 DCHECK_EQ(active_tree_, it->layer_tree_impl());
578 it->WillDraw(resource_provider_.get());
579 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57580
[email protected]c1bb5af2013-03-13 19:06:27581 if (it->HasContributingDelegatedRenderPasses()) {
582 RenderPass::Id contributing_render_pass_id =
583 it->FirstContributingRenderPassId();
584 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
585 frame->render_passes_by_id.end()) {
586 RenderPass* render_pass =
587 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14588
[email protected]c1bb5af2013-03-13 19:06:27589 AppendQuadsData append_quads_data(render_pass->id);
590 AppendQuadsForLayer(render_pass,
591 *it,
592 occlusion_tracker,
593 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57594
[email protected]c1bb5af2013-03-13 19:06:27595 contributing_render_pass_id =
596 it->NextContributingRenderPassId(contributing_render_pass_id);
597 }
[email protected]94f206c12012-08-25 00:09:14598 }
599
[email protected]c1bb5af2013-03-13 19:06:27600 AppendQuadsForLayer(target_render_pass,
601 *it,
602 occlusion_tracker,
603 &append_quads_data);
604 }
[email protected]89228202012-08-29 03:20:30605
[email protected]c1bb5af2013-03-13 19:06:27606 ++cumulative_num_layers_drawn_;
[email protected]94f206c12012-08-25 00:09:14607 }
608
[email protected]c1bb5af2013-03-13 19:06:27609 if (append_quads_data.hadOcclusionFromOutsideTargetSurface)
610 target_render_pass->has_occlusion_from_outside_target_surface = true;
611
612 if (append_quads_data.numMissingTiles) {
613 cumulative_num_missing_tiles_ += append_quads_data.numMissingTiles;
614 bool layer_has_animating_transform =
615 it->screen_space_transform_is_animating() ||
616 it->draw_transform_is_animating();
617 if (layer_has_animating_transform)
618 draw_frame = false;
619 }
620
621 if (append_quads_data.hadIncompleteTile)
622 frame->contains_incomplete_tile = true;
623
624 occlusion_tracker.LeaveLayer(it);
625 }
626
[email protected]1d993172012-10-18 18:15:04627#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27628 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
629 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
630 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
631 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
632 != frame->render_passes_by_id.end());
633 }
[email protected]94f206c12012-08-25 00:09:14634#endif
[email protected]c1bb5af2013-03-13 19:06:27635 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14636
[email protected]c1bb5af2013-03-13 19:06:27637 if (!active_tree_->has_transparent_background()) {
638 frame->render_passes.back()->has_transparent_background = false;
639 AppendQuadsToFillScreen(frame->render_passes.back(),
640 active_tree_->root_layer(),
641 active_tree_->background_color(),
642 occlusion_tracker);
643 }
[email protected]94f206c12012-08-25 00:09:14644
[email protected]c1bb5af2013-03-13 19:06:27645 if (draw_frame)
646 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]94f206c12012-08-25 00:09:14647
[email protected]c1bb5af2013-03-13 19:06:27648 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
649 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
650 RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame);
[email protected]94f206c12012-08-25 00:09:14651
[email protected]c1bb5af2013-03-13 19:06:27652 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14653}
654
[email protected]c1bb5af2013-03-13 19:06:27655void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) {
656 // Lazily create the time_source adapter so that we can vary the interval for
657 // testing.
658 if (!time_source_client_adapter_) {
659 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
660 this,
661 DelayBasedTimeSource::create(LowFrequencyAnimationInterval(),
662 proxy_->CurrentThread()));
663 }
[email protected]94f206c12012-08-25 00:09:14664
[email protected]c1bb5af2013-03-13 19:06:27665 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14666}
667
[email protected]c1bb5af2013-03-13 19:06:27668static inline RenderPass* FindRenderPassById(
669 RenderPass::Id render_pass_id,
670 const LayerTreeHostImpl::FrameData& frame) {
671 RenderPassIdHashMap::const_iterator it =
672 frame.render_passes_by_id.find(render_pass_id);
673 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14674}
675
[email protected]c1bb5af2013-03-13 19:06:27676static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
677 LayerTreeHostImpl::FrameData* frame) {
678 RenderPass* remove_render_pass =
679 FindRenderPassById(remove_render_pass_id, *frame);
680 // The pass was already removed by another quad - probably the original, and
681 // we are the replica.
682 if (!remove_render_pass)
683 return;
684 RenderPassList& render_passes = frame->render_passes;
685 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
686 render_passes.end(),
687 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14688
[email protected]c1bb5af2013-03-13 19:06:27689 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14690
[email protected]c1bb5af2013-03-13 19:06:27691 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
692 frame->render_passes.erase(to_remove);
693 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14694
[email protected]c1bb5af2013-03-13 19:06:27695 // Now follow up for all RenderPass quads and remove their RenderPasses
696 // recursively.
697 const QuadList& quad_list = removed_pass->quad_list;
698 QuadList::constBackToFrontIterator quad_list_iterator =
699 quad_list.backToFrontBegin();
700 for (; quad_list_iterator != quad_list.backToFrontEnd();
701 ++quad_list_iterator) {
702 DrawQuad* current_quad = (*quad_list_iterator);
703 if (current_quad->material != DrawQuad::RENDER_PASS)
704 continue;
[email protected]94f206c12012-08-25 00:09:14705
[email protected]c1bb5af2013-03-13 19:06:27706 RenderPass::Id next_remove_render_pass_id =
707 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
708 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
709 }
[email protected]94f206c12012-08-25 00:09:14710}
711
[email protected]c1bb5af2013-03-13 19:06:27712bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
713 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
714 const FrameData& frame) const {
715 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
716 bool quad_has_cached_resource =
717 renderer_.HaveCachedResourcesForRenderPassId(quad.render_pass_id);
718 if (quad_has_damage) {
719 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
720 return false;
721 } else if (!quad_has_cached_resource) {
722 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
723 return false;
724 }
725 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
726 return true;
[email protected]94f206c12012-08-25 00:09:14727}
728
[email protected]c1bb5af2013-03-13 19:06:27729bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
730 const RenderPassDrawQuad& quad, const FrameData& frame) const {
731 const RenderPass* render_pass =
732 FindRenderPassById(quad.render_pass_id, frame);
733 if (!render_pass)
734 return false;
[email protected]94f206c12012-08-25 00:09:14735
[email protected]c1bb5af2013-03-13 19:06:27736 // If any quad or RenderPass draws into this RenderPass, then keep it.
737 const QuadList& quad_list = render_pass->quad_list;
738 for (QuadList::constBackToFrontIterator quad_list_iterator =
739 quad_list.backToFrontBegin();
740 quad_list_iterator != quad_list.backToFrontEnd();
741 ++quad_list_iterator) {
742 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14743
[email protected]c1bb5af2013-03-13 19:06:27744 if (current_quad->material != DrawQuad::RENDER_PASS)
745 return false;
[email protected]94f206c12012-08-25 00:09:14746
[email protected]c1bb5af2013-03-13 19:06:27747 const RenderPass* contributing_pass = FindRenderPassById(
748 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
749 if (contributing_pass)
750 return false;
751 }
752 return true;
[email protected]94f206c12012-08-25 00:09:14753}
754
755// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27756template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
757 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
758 CullRenderPassesWithCachedTextures culler, FrameData* frame);
759template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
760 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
761 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14762
763// static
[email protected]c1bb5af2013-03-13 19:06:27764template <typename RenderPassCuller>
765void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
766 FrameData* frame) {
767 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
768 it != culler.RenderPassListEnd(frame->render_passes);
769 it = culler.RenderPassListNext(it)) {
770 const RenderPass* current_pass = frame->render_passes[it];
771 const QuadList& quad_list = current_pass->quad_list;
772 QuadList::constBackToFrontIterator quad_list_iterator =
773 quad_list.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14774
[email protected]c1bb5af2013-03-13 19:06:27775 for (; quad_list_iterator != quad_list.backToFrontEnd();
776 ++quad_list_iterator) {
777 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14778
[email protected]c1bb5af2013-03-13 19:06:27779 if (current_quad->material != DrawQuad::RENDER_PASS)
780 continue;
[email protected]94f206c12012-08-25 00:09:14781
[email protected]c1bb5af2013-03-13 19:06:27782 const RenderPassDrawQuad* render_pass_quad =
783 RenderPassDrawQuad::MaterialCast(current_quad);
784 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
785 continue;
[email protected]94f206c12012-08-25 00:09:14786
[email protected]c1bb5af2013-03-13 19:06:27787 // We are changing the vector in the middle of iteration. Because we
788 // delete render passes that draw into the current pass, we are
789 // guaranteed that any data from the iterator to the end will not
790 // change. So, capture the iterator position from the end of the
791 // list, and restore it after the change.
792 size_t position_from_end = frame->render_passes.size() - it;
793 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
794 it = frame->render_passes.size() - position_from_end;
795 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14796 }
[email protected]c1bb5af2013-03-13 19:06:27797 }
[email protected]94f206c12012-08-25 00:09:14798}
799
[email protected]c1bb5af2013-03-13 19:06:27800bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
801 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14802
[email protected]c1bb5af2013-03-13 19:06:27803 active_tree_->UpdateDrawProperties(
804 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27805
[email protected]c1bb5af2013-03-13 19:06:27806 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
807 frame->render_passes.clear();
808 frame->render_passes_by_id.clear();
809 frame->will_draw_layers.clear();
[email protected]94f206c12012-08-25 00:09:14810
[email protected]c1bb5af2013-03-13 19:06:27811 if (!CalculateRenderPasses(frame))
812 return false;
[email protected]94f206c12012-08-25 00:09:14813
[email protected]c1bb5af2013-03-13 19:06:27814 // If we return true, then we expect DrawLayers() to be called before this
815 // function is called again.
816 return true;
[email protected]94f206c12012-08-25 00:09:14817}
818
[email protected]c1bb5af2013-03-13 19:06:27819void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
820 const ManagedMemoryPolicy& policy) {
821 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
822 visible_ ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible,
823 ManagedMemoryPolicy::priorityCutoffToValue(
824 visible_ ?
825 policy.priorityCutoffWhenVisible :
826 policy.priorityCutoffWhenNotVisible));
827 if (evicted_resources) {
828 active_tree_->SetContentsTexturesPurged();
829 if (pending_tree_)
830 pending_tree_->SetContentsTexturesPurged();
831 client_->SetNeedsCommitOnImplThread();
832 client_->OnCanDrawStateChanged(CanDraw());
833 client_->RenewTreePriority();
834 }
835 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43836
[email protected]c1bb5af2013-03-13 19:06:27837 if (tile_manager_) {
838 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
839 new_state.memory_limit_in_bytes = visible_ ?
840 policy.bytesLimitWhenVisible :
841 policy.bytesLimitWhenNotVisible;
842 new_state.memory_limit_policy =
843 ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy(
844 visible_ ?
845 policy.priorityCutoffWhenVisible :
846 policy.priorityCutoffWhenNotVisible);
847 tile_manager_->SetGlobalState(new_state);
848 }
[email protected]94f206c12012-08-25 00:09:14849}
850
[email protected]c1bb5af2013-03-13 19:06:27851bool LayerTreeHostImpl::HasImplThread() const {
852 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44853}
854
[email protected]c1bb5af2013-03-13 19:06:27855void LayerTreeHostImpl::ScheduleManageTiles() {
856 if (client_)
857 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43858}
859
[email protected]86126792013-03-16 20:07:54860void LayerTreeHostImpl::DidInitializeVisibleTile() {
861 // TODO(reveman): Determine tiles that changed and only damage
862 // what's necessary.
863 SetFullRootLayerDamage();
[email protected]c1bb5af2013-03-13 19:06:27864 if (client_)
[email protected]86126792013-03-16 20:07:54865 client_->DidInitializeVisibleTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47866}
867
[email protected]c1bb5af2013-03-13 19:06:27868bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
869 return settings_.shouldClearRootRenderPass;
[email protected]f35e2322012-12-15 21:45:52870}
871
[email protected]c1bb5af2013-03-13 19:06:27872void LayerTreeHostImpl::SetManagedMemoryPolicy(
873 const ManagedMemoryPolicy& policy) {
874 if (managed_memory_policy_ == policy)
875 return;
[email protected]61de5812012-11-08 07:03:44876
[email protected]c1bb5af2013-03-13 19:06:27877 managed_memory_policy_ = policy;
878 if (!proxy_->HasImplThread()) {
879 // TODO(ccameron): In single-thread mode, this can be called on the main
880 // thread by GLRenderer::OnMemoryAllocationChanged.
881 DebugScopedSetImplThread impl_thread(proxy_);
882 EnforceManagedMemoryPolicy(managed_memory_policy_);
883 } else {
884 DCHECK(proxy_->IsImplThread());
885 EnforceManagedMemoryPolicy(managed_memory_policy_);
886 }
887 // We always need to commit after changing the memory policy because the new
888 // limit can result in more or less content having texture allocated for it.
889 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:14890}
891
[email protected]c1bb5af2013-03-13 19:06:27892void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
893 base::TimeDelta interval) {
894 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14895}
896
[email protected]c1bb5af2013-03-13 19:06:27897void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
898 const CompositorFrameAck& ack) {
899 if (!renderer_)
900 return;
[email protected]b6f3d7e2012-12-08 00:11:21901
[email protected]c1bb5af2013-03-13 19:06:27902 // TODO(piman): We may need to do some validation on this ack before
903 // processing it.
904 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16905}
906
[email protected]c1bb5af2013-03-13 19:06:27907void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
908 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:29909}
910
[email protected]c1bb5af2013-03-13 19:06:27911CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
912 CompositorFrameMetadata metadata;
913 metadata.device_scale_factor = device_scale_factor_;
914 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
915 metadata.viewport_size = active_tree_->ScrollableViewportSize();
916 metadata.root_layer_size = active_tree_->ScrollableSize();
917 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
918 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
919 if (top_controls_manager_) {
920 metadata.location_bar_offset =
921 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
922 metadata.location_bar_content_translation =
923 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
924 }
[email protected]bf189f62012-12-18 03:42:11925
[email protected]c1bb5af2013-03-13 19:06:27926 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:11927 return metadata;
[email protected]c1bb5af2013-03-13 19:06:27928
[email protected]ffb2720f2013-03-15 19:18:37929 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
[email protected]c1bb5af2013-03-13 19:06:27930
931 return metadata;
[email protected]bf189f62012-12-18 03:42:11932}
933
[email protected]f0c2a242013-03-15 19:34:52934void LayerTreeHostImpl::DrawLayers(FrameData* frame,
935 base::TimeTicks frame_begin_time) {
[email protected]c1bb5af2013-03-13 19:06:27936 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
937 DCHECK(CanDraw());
938 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14939
[email protected]9e3594522013-03-18 00:57:36940 fps_counter_->SaveTimeStamp(frame_begin_time);
[email protected]94f206c12012-08-25 00:09:14941
[email protected]c1bb5af2013-03-13 19:06:27942 if (tile_manager_) {
943 memory_history_->SaveEntry(
944 tile_manager_->memory_stats_from_last_assign());
945 }
[email protected]1191d9d2013-02-02 06:00:33946
[email protected]c1bb5af2013-03-13 19:06:27947 if (debug_state_.showHudRects()) {
[email protected]d35992782013-03-14 14:54:02948 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:27949 active_tree_->root_layer(),
950 *frame->render_surface_layer_list,
951 frame->occluding_screen_space_rects,
952 frame->non_occluding_screen_space_rects,
953 debug_state_);
954 }
[email protected]94f206c12012-08-25 00:09:14955
[email protected]c1bb5af2013-03-13 19:06:27956 if (debug_state_.traceAllRenderedFrames) {
957 TRACE_EVENT_INSTANT1("cc.debug", "Frame",
958 "frame", ValueToString(FrameStateAsValue()));
959 }
[email protected]131a0c22013-02-12 18:31:08960
[email protected]c1bb5af2013-03-13 19:06:27961 // Because the contents of the HUD depend on everything else in the frame, the
962 // contents of its texture are updated as the last thing before the frame is
963 // drawn.
964 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:54965 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:14966
[email protected]c1bb5af2013-03-13 19:06:27967 renderer_->DrawFrame(frame->render_passes);
968 // The render passes should be consumed by the renderer.
969 DCHECK(frame->render_passes.empty());
970 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:14971
[email protected]c1bb5af2013-03-13 19:06:27972 // The next frame should start by assuming nothing has changed, and changes
973 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:54974 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:27975 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
976 DidDrawDamagedArea();
977 }
978 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
979 UpdateAnimationState();
[email protected]94f206c12012-08-25 00:09:14980}
981
[email protected]c1bb5af2013-03-13 19:06:27982void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
983 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
984 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:52985
[email protected]c1bb5af2013-03-13 19:06:27986 // Once all layers have been drawn, pending texture uploads should no
987 // longer block future uploads.
988 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:14989}
990
[email protected]c1bb5af2013-03-13 19:06:27991void LayerTreeHostImpl::FinishAllRendering() {
992 if (renderer_)
993 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:14994}
995
[email protected]c1bb5af2013-03-13 19:06:27996bool LayerTreeHostImpl::IsContextLost() {
997 DCHECK(proxy_->IsImplThread());
998 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:14999}
1000
[email protected]c1bb5af2013-03-13 19:06:271001const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1002 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141003}
1004
[email protected]c1bb5af2013-03-13 19:06:271005bool LayerTreeHostImpl::SwapBuffers() {
1006 if (tile_manager_)
1007 tile_manager_->DidCompleteFrame();
1008 return renderer_->SwapBuffers();
[email protected]94f206c12012-08-25 00:09:141009}
1010
[email protected]c1bb5af2013-03-13 19:06:271011gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1012 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101013}
1014
[email protected]ffb2720f2013-03-15 19:18:371015gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1016 gfx::SizeF dip_size =
1017 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1018
1019 // The clip layer should be used if non-overlay scrollbars may exist since
1020 // it adjusts for them.
1021 LayerImpl* clip_layer = active_tree_->RootClipLayer();
1022 if (!Settings().solidColorScrollbars && clip_layer &&
1023 clip_layer->masks_to_bounds())
1024 dip_size = clip_layer->bounds();
1025
1026 float topOffset =
1027 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
1028 return gfx::SizeF(dip_size.width(), dip_size.height() - topOffset);
1029}
1030
[email protected]c1bb5af2013-03-13 19:06:271031const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1032 return settings();
[email protected]493067512012-09-19 23:34:101033}
1034
[email protected]c1bb5af2013-03-13 19:06:271035void LayerTreeHostImpl::DidLoseOutputSurface() {
1036 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141037}
1038
[email protected]c1bb5af2013-03-13 19:06:271039void LayerTreeHostImpl::OnSwapBuffersComplete() {
1040 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141041}
1042
[email protected]c1bb5af2013-03-13 19:06:271043void LayerTreeHostImpl::Readback(void* pixels,
1044 gfx::Rect rect_in_device_viewport) {
1045 DCHECK(renderer_);
1046 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141047}
1048
[email protected]69b50ec2013-01-19 04:58:011049bool LayerTreeHostImpl::haveRootScrollLayer() const {
[email protected]c1bb5af2013-03-13 19:06:271050 return RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011051}
1052
[email protected]c1bb5af2013-03-13 19:06:271053LayerImpl* LayerTreeHostImpl::RootLayer() const {
1054 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081055}
1056
[email protected]c1bb5af2013-03-13 19:06:271057LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1058 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081059}
1060
[email protected]c1bb5af2013-03-13 19:06:271061LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1062 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081063}
1064
[email protected]94f206c12012-08-25 00:09:141065// Content layers can be either directly scrollable or contained in an outer
1066// scrolling layer which applies the scroll transform. Given a content layer,
1067// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271068static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1069 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141070 return 0;
[email protected]c1bb5af2013-03-13 19:06:271071
1072 if (layer_impl->scrollable())
1073 return layer_impl;
1074
1075 if (layer_impl->DrawsContent() &&
1076 layer_impl->parent() &&
1077 layer_impl->parent()->scrollable())
1078 return layer_impl->parent();
1079
1080 return 0;
[email protected]94f206c12012-08-25 00:09:141081}
1082
[email protected]c1bb5af2013-03-13 19:06:271083void LayerTreeHostImpl::CreatePendingTree() {
1084 CHECK(!pending_tree_);
1085 if (recycle_tree_)
1086 recycle_tree_.swap(pending_tree_);
1087 else
1088 pending_tree_ = LayerTreeImpl::create(this);
1089 client_->OnCanDrawStateChanged(CanDraw());
1090 client_->OnHasPendingTreeStateChanged(pending_tree_);
1091 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1092 TRACE_EVENT_ASYNC_STEP0("cc",
1093 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271094}
1095
[email protected]c1bb5af2013-03-13 19:06:271096void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1097 DCHECK(!client_->IsInsideDraw()) <<
1098 "Checking for completed uploads within a draw may trigger "
1099 "spurious redraws.";
1100 if (tile_manager_)
1101 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481102}
1103
[email protected]c1bb5af2013-03-13 19:06:271104bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1105 if (!pending_tree_)
1106 return false;
[email protected]2e7ca422012-12-20 02:57:271107
[email protected]c1bb5af2013-03-13 19:06:271108 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091109
[email protected]c1bb5af2013-03-13 19:06:271110 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161111
[email protected]c1bb5af2013-03-13 19:06:271112 TRACE_EVENT_ASYNC_STEP1("cc",
1113 "PendingTree", pending_tree_.get(), "activate",
1114 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271115
[email protected]c1bb5af2013-03-13 19:06:271116 // It's always fine to activate to an empty tree. Otherwise, only
1117 // activate once all visible resources in pending tree are ready
1118 // or tile manager has no work scheduled for pending tree.
1119 if (active_tree_->root_layer() &&
1120 !pending_tree_->AreVisibleResourcesReady()) {
1121 // In smoothness takes priority mode, the pending tree's priorities are
1122 // ignored, so the tile manager may not have work for it even though it
1123 // is simultaneously not ready to be activated.
1124 if (tile_manager_->GlobalState().tree_priority ==
1125 SMOOTHNESS_TAKES_PRIORITY ||
1126 tile_manager_->HasPendingWorkScheduled(PENDING_TREE)) {
1127 TRACE_EVENT_ASYNC_STEP0("cc",
1128 "PendingTree",
1129 pending_tree_.get(),
1130 "waiting");
1131 return false;
[email protected]131a0c22013-02-12 18:31:081132 }
[email protected]c1bb5af2013-03-13 19:06:271133 }
[email protected]2e7ca422012-12-20 02:57:271134
[email protected]c1bb5af2013-03-13 19:06:271135 ActivatePendingTree();
1136 return true;
[email protected]2e7ca422012-12-20 02:57:271137}
1138
[email protected]c1bb5af2013-03-13 19:06:271139void LayerTreeHostImpl::ActivatePendingTree() {
1140 CHECK(pending_tree_);
1141 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351142
[email protected]c1bb5af2013-03-13 19:06:271143 active_tree_->PushPersistedState(pending_tree_.get());
1144 if (pending_tree_->needs_full_tree_sync()) {
1145 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331146 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271147 active_tree_->DetachLayerTree(),
1148 active_tree_.get()));
1149 }
[email protected]b5651c22013-03-14 15:06:331150 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271151 active_tree_->root_layer());
1152 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511153
[email protected]c1bb5af2013-03-13 19:06:271154 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511155
[email protected]c1bb5af2013-03-13 19:06:271156 // Now that we've synced everything from the pending tree to the active
1157 // tree, rename the pending tree the recycle tree so we can reuse it on the
1158 // next sync.
1159 pending_tree_.swap(recycle_tree_);
1160 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511161
[email protected]c1bb5af2013-03-13 19:06:271162 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221163
[email protected]c1bb5af2013-03-13 19:06:271164 // Reduce wasted memory now that unlinked resources are guaranteed not
1165 // to be used.
1166 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411167
[email protected]c1bb5af2013-03-13 19:06:271168 client_->OnCanDrawStateChanged(CanDraw());
1169 client_->OnHasPendingTreeStateChanged(pending_tree_);
1170 client_->SetNeedsRedrawOnImplThread();
1171 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241172
[email protected]c1bb5af2013-03-13 19:06:271173 if (tile_manager_ && debug_state_.continuousPainting) {
1174 RenderingStats stats;
1175 tile_manager_->GetRenderingStats(&stats);
1176 paint_time_counter_->SaveRasterizeTime(
1177 stats.totalRasterizeTimeForNowBinsOnPendingTree,
1178 active_tree_->source_frame_number());
1179 }
[email protected]2e7ca422012-12-20 02:57:271180}
1181
[email protected]c1bb5af2013-03-13 19:06:271182void LayerTreeHostImpl::SetVisible(bool visible) {
1183 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141184
[email protected]c1bb5af2013-03-13 19:06:271185 if (visible_ == visible)
1186 return;
1187 visible_ = visible;
1188 DidVisibilityChange(this, visible_);
1189 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141190
[email protected]c1bb5af2013-03-13 19:06:271191 if (!renderer_)
1192 return;
[email protected]94f206c12012-08-25 00:09:141193
[email protected]c1bb5af2013-03-13 19:06:271194 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141195
[email protected]c1bb5af2013-03-13 19:06:271196 SetBackgroundTickingEnabled(
1197 !visible_ &&
1198 !animation_registrar_->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141199}
1200
[email protected]c1bb5af2013-03-13 19:06:271201bool LayerTreeHostImpl::InitializeRenderer(
1202 scoped_ptr<OutputSurface> output_surface) {
1203 // Since we will create a new resource provider, we cannot continue to use
1204 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1205 // before we destroy the old resource provider.
1206 if (active_tree_->root_layer())
1207 ClearRenderSurfaces();
1208 if (active_tree_->root_layer())
1209 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1210 if (pending_tree_ && pending_tree_->root_layer())
1211 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1212 if (recycle_tree_ && recycle_tree_->root_layer())
1213 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]45c4b1e2013-01-16 02:19:401214
[email protected]c1bb5af2013-03-13 19:06:271215 // Note: order is important here.
1216 renderer_.reset();
1217 tile_manager_.reset();
1218 resource_provider_.reset();
1219 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141220
[email protected]c1bb5af2013-03-13 19:06:271221 if (!output_surface->BindToClient(this))
1222 return false;
[email protected]be3181652012-09-25 13:02:131223
[email protected]c1bb5af2013-03-13 19:06:271224 scoped_ptr<ResourceProvider> resource_provider =
1225 ResourceProvider::Create(output_surface.get());
1226 if (!resource_provider)
1227 return false;
[email protected]be3181652012-09-25 13:02:131228
[email protected]c1bb5af2013-03-13 19:06:271229 if (settings_.implSidePainting) {
1230 tile_manager_.reset(new TileManager(this,
1231 resource_provider.get(),
1232 settings_.numRasterThreads,
1233 settings_.useCheapnessEstimator,
1234 settings_.useColorEstimator,
1235 settings_.predictionBenchmarking));
1236 tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats());
1237 }
[email protected]8947cbe2012-11-28 05:27:431238
[email protected]c1bb5af2013-03-13 19:06:271239 if (output_surface->capabilities().has_parent_compositor) {
1240 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1241 resource_provider.get());
1242 } else if (output_surface->context3d()) {
1243 renderer_ = GLRenderer::Create(this,
1244 output_surface.get(),
1245 resource_provider.get());
1246 } else if (output_surface->software_device()) {
1247 renderer_ = SoftwareRenderer::Create(this,
1248 output_surface.get(),
1249 resource_provider.get());
1250 }
1251 if (!renderer_)
1252 return false;
[email protected]be3181652012-09-25 13:02:131253
[email protected]c1bb5af2013-03-13 19:06:271254 resource_provider_ = resource_provider.Pass();
1255 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141256
[email protected]c1bb5af2013-03-13 19:06:271257 if (!visible_)
1258 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141259
[email protected]c1bb5af2013-03-13 19:06:271260 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211261
[email protected]c1bb5af2013-03-13 19:06:271262 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1263 // to be initialized to get max texture size.
1264 active_tree_->set_needs_update_draw_properties();
1265 if (pending_tree_)
1266 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161267
[email protected]c1bb5af2013-03-13 19:06:271268 return true;
[email protected]94f206c12012-08-25 00:09:141269}
1270
[email protected]c1bb5af2013-03-13 19:06:271271void LayerTreeHostImpl::SetViewportSize(gfx::Size layout_viewport_size,
1272 gfx::Size device_viewport_size) {
1273 if (layout_viewport_size == layout_viewport_size_ &&
1274 device_viewport_size == device_viewport_size_)
1275 return;
[email protected]94f206c12012-08-25 00:09:141276
[email protected]c1bb5af2013-03-13 19:06:271277 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1278 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271279
[email protected]c1bb5af2013-03-13 19:06:271280 layout_viewport_size_ = layout_viewport_size;
1281 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141282
[email protected]c1bb5af2013-03-13 19:06:271283 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141284
[email protected]c1bb5af2013-03-13 19:06:271285 if (renderer_)
1286 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211287
[email protected]c1bb5af2013-03-13 19:06:271288 client_->OnCanDrawStateChanged(CanDraw());
[email protected]94f206c12012-08-25 00:09:141289}
1290
[email protected]c1bb5af2013-03-13 19:06:271291static void AdjustScrollsForPageScaleChange(LayerImpl* layer_impl,
1292 float page_scale_change) {
1293 if (!layer_impl)
1294 return;
[email protected]94f206c12012-08-25 00:09:141295
[email protected]c1bb5af2013-03-13 19:06:271296 if (layer_impl->scrollable()) {
1297 // We need to convert impl-side scroll deltas to page_scale space.
1298 gfx::Vector2dF scroll_delta = layer_impl->scroll_delta();
1299 scroll_delta.Scale(page_scale_change);
1300 layer_impl->SetScrollDelta(scroll_delta);
1301 }
[email protected]94f206c12012-08-25 00:09:141302
[email protected]c1bb5af2013-03-13 19:06:271303 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1304 AdjustScrollsForPageScaleChange(layer_impl->children()[i],
1305 page_scale_change);
[email protected]94f206c12012-08-25 00:09:141306}
1307
[email protected]c1bb5af2013-03-13 19:06:271308void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1309 if (device_scale_factor == device_scale_factor_)
1310 return;
1311 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271312
[email protected]c1bb5af2013-03-13 19:06:271313 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141314}
1315
[email protected]c1bb5af2013-03-13 19:06:271316void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1317 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141318}
1319
[email protected]c1bb5af2013-03-13 19:06:271320void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() {
1321 active_tree_->set_needs_update_draw_properties();
[email protected]3ba4cae2013-01-16 03:58:381322}
1323
[email protected]c1bb5af2013-03-13 19:06:271324void LayerTreeHostImpl::setNeedsRedraw() {
1325 client_->SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:141326}
1327
[email protected]c1bb5af2013-03-13 19:06:271328bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1329 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
1330 return active_tree_->RenderSurfaceLayerList().size();
[email protected]94f206c12012-08-25 00:09:141331}
1332
[email protected]c1bb5af2013-03-13 19:06:271333InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1334 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
1335 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin");
[email protected]94f206c12012-08-25 00:09:141336
[email protected]c1bb5af2013-03-13 19:06:271337 if (top_controls_manager_)
1338 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381339
[email protected]c1bb5af2013-03-13 19:06:271340 DCHECK(!CurrentlyScrollingLayer());
1341 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141342
[email protected]c1bb5af2013-03-13 19:06:271343 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141344 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141345
[email protected]c1bb5af2013-03-13 19:06:271346 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1347 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141348
[email protected]c1bb5af2013-03-13 19:06:271349 // First find out which layer was hit from the saved list of visible layers
1350 // in the most recent frame.
1351 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
1352 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521353
[email protected]c1bb5af2013-03-13 19:06:271354 // Walk up the hierarchy and look for a scrollable layer.
1355 LayerImpl* potentially_scrolling_layer_impl = 0;
1356 for (; layer_impl; layer_impl = layer_impl->parent()) {
1357 // The content layer can also block attempts to scroll outside the main
1358 // thread.
1359 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1360 if (status == ScrollOnMainThread) {
1361 num_main_thread_scrolls_++;
1362 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421363 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271364 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141365 }
1366
[email protected]c1bb5af2013-03-13 19:06:271367 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1368 if (!scroll_layer_impl)
1369 continue;
[email protected]94f206c12012-08-25 00:09:141370
[email protected]c1bb5af2013-03-13 19:06:271371 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141372
[email protected]c1bb5af2013-03-13 19:06:271373 // If any layer wants to divert the scroll event to the main thread, abort.
1374 if (status == ScrollOnMainThread) {
1375 num_main_thread_scrolls_++;
1376 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421377 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271378 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141379 }
1380
[email protected]c1bb5af2013-03-13 19:06:271381 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1382 potentially_scrolling_layer_impl = scroll_layer_impl;
1383 }
1384
1385 // When hiding top controls is enabled and the controls are hidden or
1386 // overlaying the content, force scrolls to be enabled on the root layer to
1387 // allow bringing the top controls back into view.
1388 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1389 top_controls_manager_->content_top_offset() !=
1390 settings_.topControlsHeight) {
1391 potentially_scrolling_layer_impl = RootScrollLayer();
1392 }
1393
1394 if (potentially_scrolling_layer_impl) {
1395 active_tree_->set_currently_scrolling_layer(
1396 potentially_scrolling_layer_impl);
1397 should_bubble_scrolls_ = (type != NonBubblingGesture);
1398 wheel_scrolling_ = (type == Wheel);
1399 num_impl_thread_scrolls_++;
1400 client_->RenewTreePriority();
1401 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421402 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271403 return ScrollStarted;
1404 }
1405 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141406}
1407
[email protected]c1bb5af2013-03-13 19:06:271408gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1409 LayerImpl* layer_impl,
1410 float scale_from_viewport_to_screen_space,
1411 gfx::PointF viewport_point,
1412 gfx::Vector2dF viewport_delta) {
1413 // Layers with non-invertible screen space transforms should not have passed
1414 // the scroll hit test in the first place.
1415 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1416 gfx::Transform inverse_screen_space_transform(
1417 gfx::Transform::kSkipInitialization);
1418 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1419 &inverse_screen_space_transform);
1420 // TODO: With the advent of impl-side crolling for non-root layers, we may
1421 // need to explicitly handle uninvertible transforms here.
1422 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141423
[email protected]c1bb5af2013-03-13 19:06:271424 gfx::PointF screen_space_point =
1425 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141426
[email protected]c1bb5af2013-03-13 19:06:271427 gfx::Vector2dF screen_space_delta = viewport_delta;
1428 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1429
1430 // First project the scroll start and end points to local layer space to find
1431 // the scroll delta in layer coordinates.
1432 bool start_clipped, end_clipped;
1433 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1434 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211435 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271436 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211437 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271438 gfx::PointF local_end_point =
[email protected]fa816c62013-03-18 04:24:211439 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271440 screen_space_end_point,
[email protected]fa816c62013-03-18 04:24:211441 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271442
1443 // In general scroll point coordinates should not get clipped.
1444 DCHECK(!start_clipped);
1445 DCHECK(!end_clipped);
1446 if (start_clipped || end_clipped)
1447 return gfx::Vector2dF();
1448
1449 // local_start_point and local_end_point are in content space but we want to
1450 // move them to layer space for scrolling.
1451 float width_scale = 1.f / layer_impl->contents_scale_x();
1452 float height_scale = 1.f / layer_impl->contents_scale_y();
1453 local_start_point.Scale(width_scale, height_scale);
1454 local_end_point.Scale(width_scale, height_scale);
1455
1456 // Apply the scroll delta.
1457 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1458 layer_impl->ScrollBy(local_end_point - local_start_point);
1459
1460 // Get the end point in the layer's content space so we can apply its
1461 // ScreenSpaceTransform.
1462 gfx::PointF actual_local_end_point = local_start_point +
1463 layer_impl->scroll_delta() -
1464 previous_delta;
1465 gfx::PointF actual_local_content_end_point =
1466 gfx::ScalePoint(actual_local_end_point,
1467 1.f / width_scale,
1468 1.f / height_scale);
1469
1470 // Calculate the applied scroll delta in viewport space coordinates.
1471 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211472 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271473 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211474 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271475 DCHECK(!end_clipped);
1476 if (end_clipped)
1477 return gfx::Vector2dF();
1478 gfx::PointF actual_viewport_end_point =
1479 gfx::ScalePoint(actual_screen_space_end_point,
1480 1.f / scale_from_viewport_to_screen_space);
1481 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141482}
1483
[email protected]c1bb5af2013-03-13 19:06:271484static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1485 gfx::Vector2dF local_delta) {
1486 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1487 layer_impl->ScrollBy(local_delta);
1488 return layer_impl->scroll_delta() - previous_delta;
1489}
1490
1491bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1492 gfx::Vector2dF scroll_delta) {
1493 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1494 if (!CurrentlyScrollingLayer())
1495 return false;
1496
1497 gfx::Vector2dF pending_delta = scroll_delta;
1498 bool did_scroll = false;
1499
[email protected]ffb2720f2013-03-15 19:18:371500 if (top_controls_manager_ && CurrentlyScrollingLayer() == RootScrollLayer()) {
[email protected]a91e4f82013-03-15 06:58:061501 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
[email protected]ffb2720f2013-03-15 19:18:371502 UpdateMaxScrollOffset();
1503 }
[email protected]a91e4f82013-03-15 06:58:061504
[email protected]c1bb5af2013-03-13 19:06:271505 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1506 layer_impl;
1507 layer_impl = layer_impl->parent()) {
1508 if (!layer_impl->scrollable())
1509 continue;
1510
1511 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271512 // Gesture events need to be transformed from viewport coordinates to local
1513 // layer coordinates so that the scrolling contents exactly follow the
1514 // user's finger. In contrast, wheel events represent a fixed amount of
1515 // scrolling so we can just apply them directly.
1516 if (!wheel_scrolling_) {
1517 float scale_from_viewport_to_screen_space = device_scale_factor_;
1518 applied_delta =
1519 ScrollLayerWithViewportSpaceDelta(layer_impl,
1520 scale_from_viewport_to_screen_space,
1521 viewport_point, pending_delta);
1522 } else {
1523 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141524 }
[email protected]94f206c12012-08-25 00:09:141525
[email protected]c1bb5af2013-03-13 19:06:271526 // If the layer wasn't able to move, try the next one in the hierarchy.
1527 float move_threshold_squared = 0.1f * 0.1f;
1528 if (applied_delta.LengthSquared() < move_threshold_squared) {
1529 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1530 continue;
1531 else
1532 break;
[email protected]94f206c12012-08-25 00:09:141533 }
[email protected]c1bb5af2013-03-13 19:06:271534 did_scroll = true;
1535 did_lock_scrolling_layer_ = true;
1536 if (!should_bubble_scrolls_) {
1537 active_tree_->set_currently_scrolling_layer(layer_impl);
1538 break;
[email protected]94f206c12012-08-25 00:09:141539 }
[email protected]94f206c12012-08-25 00:09:141540
[email protected]c1bb5af2013-03-13 19:06:271541 // If the applied delta is within 45 degrees of the input delta, bail out to
1542 // make it easier to scroll just one layer in one direction without
1543 // affecting any of its parents.
1544 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211545 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271546 applied_delta, pending_delta) < angle_threshold) {
1547 pending_delta = gfx::Vector2d();
1548 break;
[email protected]4a23c374c2012-12-08 08:38:551549 }
[email protected]c1bb5af2013-03-13 19:06:271550
1551 // Allow further movement only on an axis perpendicular to the direction in
1552 // which the layer moved.
1553 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211554 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271555
1556 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1557 break;
1558 }
1559
[email protected]b7c4783f2013-03-15 23:11:421560 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271561 if (did_scroll) {
1562 client_->SetNeedsCommitOnImplThread();
1563 client_->SetNeedsRedrawOnImplThread();
1564 client_->RenewTreePriority();
1565 }
1566 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551567}
1568
[email protected]c1bb5af2013-03-13 19:06:271569void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1570 active_tree_->ClearCurrentlyScrollingLayer();
1571 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141572}
1573
[email protected]c1bb5af2013-03-13 19:06:271574void LayerTreeHostImpl::ScrollEnd() {
1575 if (top_controls_manager_)
1576 top_controls_manager_->ScrollEnd();
1577 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421578 active_tree()->DidEndScroll();
[email protected]94f206c12012-08-25 00:09:141579}
1580
[email protected]c1bb5af2013-03-13 19:06:271581void LayerTreeHostImpl::PinchGestureBegin() {
1582 pinch_gesture_active_ = true;
1583 previous_pinch_anchor_ = gfx::Point();
1584 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141585}
1586
[email protected]c1bb5af2013-03-13 19:06:271587void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1588 gfx::Point anchor) {
1589 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281590
[email protected]c1bb5af2013-03-13 19:06:271591 if (!RootScrollLayer())
1592 return;
[email protected]d3afa112012-12-08 06:24:281593
[email protected]c1bb5af2013-03-13 19:06:271594 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1595 // position over the course of the magnify.
1596 float page_scale_delta = active_tree_->page_scale_delta();
1597 gfx::PointF previous_scale_anchor =
1598 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1599 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1600 page_scale_delta = active_tree_->page_scale_delta();
1601 gfx::PointF new_scale_anchor =
1602 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1603 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1604
1605 previous_pinch_anchor_ = anchor;
1606
1607 move.Scale(1 / active_tree_->page_scale_factor());
1608
1609 RootScrollLayer()->ScrollBy(move);
1610
1611 if (RootScrollLayer()->scrollbar_animation_controller()) {
1612 RootScrollLayer()->scrollbar_animation_controller()->
1613 didPinchGestureUpdate(base::TimeTicks::Now());
1614 }
1615
1616 client_->SetNeedsCommitOnImplThread();
1617 client_->SetNeedsRedrawOnImplThread();
1618 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281619}
1620
[email protected]c1bb5af2013-03-13 19:06:271621void LayerTreeHostImpl::PinchGestureEnd() {
1622 pinch_gesture_active_ = false;
1623
1624 if (RootScrollLayer() &&
1625 RootScrollLayer()->scrollbar_animation_controller()) {
1626 RootScrollLayer()->scrollbar_animation_controller()->
1627 didPinchGestureEnd(base::TimeTicks::Now());
1628 }
1629
1630 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141631}
1632
[email protected]c1bb5af2013-03-13 19:06:271633static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1634 LayerImpl* layer_impl) {
1635 if (!layer_impl)
1636 return;
[email protected]94f206c12012-08-25 00:09:141637
[email protected]c1bb5af2013-03-13 19:06:271638 gfx::Vector2d scroll_delta =
1639 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1640 if (!scroll_delta.IsZero()) {
1641 LayerTreeHostCommon::ScrollUpdateInfo scroll;
1642 scroll.layerId = layer_impl->id();
1643 scroll.scrollDelta = scroll_delta;
1644 scroll_info->scrolls.push_back(scroll);
1645 layer_impl->SetSentScrollDelta(scroll_delta);
1646 }
[email protected]94f206c12012-08-25 00:09:141647
[email protected]c1bb5af2013-03-13 19:06:271648 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1649 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141650}
1651
[email protected]c1bb5af2013-03-13 19:06:271652scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1653 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301654
[email protected]c1bb5af2013-03-13 19:06:271655 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
1656 scroll_info->pageScaleDelta = active_tree_->page_scale_delta();
1657 active_tree_->set_sent_page_scale_delta(scroll_info->pageScaleDelta);
[email protected]362f1e8b2013-01-21 16:54:301658
[email protected]c1bb5af2013-03-13 19:06:271659 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301660}
1661
[email protected]c1bb5af2013-03-13 19:06:271662void LayerTreeHostImpl::SetFullRootLayerDamage() {
1663 if (active_tree_->root_layer()) {
1664 RenderSurfaceImpl* render_surface =
1665 active_tree_->root_layer()->render_surface();
1666 if (render_surface)
1667 render_surface->damage_tracker()->ForceFullDamageNextUpdate();
1668 }
[email protected]829ad972013-01-28 23:36:101669}
1670
[email protected]c1bb5af2013-03-13 19:06:271671void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1672 if (!page_scale_animation_ || !RootScrollLayer())
1673 return;
1674
1675 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1676 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1677 RootScrollLayer()->scroll_delta();
1678
1679 active_tree_->SetPageScaleDelta(
1680 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1681 active_tree_->page_scale_factor());
1682 gfx::Vector2dF next_scroll =
1683 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1684
1685 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1686 client_->SetNeedsRedrawOnImplThread();
1687
1688 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1689 page_scale_animation_.reset();
1690 client_->SetNeedsCommitOnImplThread();
1691 client_->RenewTreePriority();
1692 }
[email protected]829ad972013-01-28 23:36:101693}
1694
[email protected]ffb2720f2013-03-15 19:18:371695void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1696 if (!top_controls_manager_ || !RootScrollLayer())
1697 return;
1698 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1699 UpdateMaxScrollOffset();
1700 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1701 scroll, 1.f / active_tree_->total_page_scale_factor()));
1702}
1703
[email protected]c1bb5af2013-03-13 19:06:271704void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1705 base::Time wall_clock_time) {
1706 if (!settings_.acceleratedAnimationEnabled ||
1707 animation_registrar_->active_animation_controllers().empty() ||
1708 !active_tree_->root_layer())
1709 return;
1710
1711 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1712
1713 last_animation_time_ = wall_clock_time;
1714 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1715
1716 AnimationRegistrar::AnimationControllerMap copy =
1717 animation_registrar_->active_animation_controllers();
1718 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1719 iter != copy.end();
1720 ++iter)
1721 (*iter).second->Animate(monotonic_seconds);
1722
1723 client_->SetNeedsRedrawOnImplThread();
1724 SetBackgroundTickingEnabled(
1725 !visible_ &&
1726 !animation_registrar_->active_animation_controllers().empty());
[email protected]131a0c22013-02-12 18:31:081727}
1728
[email protected]c1bb5af2013-03-13 19:06:271729void LayerTreeHostImpl::UpdateAnimationState() {
1730 if (!settings_.acceleratedAnimationEnabled ||
1731 animation_registrar_->active_animation_controllers().empty() ||
1732 !active_tree_->root_layer())
1733 return;
1734
1735 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1736 scoped_ptr<AnimationEventsVector> events =
1737 make_scoped_ptr(new AnimationEventsVector);
1738 AnimationRegistrar::AnimationControllerMap copy =
1739 animation_registrar_->active_animation_controllers();
1740 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1741 iter != copy.end();
1742 ++iter)
1743 (*iter).second->UpdateState(events.get());
1744
1745 if (!events->empty()) {
1746 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1747 last_animation_time_);
1748 }
[email protected]131a0c22013-02-12 18:31:081749}
1750
[email protected]c1bb5af2013-03-13 19:06:271751base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1752 return base::TimeDelta::FromSeconds(1);
1753}
1754
1755void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1756 DCHECK(current);
1757 current->DidLoseOutputSurface();
1758 if (current->mask_layer())
1759 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1760 if (current->replica_layer())
1761 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1762 for (size_t i = 0; i < current->children().size(); ++i)
1763 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1764}
1765
1766void LayerTreeHostImpl::ClearRenderSurfaces() {
1767 active_tree_->ClearRenderSurfaces();
1768 if (pending_tree_)
1769 pending_tree_->ClearRenderSurfaces();
1770}
1771
1772std::string LayerTreeHostImpl::LayerTreeAsText() const {
1773 std::string str;
1774 if (active_tree_->root_layer()) {
1775 str = active_tree_->root_layer()->LayerTreeAsText();
1776 str += "RenderSurfaces:\n";
1777 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1778 }
1779 return str;
1780}
1781
1782std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1783 std::string str;
1784 if (active_tree_->root_layer()) {
1785 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1786 base::JSONWriter::WriteWithOptions(
1787 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1788 }
1789 return str;
1790}
1791
1792void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1793 int indent,
1794 const LayerImpl* layer) const {
1795 if (layer->render_surface())
1796 layer->render_surface()->DumpSurface(str, indent);
1797
1798 for (size_t i = 0; i < layer->children().size(); ++i)
1799 DumpRenderSurfaces(str, indent, layer->children()[i]);
1800}
1801
1802int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:361803 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:271804}
1805
1806void LayerTreeHostImpl::CollectRenderingStats(RenderingStats* stats) const {
[email protected]9e3594522013-03-18 00:57:361807 stats->numFramesSentToScreen = fps_counter_->current_frame_number();
1808 stats->droppedFrameCount = fps_counter_->dropped_frame_count();
[email protected]c1bb5af2013-03-13 19:06:271809 stats->numImplThreadScrolls = num_impl_thread_scrolls_;
1810 stats->numMainThreadScrolls = num_main_thread_scrolls_;
1811 stats->numLayersDrawn = cumulative_num_layers_drawn_;
1812 stats->numMissingTiles = cumulative_num_missing_tiles_;
1813
1814 if (tile_manager_)
1815 tile_manager_->GetRenderingStats(stats);
1816}
1817
1818void LayerTreeHostImpl::SendManagedMemoryStats(
1819 size_t memory_visible_bytes,
1820 size_t memory_visible_and_nearby_bytes,
1821 size_t memory_use_bytes) {
1822 if (!renderer_)
1823 return;
1824
1825 // Round the numbers being sent up to the next 8MB, to throttle the rate
1826 // at which we spam the GPU process.
1827 static const size_t rounding_step = 8 * 1024 * 1024;
1828 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1829 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1830 rounding_step);
1831 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1832 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1833 last_sent_memory_visible_and_nearby_bytes_ ==
1834 memory_visible_and_nearby_bytes &&
1835 last_sent_memory_use_bytes_ == memory_use_bytes) {
1836 return;
1837 }
1838 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1839 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1840 last_sent_memory_use_bytes_ = memory_use_bytes;
1841
1842 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
1843 last_sent_memory_visible_and_nearby_bytes_,
1844 last_sent_memory_use_bytes_);
1845}
1846
1847void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
1848 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
1849}
1850
1851void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
1852 base::TimeTicks time) {
1853 if (!layer)
1854 return;
1855
1856 ScrollbarAnimationController* scrollbar_controller =
1857 layer->scrollbar_animation_controller();
1858 if (scrollbar_controller && scrollbar_controller->animate(time))
1859 client_->SetNeedsRedrawOnImplThread();
1860
1861 for (size_t i = 0; i < layer->children().size(); ++i)
1862 AnimateScrollbarsRecursive(layer->children()[i], time);
1863}
1864
1865void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
1866 if (!tile_manager_)
1867 return;
1868
1869 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
1870 if (new_state.tree_priority == priority)
1871 return;
1872
1873 new_state.tree_priority = priority;
1874 tile_manager_->SetGlobalState(new_state);
1875}
1876
1877void LayerTreeHostImpl::BeginNextFrame() {
1878 current_frame_time_ = base::TimeTicks();
1879}
1880
1881base::TimeTicks LayerTreeHostImpl::CurrentFrameTime() {
1882 if (current_frame_time_.is_null())
1883 current_frame_time_ = base::TimeTicks::Now();
1884 return current_frame_time_;
1885}
1886
1887scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
1888 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1889 state->Set("activation_state", ActivationStateAsValue().release());
1890 state->Set("frame_state", FrameStateAsValue().release());
1891 return state.PassAs<base::Value>();
1892}
1893
1894scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
1895 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1896 state->SetString("lthi_id", StringPrintf("%p", this));
1897 state->SetBoolean("visible_resources_ready",
1898 pending_tree_->AreVisibleResourcesReady());
1899 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
1900 return state.PassAs<base::Value>();
1901}
1902
1903scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
1904 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1905 state->SetString("lthi_id", StringPrintf("%p", this));
1906 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:211907 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:271908 if (tile_manager_)
1909 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
1910 state->Set("active_tree", active_tree_->AsValue().release());
1911 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:081912}
1913
[email protected]b9dcf43a2013-01-09 00:15:291914// static
[email protected]c1bb5af2013-03-13 19:06:271915LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
1916 LayerImpl* layer) {
1917 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:291918 return NULL;
[email protected]c1bb5af2013-03-13 19:06:271919
1920 if (layer->DrawsContent())
1921 return layer;
1922
1923 for (LayerImpl::LayerList::const_iterator it = layer->children().begin();
1924 it != layer->children().end(); ++it) {
1925 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
1926 if (nccr)
1927 return nccr;
1928 }
1929
1930 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:291931}
1932
[email protected]c1bb5af2013-03-13 19:06:271933skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
1934 LayerTreeImpl* tree =
1935 pending_tree_ ? pending_tree_.get() : active_tree_.get();
1936 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
1937 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:291938}
1939
[email protected]c1bb5af2013-03-13 19:06:271940void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
1941 if (debug_state_.continuousPainting != debug_state.continuousPainting)
1942 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:241943
[email protected]c1bb5af2013-03-13 19:06:271944 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:021945
[email protected]c1bb5af2013-03-13 19:06:271946 if (tile_manager_)
1947 tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats());
[email protected]d0d12192013-02-08 19:02:021948}
1949
[email protected]c1bb5af2013-03-13 19:06:271950void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time,
1951 int commit_number) {
1952 DCHECK(debug_state_.continuousPainting);
1953 paint_time_counter_->SavePaintTime(total_paint_time, commit_number);
[email protected]0edbfbe9f2013-01-17 03:33:031954}
1955
[email protected]d3143c732012-10-05 19:17:591956} // namespace cc