blob: 0b425615234e5de21a23b17ea3fab17dc04e50e8 [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]556fd292013-03-18 08:03:045#include "cc/trees/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]95e4e1a02013-03-18 07:09:0915#include "cc/animation/scrollbar_animation_controller.h"
[email protected]681ccff2013-03-18 06:13:5216#include "cc/base/math_util.h"
17#include "cc/base/util.h"
[email protected]6e84de22013-03-18 06:54:2718#include "cc/debug/debug_rect_history.h"
19#include "cc/debug/frame_rate_counter.h"
20#include "cc/debug/overdraw_metrics.h"
21#include "cc/debug/paint_time_counter.h"
[email protected]372bad5f2013-03-21 16:38:4322#include "cc/debug/rendering_stats_instrumentation.h"
[email protected]3052b10f2013-03-18 07:41:2123#include "cc/input/page_scale_animation.h"
24#include "cc/input/top_controls_manager.h"
[email protected]cc3cfaa2013-03-18 09:05:5225#include "cc/layers/append_quads_data.h"
26#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]50761e92013-03-29 20:51:2827#include "cc/layers/layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5228#include "cc/layers/layer_iterator.h"
[email protected]50761e92013-03-29 20:51:2829#include "cc/layers/render_surface_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5230#include "cc/layers/scrollbar_layer_impl.h"
[email protected]7f0d825f2013-03-18 07:24:3031#include "cc/output/compositor_frame_metadata.h"
32#include "cc/output/delegating_renderer.h"
33#include "cc/output/gl_renderer.h"
34#include "cc/output/software_renderer.h"
[email protected]89e82672013-03-18 07:50:5635#include "cc/quads/render_pass_draw_quad.h"
36#include "cc/quads/shared_quad_state.h"
37#include "cc/quads/solid_color_draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4038#include "cc/resources/memory_history.h"
39#include "cc/resources/picture_layer_tiling.h"
40#include "cc/resources/prioritized_resource_manager.h"
[email protected]be4655a2013-03-18 08:36:3141#include "cc/scheduler/delay_based_time_source.h"
42#include "cc/scheduler/texture_uploader.h"
[email protected]556fd292013-03-18 08:03:0443#include "cc/trees/damage_tracker.h"
44#include "cc/trees/layer_tree_host.h"
45#include "cc/trees/layer_tree_host_common.h"
46#include "cc/trees/layer_tree_impl.h"
47#include "cc/trees/quad_culler.h"
48#include "cc/trees/single_thread_proxy.h"
49#include "cc/trees/tree_synchronizer.h"
[email protected]d455d552012-11-02 00:19:0650#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1351#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1452
[email protected]94f206c12012-08-25 00:09:1453namespace {
54
[email protected]c1bb5af2013-03-13 19:06:2755void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) {
56 if (visible) {
57 TRACE_EVENT_ASYNC_BEGIN1("webkit",
58 "LayerTreeHostImpl::SetVisible",
59 id,
60 "LayerTreeHostImpl",
61 id);
62 return;
63 }
[email protected]94f206c12012-08-25 00:09:1464
[email protected]c1bb5af2013-03-13 19:06:2765 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id);
[email protected]94f206c12012-08-25 00:09:1466}
67
[email protected]c1bb5af2013-03-13 19:06:2768std::string ValueToString(scoped_ptr<base::Value> value) {
69 std::string str;
70 base::JSONWriter::Write(value.get(), &str);
71 return str;
[email protected]131a0c22013-02-12 18:31:0872}
73
[email protected]c1bb5af2013-03-13 19:06:2774} // namespace
[email protected]94f206c12012-08-25 00:09:1475
[email protected]9c88e562012-09-14 22:21:3076namespace cc {
[email protected]94f206c12012-08-25 00:09:1477
[email protected]96baf3e2012-10-22 23:09:5578class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]c1bb5af2013-03-13 19:06:2779 public:
80 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
81 LayerTreeHostImpl* layer_tree_host_impl,
82 scoped_refptr<DelayBasedTimeSource> time_source) {
83 return make_scoped_ptr(
84 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
85 time_source));
86 }
87 virtual ~LayerTreeHostImplTimeSourceAdapter() {
[email protected]6d0e69d2013-03-20 14:53:2688 time_source_->SetClient(NULL);
89 time_source_->SetActive(false);
[email protected]c1bb5af2013-03-13 19:06:2790 }
91
[email protected]6d0e69d2013-03-20 14:53:2692 virtual void OnTimerTick() OVERRIDE {
[email protected]c1bb5af2013-03-13 19:06:2793 // In single threaded mode we attempt to simulate changing the current
94 // thread by maintaining a fake thread id. When we switch from one
95 // thread to another, we construct DebugScopedSetXXXThread objects that
96 // update the thread id. This lets DCHECKS that ensure we're on the
97 // right thread to work correctly in single threaded mode. The problem
98 // here is that the timer tasks are run via the message loop, and when
99 // they run, we've had no chance to construct a DebugScopedSetXXXThread
100 // object. The result is that we report that we're running on the main
101 // thread. In multi-threaded mode, this timer is run on the compositor
102 // thread, so to keep this consistent in single-threaded mode, we'll
103 // construct a DebugScopedSetImplThread object. There is no need to do
104 // this in multi-threaded mode since the real thread id's will be
105 // correct. In fact, setting fake thread id's interferes with the real
106 // thread id's and causes breakage.
107 scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
108 if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
109 set_impl_thread.reset(
110 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
[email protected]94f206c12012-08-25 00:09:14111 }
112
[email protected]c1bb5af2013-03-13 19:06:27113 layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
[email protected]fb7425a2013-04-22 16:28:55114 layer_tree_host_impl_->Animate(
115 layer_tree_host_impl_->CurrentFrameTimeTicks(),
116 layer_tree_host_impl_->CurrentFrameTime());
[email protected]3d9f7432013-04-06 00:35:18117 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
118 bool start_ready_animations = true;
119 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]c1bb5af2013-03-13 19:06:27120 layer_tree_host_impl_->BeginNextFrame();
121 }
[email protected]373974232013-01-10 22:20:50122
[email protected]c1bb5af2013-03-13 19:06:27123 void SetActive(bool active) {
[email protected]6d0e69d2013-03-20 14:53:26124 if (active != time_source_->Active())
125 time_source_->SetActive(active);
[email protected]c1bb5af2013-03-13 19:06:27126 }
[email protected]94f206c12012-08-25 00:09:14127
[email protected]c1bb5af2013-03-13 19:06:27128 private:
129 LayerTreeHostImplTimeSourceAdapter(
130 LayerTreeHostImpl* layer_tree_host_impl,
131 scoped_refptr<DelayBasedTimeSource> time_source)
132 : layer_tree_host_impl_(layer_tree_host_impl),
133 time_source_(time_source) {
[email protected]6d0e69d2013-03-20 14:53:26134 time_source_->SetClient(this);
[email protected]c1bb5af2013-03-13 19:06:27135 }
[email protected]94f206c12012-08-25 00:09:14136
[email protected]c1bb5af2013-03-13 19:06:27137 LayerTreeHostImpl* layer_tree_host_impl_;
138 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14139
[email protected]c1bb5af2013-03-13 19:06:27140 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14141};
142
[email protected]96baf3e2012-10-22 23:09:55143LayerTreeHostImpl::FrameData::FrameData()
[email protected]e0341352013-04-06 05:01:20144 : contains_incomplete_tile(false), has_no_damage(false) {}
[email protected]c1bb5af2013-03-13 19:06:27145
146LayerTreeHostImpl::FrameData::~FrameData() {}
147
148scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
149 const LayerTreeSettings& settings,
150 LayerTreeHostImplClient* client,
[email protected]372bad5f2013-03-21 16:38:43151 Proxy* proxy,
152 RenderingStatsInstrumentation* rendering_stats_instrumentation) {
153 return make_scoped_ptr(
154 new LayerTreeHostImpl(settings,
155 client,
156 proxy,
157 rendering_stats_instrumentation));
[email protected]493067512012-09-19 23:34:10158}
159
[email protected]372bad5f2013-03-21 16:38:43160LayerTreeHostImpl::LayerTreeHostImpl(
161 const LayerTreeSettings& settings,
162 LayerTreeHostImplClient* client,
163 Proxy* proxy,
164 RenderingStatsInstrumentation* rendering_stats_instrumentation)
[email protected]c1bb5af2013-03-13 19:06:27165 : client_(client),
166 proxy_(proxy),
167 did_lock_scrolling_layer_(false),
168 should_bubble_scrolls_(false),
169 wheel_scrolling_(false),
170 settings_(settings),
[email protected]d9083762013-03-24 01:36:40171 overdraw_bottom_height_(0.f),
[email protected]c1bb5af2013-03-13 19:06:27172 device_scale_factor_(1.f),
173 visible_(true),
174 managed_memory_policy_(
[email protected]b56c1302013-03-20 21:17:34175 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
[email protected]c1bb5af2013-03-13 19:06:27176 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
177 0,
178 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
179 pinch_gesture_active_(false),
[email protected]9e3594522013-03-18 00:57:36180 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29181 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27182 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02183 debug_rect_history_(DebugRectHistory::Create()),
[email protected]d7626ffd2013-03-29 00:17:42184 max_memory_needed_bytes_(0),
[email protected]c1bb5af2013-03-13 19:06:27185 last_sent_memory_visible_bytes_(0),
186 last_sent_memory_visible_and_nearby_bytes_(0),
187 last_sent_memory_use_bytes_(0),
[email protected]372bad5f2013-03-21 16:38:43188 animation_registrar_(AnimationRegistrar::Create()),
189 rendering_stats_instrumentation_(rendering_stats_instrumentation) {
[email protected]c1bb5af2013-03-13 19:06:27190 DCHECK(proxy_->IsImplThread());
191 DidVisibilityChange(this, visible_);
192
[email protected]8e0176d2013-03-21 03:14:52193 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27194
[email protected]8e0176d2013-03-21 03:14:52195 if (settings.calculate_top_controls_position) {
[email protected]c1bb5af2013-03-13 19:06:27196 top_controls_manager_ =
197 TopControlsManager::Create(this,
[email protected]8e0176d2013-03-21 03:14:52198 settings.top_controls_height,
199 settings.top_controls_show_threshold,
200 settings.top_controls_hide_threshold);
[email protected]c1bb5af2013-03-13 19:06:27201 }
202
[email protected]8e0176d2013-03-21 03:14:52203 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27204
205 // LTHI always has an active tree.
206 active_tree_ = LayerTreeImpl::create(this);
[email protected]493067512012-09-19 23:34:10207}
208
[email protected]c1bb5af2013-03-13 19:06:27209LayerTreeHostImpl::~LayerTreeHostImpl() {
210 DCHECK(proxy_->IsImplThread());
211 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
212
213 if (active_tree_->root_layer()) {
214 ClearRenderSurfaces();
215 // The layer trees must be destroyed before the layer tree host. We've
216 // made a contract with our animation controllers that the registrar
217 // will outlive them, and we must make good.
218 recycle_tree_.reset();
219 pending_tree_.reset();
220 active_tree_.reset();
221 }
[email protected]94f206c12012-08-25 00:09:14222}
223
[email protected]c1bb5af2013-03-13 19:06:27224void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29225
[email protected]c1bb5af2013-03-13 19:06:27226void LayerTreeHostImpl::CommitComplete() {
227 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08228
[email protected]c1bb5af2013-03-13 19:06:27229 // Impl-side painting needs an update immediately post-commit to have the
230 // opportunity to create tilings. Other paths can call UpdateDrawProperties
231 // more lazily when needed prior to drawing.
[email protected]8e0176d2013-03-21 03:14:52232 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:27233 pending_tree_->set_needs_update_draw_properties();
234 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
235 } else {
236 active_tree_->set_needs_update_draw_properties();
237 }
[email protected]3ba4cae2013-01-16 03:58:38238
[email protected]c1bb5af2013-03-13 19:06:27239 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14240}
241
[email protected]c1bb5af2013-03-13 19:06:27242bool LayerTreeHostImpl::CanDraw() {
243 // Note: If you are changing this function or any other function that might
244 // affect the result of CanDraw, make sure to call
245 // client_->OnCanDrawStateChanged in the proper places and update the
246 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14247
[email protected]c1bb5af2013-03-13 19:06:27248 if (!active_tree_->root_layer()) {
[email protected]c76faea2013-03-26 07:42:42249 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
250 TRACE_EVENT_SCOPE_THREAD);
[email protected]2f1acc262012-11-16 21:42:22251 return false;
[email protected]c1bb5af2013-03-13 19:06:27252 }
253 if (device_viewport_size_.IsEmpty()) {
[email protected]c76faea2013-03-26 07:42:42254 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
255 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27256 return false;
257 }
258 if (active_tree_->ViewportSizeInvalid()) {
259 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42260 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed",
261 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27262 return false;
263 }
264 if (!renderer_) {
[email protected]c76faea2013-03-26 07:42:42265 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer",
266 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27267 return false;
268 }
269 if (active_tree_->ContentsTexturesPurged()) {
270 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42271 "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
272 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27273 return false;
274 }
275 return true;
[email protected]2f1acc262012-11-16 21:42:22276}
277
[email protected]c1bb5af2013-03-13 19:06:27278void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
279 base::Time wall_clock_time) {
280 AnimatePageScale(monotonic_time);
281 AnimateLayers(monotonic_time, wall_clock_time);
282 AnimateScrollbars(monotonic_time);
[email protected]ffb2720f2013-03-15 19:18:37283 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14284}
285
[email protected]c1bb5af2013-03-13 19:06:27286void LayerTreeHostImpl::ManageTiles() {
287 DCHECK(tile_manager_);
288 tile_manager_->ManageTiles();
289
290 size_t memory_required_bytes;
291 size_t memory_nice_to_have_bytes;
292 size_t memory_used_bytes;
293 tile_manager_->GetMemoryStats(&memory_required_bytes,
294 &memory_nice_to_have_bytes,
295 &memory_used_bytes);
296 SendManagedMemoryStats(memory_required_bytes,
297 memory_nice_to_have_bytes,
298 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15299}
300
[email protected]80334ba2013-03-20 17:33:50301void LayerTreeHostImpl::SetAnticipatedDrawTime(base::TimeTicks time) {
[email protected]f8456612013-03-19 20:56:09302 if (tile_manager_)
303 tile_manager_->SetAnticipatedDrawTime(time);
304}
305
[email protected]c1bb5af2013-03-13 19:06:27306void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
307 bool anchor_point,
308 float page_scale,
309 base::TimeTicks start_time,
310 base::TimeDelta duration) {
311 if (!RootScrollLayer())
312 return;
313
314 gfx::Vector2dF scroll_total =
315 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
316 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
[email protected]6fc4ee002013-03-26 23:39:51317 gfx::SizeF viewport_size = VisibleViewportSize();
[email protected]c1bb5af2013-03-13 19:06:27318
319 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
320 page_scale_animation_ =
321 PageScaleAnimation::Create(scroll_total,
322 active_tree_->total_page_scale_factor(),
323 viewport_size,
324 scaled_scrollable_size,
325 start_time_seconds);
326
327 if (anchor_point) {
328 gfx::Vector2dF anchor(target_offset);
329 page_scale_animation_->ZoomWithAnchor(anchor,
330 page_scale,
331 duration.InSecondsF());
332 } else {
333 gfx::Vector2dF scaled_target_offset = target_offset;
334 page_scale_animation_->ZoomTo(scaled_target_offset,
335 page_scale,
336 duration.InSecondsF());
337 }
338
339 client_->SetNeedsRedrawOnImplThread();
340 client_->SetNeedsCommitOnImplThread();
341 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15342}
343
[email protected]c1bb5af2013-03-13 19:06:27344void LayerTreeHostImpl::ScheduleAnimation() {
345 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15346}
347
[email protected]c1bb5af2013-03-13 19:06:27348bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
349 if (!EnsureRenderSurfaceLayerList())
350 return false;
[email protected]f57bbc02012-11-21 07:02:15351
[email protected]c1bb5af2013-03-13 19:06:27352 gfx::PointF device_viewport_point =
353 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15354
[email protected]c1bb5af2013-03-13 19:06:27355 // First find out which layer was hit from the saved list of visible layers
356 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:39357 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:27358 device_viewport_point,
359 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15360
[email protected]c1bb5af2013-03-13 19:06:27361 // Walk up the hierarchy and look for a layer with a touch event handler
362 // region that the given point hits.
363 for (; layer_impl; layer_impl = layer_impl->parent()) {
[email protected]6ba914122013-03-22 16:26:39364 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point,
[email protected]c1bb5af2013-03-13 19:06:27365 layer_impl))
366 return true;
367 }
[email protected]f57bbc02012-11-21 07:02:15368
[email protected]c1bb5af2013-03-13 19:06:27369 return false;
370}
371
[email protected]ef915f532013-04-22 20:56:32372void LayerTreeHostImpl::DidReceiveLastInputEventForVSync(
373 base::TimeTicks frame_time) {
374 client_->DidReceiveLastInputEventForVSync(frame_time);
375}
376
[email protected]c1bb5af2013-03-13 19:06:27377void LayerTreeHostImpl::TrackDamageForAllSurfaces(
378 LayerImpl* root_draw_layer,
[email protected]50761e92013-03-29 20:51:28379 const LayerImplList& render_surface_layer_list) {
[email protected]c1bb5af2013-03-13 19:06:27380 // For now, we use damage tracking to compute a global scissor. To do this, we
381 // must compute all damage tracking before drawing anything, so that we know
382 // the root damage rect. The root damage rect is then used to scissor each
383 // surface.
384
385 for (int surface_index = render_surface_layer_list.size() - 1;
[email protected]bf691c22013-03-26 21:15:06386 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27387 --surface_index) {
388 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
389 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
390 DCHECK(render_surface);
391 render_surface->damage_tracker()->UpdateDamageTrackingState(
392 render_surface->layer_list(),
393 render_surface_layer->id(),
394 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
395 render_surface->content_rect(),
396 render_surface_layer->mask_layer(),
397 render_surface_layer->filters(),
398 render_surface_layer->filter().get());
399 }
400}
401
402void LayerTreeHostImpl::FrameData::AppendRenderPass(
403 scoped_ptr<RenderPass> render_pass) {
404 render_passes_by_id[render_pass->id] = render_pass.get();
405 render_passes.push_back(render_pass.Pass());
406}
407
408static void AppendQuadsForLayer(RenderPass* target_render_pass,
409 LayerImpl* layer,
410 const OcclusionTrackerImpl& occlusion_tracker,
411 AppendQuadsData* append_quads_data) {
412 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49413 QuadCuller quad_culler(&target_render_pass->quad_list,
414 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27415 layer,
416 occlusion_tracker,
417 layer->ShowDebugBorders(),
418 for_surface);
419 layer->AppendQuads(&quad_culler, append_quads_data);
420}
421
422static void AppendQuadsForRenderSurfaceLayer(
423 RenderPass* target_render_pass,
424 LayerImpl* layer,
425 const RenderPass* contributing_render_pass,
426 const OcclusionTrackerImpl& occlusion_tracker,
427 AppendQuadsData* append_quads_data) {
428 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49429 QuadCuller quad_culler(&target_render_pass->quad_list,
430 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27431 layer,
432 occlusion_tracker,
433 layer->ShowDebugBorders(),
434 for_surface);
435
436 bool is_replica = false;
437 layer->render_surface()->AppendQuads(&quad_culler,
438 append_quads_data,
439 is_replica,
440 contributing_render_pass->id);
441
442 // Add replica after the surface so that it appears below the surface.
443 if (layer->has_replica()) {
444 is_replica = true;
445 layer->render_surface()->AppendQuads(&quad_culler,
446 append_quads_data,
447 is_replica,
448 contributing_render_pass->id);
449 }
450}
451
452static void AppendQuadsToFillScreen(
453 RenderPass* target_render_pass,
454 LayerImpl* root_layer,
455 SkColor screen_background_color,
456 const OcclusionTrackerImpl& occlusion_tracker) {
457 if (!root_layer || !SkColorGetA(screen_background_color))
458 return;
459
460 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
461 if (fill_region.IsEmpty())
462 return;
463
464 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49465 QuadCuller quad_culler(&target_render_pass->quad_list,
466 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27467 root_layer,
468 occlusion_tracker,
469 root_layer->ShowDebugBorders(),
470 for_surface);
471
472 // Manually create the quad state for the gutter quads, as the root layer
473 // doesn't have any bounds and so can't generate this itself.
474 // TODO(danakj): Make the gutter quads generated by the solid color layer
475 // (make it smarter about generating quads to fill unoccluded areas).
476
477 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
478 float opacity = 1.f;
479 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49480 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27481 shared_quad_state->SetAll(root_layer->draw_transform(),
482 root_target_rect.size(),
483 root_target_rect,
484 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01485 false,
[email protected]f57bbc02012-11-21 07:02:15486 opacity);
487
[email protected]c1bb5af2013-03-13 19:06:27488 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17489
[email protected]c1bb5af2013-03-13 19:06:27490 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
491 bool did_invert = root_layer->screen_space_transform().GetInverse(
492 &transform_to_layer_space);
493 DCHECK(did_invert);
494 for (Region::Iterator fill_rects(fill_region);
495 fill_rects.has_rect();
496 fill_rects.next()) {
497 // The root layer transform is composed of translations and scales only,
498 // no perspective, so mapping is sufficient (as opposed to projecting).
499 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21500 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27501 // Skip the quad culler and just append the quads directly to avoid
502 // occlusion checks.
503 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
504 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
[email protected]c7e95b42013-03-18 01:13:49505 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27506 }
[email protected]467b3612012-08-28 07:41:16507}
508
[email protected]c1bb5af2013-03-13 19:06:27509bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
510 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14511
[email protected]c1bb5af2013-03-13 19:06:27512 if (!CanDraw() || !active_tree_->root_layer())
513 return false;
[email protected]2d692992012-12-19 01:19:32514
[email protected]c1bb5af2013-03-13 19:06:27515 TrackDamageForAllSurfaces(active_tree_->root_layer(),
516 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14517
[email protected]e0341352013-04-06 05:01:20518 // If the root render surface has no visible damage, then don't generate a
519 // frame at all.
520 RenderSurfaceImpl* root_surface =
521 active_tree_->root_layer()->render_surface();
522 bool root_surface_has_no_visible_damage =
523 !root_surface->damage_tracker()->current_damage_rect().Intersects(
524 root_surface->content_rect());
525 bool root_surface_has_contributing_layers =
526 !root_surface->layer_list().empty();
527 if (root_surface_has_contributing_layers &&
528 root_surface_has_no_visible_damage) {
529 TRACE_EVENT0("cc",
530 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
531 frame->has_no_damage = true;
532 return true;
533 }
534
[email protected]c1bb5af2013-03-13 19:06:27535 TRACE_EVENT1("cc",
536 "LayerTreeHostImpl::CalculateRenderPasses",
537 "render_surface_layer_list.size()",
[email protected]bf691c22013-03-26 21:15:06538 static_cast<uint64>(frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14539
[email protected]c1bb5af2013-03-13 19:06:27540 // Create the render passes in dependency order.
541 for (int surface_index = frame->render_surface_layer_list->size() - 1;
[email protected]bf691c22013-03-26 21:15:06542 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27543 --surface_index) {
544 LayerImpl* render_surface_layer =
545 (*frame->render_surface_layer_list)[surface_index];
546 render_surface_layer->render_surface()->AppendRenderPasses(frame);
547 }
[email protected]94f206c12012-08-25 00:09:14548
[email protected]c1bb5af2013-03-13 19:06:27549 bool record_metrics_for_frame =
[email protected]8e0176d2013-03-21 03:14:52550 settings_.show_overdraw_in_tracing &&
[email protected]c1bb5af2013-03-13 19:06:27551 base::debug::TraceLog::GetInstance() &&
552 base::debug::TraceLog::GetInstance()->IsEnabled();
553 OcclusionTrackerImpl occlusion_tracker(
554 active_tree_->root_layer()->render_surface()->content_rect(),
555 record_metrics_for_frame);
556 occlusion_tracker.set_minimum_tracking_size(
[email protected]8e0176d2013-03-21 03:14:52557 settings_.minimum_occlusion_tracking_size);
[email protected]94f206c12012-08-25 00:09:14558
[email protected]846f455b2013-03-18 19:07:41559 if (debug_state_.show_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27560 occlusion_tracker.set_occluding_screen_space_rects_container(
561 &frame->occluding_screen_space_rects);
562 }
[email protected]846f455b2013-03-18 19:07:41563 if (debug_state_.show_non_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27564 occlusion_tracker.set_non_occluding_screen_space_rects_container(
565 &frame->non_occluding_screen_space_rects);
566 }
[email protected]94f206c12012-08-25 00:09:14567
[email protected]c1bb5af2013-03-13 19:06:27568 // Add quads to the Render passes in FrontToBack order to allow for testing
569 // occlusion and performing culling during the tree walk.
570 typedef LayerIterator<LayerImpl,
[email protected]50761e92013-03-29 20:51:28571 LayerImplList,
[email protected]c1bb5af2013-03-13 19:06:27572 RenderSurfaceImpl,
573 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14574
[email protected]c1bb5af2013-03-13 19:06:27575 // Typically when we are missing a texture and use a checkerboard quad, we
576 // still draw the frame. However when the layer being checkerboarded is moving
577 // due to an impl-animation, we drop the frame to avoid flashing due to the
578 // texture suddenly appearing in the future.
579 bool draw_frame = true;
[email protected]94f206c12012-08-25 00:09:14580
[email protected]372bad5f2013-03-21 16:38:43581 int layers_drawn = 0;
582
[email protected]c1bb5af2013-03-13 19:06:27583 LayerIteratorType end =
[email protected]71dfcc72013-03-20 21:30:09584 LayerIteratorType::End(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27585 for (LayerIteratorType it =
[email protected]71dfcc72013-03-20 21:30:09586 LayerIteratorType::Begin(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27587 it != end;
588 ++it) {
589 RenderPass::Id target_render_pass_id =
[email protected]71dfcc72013-03-20 21:30:09590 it.target_render_surface_layer()->render_surface()->RenderPassId();
[email protected]c1bb5af2013-03-13 19:06:27591 RenderPass* target_render_pass =
592 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14593
[email protected]c1bb5af2013-03-13 19:06:27594 occlusion_tracker.EnterLayer(it);
[email protected]94f206c12012-08-25 00:09:14595
[email protected]c1bb5af2013-03-13 19:06:27596 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30597
[email protected]71dfcc72013-03-20 21:30:09598 if (it.represents_contributing_render_surface()) {
[email protected]c1bb5af2013-03-13 19:06:27599 RenderPass::Id contributing_render_pass_id =
600 it->render_surface()->RenderPassId();
601 RenderPass* contributing_render_pass =
602 frame->render_passes_by_id[contributing_render_pass_id];
603 AppendQuadsForRenderSurfaceLayer(target_render_pass,
604 *it,
605 contributing_render_pass,
606 occlusion_tracker,
607 &append_quads_data);
[email protected]e1e768f2013-03-26 08:48:09608 } else if (it.represents_itself() &&
609 !it->visible_content_rect().IsEmpty()) {
[email protected]c1bb5af2013-03-13 19:06:27610 bool has_occlusion_from_outside_target_surface;
611 bool impl_draw_transform_is_unknown = false;
612 if (occlusion_tracker.Occluded(
613 it->render_target(),
614 it->visible_content_rect(),
615 it->draw_transform(),
616 impl_draw_transform_is_unknown,
617 it->is_clipped(),
618 it->clip_rect(),
619 &has_occlusion_from_outside_target_surface)) {
[email protected]e1e768f2013-03-26 08:48:09620 append_quads_data.had_occlusion_from_outside_target_surface |=
[email protected]c1bb5af2013-03-13 19:06:27621 has_occlusion_from_outside_target_surface;
622 } else {
623 DCHECK_EQ(active_tree_, it->layer_tree_impl());
624 it->WillDraw(resource_provider_.get());
625 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57626
[email protected]c1bb5af2013-03-13 19:06:27627 if (it->HasContributingDelegatedRenderPasses()) {
628 RenderPass::Id contributing_render_pass_id =
629 it->FirstContributingRenderPassId();
630 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
631 frame->render_passes_by_id.end()) {
632 RenderPass* render_pass =
633 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14634
[email protected]c1bb5af2013-03-13 19:06:27635 AppendQuadsData append_quads_data(render_pass->id);
636 AppendQuadsForLayer(render_pass,
637 *it,
638 occlusion_tracker,
639 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57640
[email protected]c1bb5af2013-03-13 19:06:27641 contributing_render_pass_id =
642 it->NextContributingRenderPassId(contributing_render_pass_id);
643 }
[email protected]94f206c12012-08-25 00:09:14644 }
645
[email protected]c1bb5af2013-03-13 19:06:27646 AppendQuadsForLayer(target_render_pass,
647 *it,
648 occlusion_tracker,
649 &append_quads_data);
650 }
[email protected]89228202012-08-29 03:20:30651
[email protected]372bad5f2013-03-21 16:38:43652 ++layers_drawn;
[email protected]94f206c12012-08-25 00:09:14653 }
654
[email protected]e1e768f2013-03-26 08:48:09655 if (append_quads_data.had_occlusion_from_outside_target_surface)
[email protected]c1bb5af2013-03-13 19:06:27656 target_render_pass->has_occlusion_from_outside_target_surface = true;
657
[email protected]e1e768f2013-03-26 08:48:09658 if (append_quads_data.num_missing_tiles) {
[email protected]372bad5f2013-03-21 16:38:43659 rendering_stats_instrumentation_->AddMissingTiles(
[email protected]e1e768f2013-03-26 08:48:09660 append_quads_data.num_missing_tiles);
[email protected]c1bb5af2013-03-13 19:06:27661 bool layer_has_animating_transform =
662 it->screen_space_transform_is_animating() ||
663 it->draw_transform_is_animating();
664 if (layer_has_animating_transform)
665 draw_frame = false;
666 }
667
[email protected]e1e768f2013-03-26 08:48:09668 if (append_quads_data.had_incomplete_tile)
[email protected]c1bb5af2013-03-13 19:06:27669 frame->contains_incomplete_tile = true;
670
671 occlusion_tracker.LeaveLayer(it);
672 }
673
[email protected]372bad5f2013-03-21 16:38:43674 rendering_stats_instrumentation_->AddLayersDrawn(layers_drawn);
675
[email protected]1d993172012-10-18 18:15:04676#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27677 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
678 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
679 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
680 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
681 != frame->render_passes_by_id.end());
682 }
[email protected]94f206c12012-08-25 00:09:14683#endif
[email protected]c1bb5af2013-03-13 19:06:27684 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14685
[email protected]c1bb5af2013-03-13 19:06:27686 if (!active_tree_->has_transparent_background()) {
687 frame->render_passes.back()->has_transparent_background = false;
688 AppendQuadsToFillScreen(frame->render_passes.back(),
689 active_tree_->root_layer(),
690 active_tree_->background_color(),
691 occlusion_tracker);
692 }
[email protected]94f206c12012-08-25 00:09:14693
[email protected]c1bb5af2013-03-13 19:06:27694 if (draw_frame)
695 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]94f206c12012-08-25 00:09:14696
[email protected]c1bb5af2013-03-13 19:06:27697 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
698 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
[email protected]bf691c22013-03-26 21:15:06699 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()),
700 frame);
[email protected]94f206c12012-08-25 00:09:14701
[email protected]e0341352013-04-06 05:01:20702 // If we're making a frame to draw, it better have at least one render pass.
703 DCHECK(!frame->render_passes.empty());
[email protected]c1bb5af2013-03-13 19:06:27704 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14705}
706
[email protected]3d9f7432013-04-06 00:35:18707void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
708 bool should_background_tick) {
709 bool enabled = should_background_tick &&
710 !animation_registrar_->active_animation_controllers().empty();
711
[email protected]c1bb5af2013-03-13 19:06:27712 // Lazily create the time_source adapter so that we can vary the interval for
713 // testing.
714 if (!time_source_client_adapter_) {
715 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
716 this,
[email protected]6d0e69d2013-03-20 14:53:26717 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
[email protected]c1bb5af2013-03-13 19:06:27718 proxy_->CurrentThread()));
719 }
[email protected]94f206c12012-08-25 00:09:14720
[email protected]c1bb5af2013-03-13 19:06:27721 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14722}
723
[email protected]b9d4a362013-04-23 05:36:27724void LayerTreeHostImpl::SetViewportDamage(gfx::Rect damage_rect) {
[email protected]878705be2013-04-15 22:44:02725 viewport_damage_rect_.Union(damage_rect);
726}
727
[email protected]c1bb5af2013-03-13 19:06:27728static inline RenderPass* FindRenderPassById(
729 RenderPass::Id render_pass_id,
730 const LayerTreeHostImpl::FrameData& frame) {
731 RenderPassIdHashMap::const_iterator it =
732 frame.render_passes_by_id.find(render_pass_id);
733 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14734}
735
[email protected]c1bb5af2013-03-13 19:06:27736static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
737 LayerTreeHostImpl::FrameData* frame) {
738 RenderPass* remove_render_pass =
739 FindRenderPassById(remove_render_pass_id, *frame);
740 // The pass was already removed by another quad - probably the original, and
741 // we are the replica.
742 if (!remove_render_pass)
743 return;
744 RenderPassList& render_passes = frame->render_passes;
745 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
746 render_passes.end(),
747 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14748
[email protected]c1bb5af2013-03-13 19:06:27749 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14750
[email protected]c1bb5af2013-03-13 19:06:27751 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
752 frame->render_passes.erase(to_remove);
753 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14754
[email protected]c1bb5af2013-03-13 19:06:27755 // Now follow up for all RenderPass quads and remove their RenderPasses
756 // recursively.
757 const QuadList& quad_list = removed_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29758 QuadList::ConstBackToFrontIterator quad_list_iterator =
759 quad_list.BackToFrontBegin();
760 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27761 ++quad_list_iterator) {
762 DrawQuad* current_quad = (*quad_list_iterator);
763 if (current_quad->material != DrawQuad::RENDER_PASS)
764 continue;
[email protected]94f206c12012-08-25 00:09:14765
[email protected]c1bb5af2013-03-13 19:06:27766 RenderPass::Id next_remove_render_pass_id =
767 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
768 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
769 }
[email protected]94f206c12012-08-25 00:09:14770}
771
[email protected]c1bb5af2013-03-13 19:06:27772bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
773 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
774 const FrameData& frame) const {
775 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
776 bool quad_has_cached_resource =
[email protected]bf691c22013-03-26 21:15:06777 renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id);
[email protected]c1bb5af2013-03-13 19:06:27778 if (quad_has_damage) {
779 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
780 return false;
781 } else if (!quad_has_cached_resource) {
782 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
783 return false;
784 }
785 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
786 return true;
[email protected]94f206c12012-08-25 00:09:14787}
788
[email protected]c1bb5af2013-03-13 19:06:27789bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
790 const RenderPassDrawQuad& quad, const FrameData& frame) const {
791 const RenderPass* render_pass =
792 FindRenderPassById(quad.render_pass_id, frame);
793 if (!render_pass)
794 return false;
[email protected]94f206c12012-08-25 00:09:14795
[email protected]c1bb5af2013-03-13 19:06:27796 // If any quad or RenderPass draws into this RenderPass, then keep it.
797 const QuadList& quad_list = render_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29798 for (QuadList::ConstBackToFrontIterator quad_list_iterator =
799 quad_list.BackToFrontBegin();
800 quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27801 ++quad_list_iterator) {
802 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14803
[email protected]c1bb5af2013-03-13 19:06:27804 if (current_quad->material != DrawQuad::RENDER_PASS)
805 return false;
[email protected]94f206c12012-08-25 00:09:14806
[email protected]c1bb5af2013-03-13 19:06:27807 const RenderPass* contributing_pass = FindRenderPassById(
808 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
809 if (contributing_pass)
810 return false;
811 }
812 return true;
[email protected]94f206c12012-08-25 00:09:14813}
814
815// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27816template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
817 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
818 CullRenderPassesWithCachedTextures culler, FrameData* frame);
819template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
820 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
821 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14822
823// static
[email protected]c1bb5af2013-03-13 19:06:27824template <typename RenderPassCuller>
825void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
826 FrameData* frame) {
827 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
828 it != culler.RenderPassListEnd(frame->render_passes);
829 it = culler.RenderPassListNext(it)) {
830 const RenderPass* current_pass = frame->render_passes[it];
831 const QuadList& quad_list = current_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29832 QuadList::ConstBackToFrontIterator quad_list_iterator =
833 quad_list.BackToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14834
[email protected]ed511b8d2013-03-25 03:29:29835 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27836 ++quad_list_iterator) {
837 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14838
[email protected]c1bb5af2013-03-13 19:06:27839 if (current_quad->material != DrawQuad::RENDER_PASS)
840 continue;
[email protected]94f206c12012-08-25 00:09:14841
[email protected]c1bb5af2013-03-13 19:06:27842 const RenderPassDrawQuad* render_pass_quad =
843 RenderPassDrawQuad::MaterialCast(current_quad);
844 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
845 continue;
[email protected]94f206c12012-08-25 00:09:14846
[email protected]c1bb5af2013-03-13 19:06:27847 // We are changing the vector in the middle of iteration. Because we
848 // delete render passes that draw into the current pass, we are
849 // guaranteed that any data from the iterator to the end will not
850 // change. So, capture the iterator position from the end of the
851 // list, and restore it after the change.
852 size_t position_from_end = frame->render_passes.size() - it;
853 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
854 it = frame->render_passes.size() - position_from_end;
855 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14856 }
[email protected]c1bb5af2013-03-13 19:06:27857 }
[email protected]94f206c12012-08-25 00:09:14858}
859
[email protected]e0341352013-04-06 05:01:20860bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
861 gfx::Rect device_viewport_damage_rect) {
[email protected]c1bb5af2013-03-13 19:06:27862 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14863
[email protected]c1bb5af2013-03-13 19:06:27864 active_tree_->UpdateDrawProperties(
865 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27866
[email protected]c1bb5af2013-03-13 19:06:27867 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
868 frame->render_passes.clear();
869 frame->render_passes_by_id.clear();
870 frame->will_draw_layers.clear();
[email protected]e0341352013-04-06 05:01:20871 frame->contains_incomplete_tile = false;
872 frame->has_no_damage = false;
873
874 if (active_tree_->root_layer()) {
[email protected]878705be2013-04-15 22:44:02875 device_viewport_damage_rect.Union(viewport_damage_rect_);
876 viewport_damage_rect_ = gfx::Rect();
[email protected]e0341352013-04-06 05:01:20877
878 active_tree_->root_layer()->render_surface()->damage_tracker()->
879 AddDamageNextUpdate(device_viewport_damage_rect);
880 }
[email protected]94f206c12012-08-25 00:09:14881
[email protected]c1bb5af2013-03-13 19:06:27882 if (!CalculateRenderPasses(frame))
883 return false;
[email protected]94f206c12012-08-25 00:09:14884
[email protected]e4c3c87a2013-04-22 02:28:40885 frame->latency_info = active_tree_->GetLatencyInfo();
886
[email protected]c1bb5af2013-03-13 19:06:27887 // If we return true, then we expect DrawLayers() to be called before this
888 // function is called again.
889 return true;
[email protected]94f206c12012-08-25 00:09:14890}
891
[email protected]c1bb5af2013-03-13 19:06:27892void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
893 const ManagedMemoryPolicy& policy) {
894 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
[email protected]46b8acc2013-03-19 22:38:35895 visible_ ? policy.bytes_limit_when_visible
896 : policy.bytes_limit_when_not_visible,
897 ManagedMemoryPolicy::PriorityCutoffToValue(
898 visible_ ? policy.priority_cutoff_when_visible
899 : policy.priority_cutoff_when_not_visible));
[email protected]c1bb5af2013-03-13 19:06:27900 if (evicted_resources) {
901 active_tree_->SetContentsTexturesPurged();
902 if (pending_tree_)
903 pending_tree_->SetContentsTexturesPurged();
904 client_->SetNeedsCommitOnImplThread();
905 client_->OnCanDrawStateChanged(CanDraw());
906 client_->RenewTreePriority();
907 }
908 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43909
[email protected]c1bb5af2013-03-13 19:06:27910 if (tile_manager_) {
911 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
912 new_state.memory_limit_in_bytes = visible_ ?
[email protected]46b8acc2013-03-19 22:38:35913 policy.bytes_limit_when_visible :
914 policy.bytes_limit_when_not_visible;
[email protected]41124c52013-03-28 23:26:57915 // TODO(reveman): We should avoid keeping around unused resources if
916 // possible. crbug.com/224475
[email protected]9d52c1c32013-04-09 19:11:36917 new_state.unused_memory_limit_in_bytes = static_cast<size_t>(
918 (static_cast<int64>(new_state.memory_limit_in_bytes) *
919 settings_.max_unused_resource_memory_percentage) / 100);
[email protected]c1bb5af2013-03-13 19:06:27920 new_state.memory_limit_policy =
[email protected]46b8acc2013-03-19 22:38:35921 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
[email protected]c1bb5af2013-03-13 19:06:27922 visible_ ?
[email protected]46b8acc2013-03-19 22:38:35923 policy.priority_cutoff_when_visible :
924 policy.priority_cutoff_when_not_visible);
[email protected]c1bb5af2013-03-13 19:06:27925 tile_manager_->SetGlobalState(new_state);
926 }
[email protected]94f206c12012-08-25 00:09:14927}
928
[email protected]c1bb5af2013-03-13 19:06:27929bool LayerTreeHostImpl::HasImplThread() const {
930 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44931}
932
[email protected]c1bb5af2013-03-13 19:06:27933void LayerTreeHostImpl::ScheduleManageTiles() {
934 if (client_)
935 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43936}
937
[email protected]86126792013-03-16 20:07:54938void LayerTreeHostImpl::DidInitializeVisibleTile() {
939 // TODO(reveman): Determine tiles that changed and only damage
940 // what's necessary.
941 SetFullRootLayerDamage();
[email protected]c1bb5af2013-03-13 19:06:27942 if (client_)
[email protected]86126792013-03-16 20:07:54943 client_->DidInitializeVisibleTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47944}
945
[email protected]c1bb5af2013-03-13 19:06:27946bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
[email protected]8e0176d2013-03-21 03:14:52947 return settings_.should_clear_root_render_pass;
[email protected]f35e2322012-12-15 21:45:52948}
949
[email protected]c1bb5af2013-03-13 19:06:27950void LayerTreeHostImpl::SetManagedMemoryPolicy(
951 const ManagedMemoryPolicy& policy) {
952 if (managed_memory_policy_ == policy)
953 return;
[email protected]61de5812012-11-08 07:03:44954
[email protected]d7626ffd2013-03-29 00:17:42955 // If there is already enough memory to draw everything imaginable and the
956 // new memory limit does not change this, then do not re-commit. Don't bother
957 // skipping commits if this is not visible (commits don't happen when not
958 // visible, there will almost always be a commit when this becomes visible).
959 bool needs_commit = true;
960 if (visible() &&
961 policy.bytes_limit_when_visible >=
962 max_memory_needed_bytes_ &&
963 managed_memory_policy_.bytes_limit_when_visible >=
964 max_memory_needed_bytes_ &&
965 policy.priority_cutoff_when_visible ==
966 managed_memory_policy_.priority_cutoff_when_visible) {
967 needs_commit = false;
968 }
969
[email protected]c1bb5af2013-03-13 19:06:27970 managed_memory_policy_ = policy;
971 if (!proxy_->HasImplThread()) {
[email protected]d7626ffd2013-03-29 00:17:42972 // In single-thread mode, this can be called on the main thread by
973 // GLRenderer::OnMemoryAllocationChanged.
[email protected]c1bb5af2013-03-13 19:06:27974 DebugScopedSetImplThread impl_thread(proxy_);
975 EnforceManagedMemoryPolicy(managed_memory_policy_);
976 } else {
977 DCHECK(proxy_->IsImplThread());
978 EnforceManagedMemoryPolicy(managed_memory_policy_);
979 }
[email protected]d7626ffd2013-03-29 00:17:42980
981 if (needs_commit)
982 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:14983}
984
[email protected]c1bb5af2013-03-13 19:06:27985void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
986 base::TimeDelta interval) {
987 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14988}
989
[email protected]7ed47512013-03-26 22:28:45990void LayerTreeHostImpl::DidVSync(base::TimeTicks frame_time) {
991 client_->DidVSync(frame_time);
992}
993
[email protected]c1bb5af2013-03-13 19:06:27994void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
995 const CompositorFrameAck& ack) {
996 if (!renderer_)
997 return;
[email protected]b6f3d7e2012-12-08 00:11:21998
[email protected]c1bb5af2013-03-13 19:06:27999 // TODO(piman): We may need to do some validation on this ack before
1000 // processing it.
1001 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]bb1e2822013-04-17 22:06:011002
1003 // When using compositor frame data, the ack doubles as a swap complete ack.
1004 OnSwapBuffersComplete();
[email protected]a46f32932012-12-07 21:43:161005}
1006
[email protected]c1bb5af2013-03-13 19:06:271007void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
1008 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:291009}
1010
[email protected]c1bb5af2013-03-13 19:06:271011CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
1012 CompositorFrameMetadata metadata;
1013 metadata.device_scale_factor = device_scale_factor_;
1014 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
1015 metadata.viewport_size = active_tree_->ScrollableViewportSize();
1016 metadata.root_layer_size = active_tree_->ScrollableSize();
1017 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
1018 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
1019 if (top_controls_manager_) {
1020 metadata.location_bar_offset =
1021 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
1022 metadata.location_bar_content_translation =
1023 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
[email protected]5a54b2822013-03-26 10:00:011024 metadata.overdraw_bottom_height = overdraw_bottom_height_;
[email protected]c1bb5af2013-03-13 19:06:271025 }
[email protected]bf189f62012-12-18 03:42:111026
[email protected]c1bb5af2013-03-13 19:06:271027 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:111028 return metadata;
[email protected]c1bb5af2013-03-13 19:06:271029
[email protected]ffb2720f2013-03-15 19:18:371030 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
[email protected]e4c3c87a2013-04-22 02:28:401031 metadata.latency_info = active_tree_->GetLatencyInfo();
[email protected]c1bb5af2013-03-13 19:06:271032
1033 return metadata;
[email protected]bf189f62012-12-18 03:42:111034}
1035
[email protected]73673592013-04-03 22:14:321036bool LayerTreeHostImpl::AllowPartialSwap() const {
1037 // We don't track damage on the HUD layer (it interacts with damage tracking
1038 // visualizations), so disable partial swaps to make the HUD layer display
1039 // properly.
1040 return !debug_state_.ShowHudRects();
1041}
1042
[email protected]f0c2a242013-03-15 19:34:521043void LayerTreeHostImpl::DrawLayers(FrameData* frame,
1044 base::TimeTicks frame_begin_time) {
[email protected]c1bb5af2013-03-13 19:06:271045 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
1046 DCHECK(CanDraw());
[email protected]e0341352013-04-06 05:01:201047
1048 if (frame->has_no_damage)
1049 return;
1050
[email protected]c1bb5af2013-03-13 19:06:271051 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:141052
[email protected]9e3594522013-03-18 00:57:361053 fps_counter_->SaveTimeStamp(frame_begin_time);
[email protected]94f206c12012-08-25 00:09:141054
[email protected]372bad5f2013-03-21 16:38:431055 rendering_stats_instrumentation_->SetScreenFrameCount(
1056 fps_counter_->current_frame_number());
1057 rendering_stats_instrumentation_->SetDroppedFrameCount(
1058 fps_counter_->dropped_frame_count());
1059
[email protected]c1bb5af2013-03-13 19:06:271060 if (tile_manager_) {
1061 memory_history_->SaveEntry(
1062 tile_manager_->memory_stats_from_last_assign());
1063 }
[email protected]1191d9d2013-02-02 06:00:331064
[email protected]846f455b2013-03-18 19:07:411065 if (debug_state_.ShowHudRects()) {
[email protected]d35992782013-03-14 14:54:021066 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:271067 active_tree_->root_layer(),
1068 *frame->render_surface_layer_list,
1069 frame->occluding_screen_space_rects,
1070 frame->non_occluding_screen_space_rects,
1071 debug_state_);
1072 }
[email protected]94f206c12012-08-25 00:09:141073
[email protected]a848c102013-03-26 08:59:091074 if (!settings_.impl_side_painting && debug_state_.continuous_painting) {
1075 const RenderingStats& stats =
1076 rendering_stats_instrumentation_->GetRenderingStats();
1077 paint_time_counter_->SavePaintTime(stats.total_paint_time);
1078 }
1079
[email protected]846f455b2013-03-18 19:07:411080 if (debug_state_.trace_all_rendered_frames) {
[email protected]c76faea2013-03-26 07:42:421081 TRACE_EVENT_INSTANT1("cc.debug", "Frame", TRACE_EVENT_SCOPE_THREAD,
[email protected]c1bb5af2013-03-13 19:06:271082 "frame", ValueToString(FrameStateAsValue()));
1083 }
[email protected]131a0c22013-02-12 18:31:081084
[email protected]c1bb5af2013-03-13 19:06:271085 // Because the contents of the HUD depend on everything else in the frame, the
1086 // contents of its texture are updated as the last thing before the frame is
1087 // drawn.
1088 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:541089 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:141090
[email protected]d002dd02013-03-27 07:40:401091 renderer_->DrawFrame(&frame->render_passes);
[email protected]c1bb5af2013-03-13 19:06:271092 // The render passes should be consumed by the renderer.
1093 DCHECK(frame->render_passes.empty());
1094 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:141095
[email protected]c1bb5af2013-03-13 19:06:271096 // The next frame should start by assuming nothing has changed, and changes
1097 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:541098 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:271099 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
1100 DidDrawDamagedArea();
1101 }
1102 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:141103}
1104
[email protected]c1bb5af2013-03-13 19:06:271105void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
1106 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
1107 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:521108
[email protected]c1bb5af2013-03-13 19:06:271109 // Once all layers have been drawn, pending texture uploads should no
1110 // longer block future uploads.
1111 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:141112}
1113
[email protected]c1bb5af2013-03-13 19:06:271114void LayerTreeHostImpl::FinishAllRendering() {
1115 if (renderer_)
1116 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:141117}
1118
[email protected]c1bb5af2013-03-13 19:06:271119bool LayerTreeHostImpl::IsContextLost() {
1120 DCHECK(proxy_->IsImplThread());
1121 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141122}
1123
[email protected]c1bb5af2013-03-13 19:06:271124const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1125 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141126}
1127
[email protected]e0341352013-04-06 05:01:201128bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
1129 if (frame.has_no_damage)
1130 return false;
[email protected]e4c3c87a2013-04-22 02:28:401131 bool result = renderer_->SwapBuffers(frame.latency_info);
1132 if (result)
1133 active_tree_->ClearLatencyInfo();
1134 return result;
[email protected]94f206c12012-08-25 00:09:141135}
1136
[email protected]7ed47512013-03-26 22:28:451137void LayerTreeHostImpl::EnableVSyncNotification(bool enable) {
1138 if (output_surface_)
1139 output_surface_->EnableVSyncNotification(enable);
1140}
1141
[email protected]c1bb5af2013-03-13 19:06:271142gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1143 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101144}
1145
[email protected]ffb2720f2013-03-15 19:18:371146gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1147 gfx::SizeF dip_size =
1148 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1149
1150 // The clip layer should be used if non-overlay scrollbars may exist since
1151 // it adjusts for them.
1152 LayerImpl* clip_layer = active_tree_->RootClipLayer();
[email protected]8e0176d2013-03-21 03:14:521153 if (!Settings().solid_color_scrollbars && clip_layer &&
[email protected]ffb2720f2013-03-15 19:18:371154 clip_layer->masks_to_bounds())
1155 dip_size = clip_layer->bounds();
1156
[email protected]ed511b8d2013-03-25 03:29:291157 float top_offset =
[email protected]ffb2720f2013-03-15 19:18:371158 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
[email protected]d9083762013-03-24 01:36:401159 return gfx::SizeF(dip_size.width(),
[email protected]ed511b8d2013-03-25 03:29:291160 dip_size.height() - top_offset - overdraw_bottom_height_);
[email protected]ffb2720f2013-03-15 19:18:371161}
1162
[email protected]c1bb5af2013-03-13 19:06:271163const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1164 return settings();
[email protected]493067512012-09-19 23:34:101165}
1166
[email protected]c1bb5af2013-03-13 19:06:271167void LayerTreeHostImpl::DidLoseOutputSurface() {
[email protected]bb1e2822013-04-17 22:06:011168 // TODO(jamesr): The renderer_ check is needed to make some of the
1169 // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or
1170 // important) in production. We should adjust the test to not need this.
1171 if (renderer_)
1172 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141173}
1174
[email protected]c1bb5af2013-03-13 19:06:271175void LayerTreeHostImpl::OnSwapBuffersComplete() {
1176 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141177}
1178
[email protected]c1bb5af2013-03-13 19:06:271179void LayerTreeHostImpl::Readback(void* pixels,
1180 gfx::Rect rect_in_device_viewport) {
1181 DCHECK(renderer_);
1182 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141183}
1184
[email protected]59adb112013-04-09 04:48:441185bool LayerTreeHostImpl::HaveRootScrollLayer() const {
[email protected]3209161d2013-03-29 19:17:341186 return !!RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011187}
1188
[email protected]c1bb5af2013-03-13 19:06:271189LayerImpl* LayerTreeHostImpl::RootLayer() const {
1190 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081191}
1192
[email protected]c1bb5af2013-03-13 19:06:271193LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1194 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081195}
1196
[email protected]c1bb5af2013-03-13 19:06:271197LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1198 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081199}
1200
[email protected]94f206c12012-08-25 00:09:141201// Content layers can be either directly scrollable or contained in an outer
1202// scrolling layer which applies the scroll transform. Given a content layer,
1203// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271204static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1205 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141206 return 0;
[email protected]c1bb5af2013-03-13 19:06:271207
1208 if (layer_impl->scrollable())
1209 return layer_impl;
1210
1211 if (layer_impl->DrawsContent() &&
1212 layer_impl->parent() &&
1213 layer_impl->parent()->scrollable())
1214 return layer_impl->parent();
1215
1216 return 0;
[email protected]94f206c12012-08-25 00:09:141217}
1218
[email protected]c1bb5af2013-03-13 19:06:271219void LayerTreeHostImpl::CreatePendingTree() {
1220 CHECK(!pending_tree_);
1221 if (recycle_tree_)
1222 recycle_tree_.swap(pending_tree_);
1223 else
1224 pending_tree_ = LayerTreeImpl::create(this);
1225 client_->OnCanDrawStateChanged(CanDraw());
1226 client_->OnHasPendingTreeStateChanged(pending_tree_);
1227 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1228 TRACE_EVENT_ASYNC_STEP0("cc",
1229 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271230}
1231
[email protected]c1bb5af2013-03-13 19:06:271232void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1233 DCHECK(!client_->IsInsideDraw()) <<
1234 "Checking for completed uploads within a draw may trigger "
1235 "spurious redraws.";
1236 if (tile_manager_)
1237 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481238}
1239
[email protected]c1bb5af2013-03-13 19:06:271240bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1241 if (!pending_tree_)
1242 return false;
[email protected]2e7ca422012-12-20 02:57:271243
[email protected]c1bb5af2013-03-13 19:06:271244 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091245
[email protected]c1bb5af2013-03-13 19:06:271246 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161247
[email protected]c1bb5af2013-03-13 19:06:271248 TRACE_EVENT_ASYNC_STEP1("cc",
1249 "PendingTree", pending_tree_.get(), "activate",
1250 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271251
[email protected]8ca1e6c2013-04-02 03:49:261252 // Activate once all visible resources in pending tree are ready.
1253 if (!pending_tree_->AreVisibleResourcesReady())
1254 return false;
[email protected]2e7ca422012-12-20 02:57:271255
[email protected]c1bb5af2013-03-13 19:06:271256 ActivatePendingTree();
1257 return true;
[email protected]2e7ca422012-12-20 02:57:271258}
1259
[email protected]c1bb5af2013-03-13 19:06:271260void LayerTreeHostImpl::ActivatePendingTree() {
1261 CHECK(pending_tree_);
1262 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351263
[email protected]c1bb5af2013-03-13 19:06:271264 active_tree_->PushPersistedState(pending_tree_.get());
1265 if (pending_tree_->needs_full_tree_sync()) {
1266 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331267 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271268 active_tree_->DetachLayerTree(),
1269 active_tree_.get()));
1270 }
[email protected]b5651c22013-03-14 15:06:331271 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271272 active_tree_->root_layer());
1273 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511274
[email protected]c1bb5af2013-03-13 19:06:271275 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511276
[email protected]c1bb5af2013-03-13 19:06:271277 // Now that we've synced everything from the pending tree to the active
1278 // tree, rename the pending tree the recycle tree so we can reuse it on the
1279 // next sync.
1280 pending_tree_.swap(recycle_tree_);
1281 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511282
[email protected]c1bb5af2013-03-13 19:06:271283 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221284
[email protected]c1bb5af2013-03-13 19:06:271285 // Reduce wasted memory now that unlinked resources are guaranteed not
1286 // to be used.
1287 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411288
[email protected]c1bb5af2013-03-13 19:06:271289 client_->OnCanDrawStateChanged(CanDraw());
1290 client_->OnHasPendingTreeStateChanged(pending_tree_);
1291 client_->SetNeedsRedrawOnImplThread();
1292 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241293
[email protected]a848c102013-03-26 08:59:091294 if (debug_state_.continuous_painting) {
1295 const RenderingStats& stats =
[email protected]372bad5f2013-03-21 16:38:431296 rendering_stats_instrumentation_->GetRenderingStats();
[email protected]a848c102013-03-26 08:59:091297 paint_time_counter_->SavePaintTime(
1298 stats.total_paint_time +
1299 stats.total_rasterize_time_for_now_bins_on_pending_tree);
[email protected]c1bb5af2013-03-13 19:06:271300 }
[email protected]2e7ca422012-12-20 02:57:271301}
1302
[email protected]c1bb5af2013-03-13 19:06:271303void LayerTreeHostImpl::SetVisible(bool visible) {
1304 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141305
[email protected]c1bb5af2013-03-13 19:06:271306 if (visible_ == visible)
1307 return;
1308 visible_ = visible;
1309 DidVisibilityChange(this, visible_);
1310 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141311
[email protected]c1bb5af2013-03-13 19:06:271312 if (!renderer_)
1313 return;
[email protected]94f206c12012-08-25 00:09:141314
[email protected]c1bb5af2013-03-13 19:06:271315 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141316}
1317
[email protected]c1bb5af2013-03-13 19:06:271318bool LayerTreeHostImpl::InitializeRenderer(
1319 scoped_ptr<OutputSurface> output_surface) {
1320 // Since we will create a new resource provider, we cannot continue to use
1321 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1322 // before we destroy the old resource provider.
1323 if (active_tree_->root_layer())
1324 ClearRenderSurfaces();
1325 if (active_tree_->root_layer())
1326 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1327 if (pending_tree_ && pending_tree_->root_layer())
1328 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1329 if (recycle_tree_ && recycle_tree_->root_layer())
1330 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]7ba3ca72013-04-11 06:37:251331 if (resource_provider_)
1332 resource_provider_->DidLoseOutputSurface();
[email protected]45c4b1e2013-01-16 02:19:401333
[email protected]c1bb5af2013-03-13 19:06:271334 // Note: order is important here.
1335 renderer_.reset();
1336 tile_manager_.reset();
1337 resource_provider_.reset();
1338 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141339
[email protected]c1bb5af2013-03-13 19:06:271340 if (!output_surface->BindToClient(this))
1341 return false;
[email protected]be3181652012-09-25 13:02:131342
[email protected]075d8aa2013-04-01 23:03:111343 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1344 output_surface.get(), settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271345 if (!resource_provider)
1346 return false;
[email protected]be3181652012-09-25 13:02:131347
[email protected]8e0176d2013-03-21 03:14:521348 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:271349 tile_manager_.reset(new TileManager(this,
1350 resource_provider.get(),
[email protected]8e0176d2013-03-21 03:14:521351 settings_.num_raster_threads,
1352 settings_.use_cheapness_estimator,
1353 settings_.use_color_estimator,
[email protected]372bad5f2013-03-21 16:38:431354 settings_.prediction_benchmarking,
1355 rendering_stats_instrumentation_));
[email protected]c1bb5af2013-03-13 19:06:271356 }
[email protected]8947cbe2012-11-28 05:27:431357
[email protected]c1bb5af2013-03-13 19:06:271358 if (output_surface->capabilities().has_parent_compositor) {
1359 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1360 resource_provider.get());
1361 } else if (output_surface->context3d()) {
1362 renderer_ = GLRenderer::Create(this,
1363 output_surface.get(),
[email protected]075d8aa2013-04-01 23:03:111364 resource_provider.get(),
1365 settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271366 } else if (output_surface->software_device()) {
1367 renderer_ = SoftwareRenderer::Create(this,
1368 output_surface.get(),
1369 resource_provider.get());
1370 }
1371 if (!renderer_)
1372 return false;
[email protected]be3181652012-09-25 13:02:131373
[email protected]c1bb5af2013-03-13 19:06:271374 resource_provider_ = resource_provider.Pass();
1375 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141376
[email protected]c1bb5af2013-03-13 19:06:271377 if (!visible_)
1378 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141379
[email protected]c1bb5af2013-03-13 19:06:271380 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211381
[email protected]c1bb5af2013-03-13 19:06:271382 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1383 // to be initialized to get max texture size.
1384 active_tree_->set_needs_update_draw_properties();
1385 if (pending_tree_)
1386 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161387
[email protected]c1bb5af2013-03-13 19:06:271388 return true;
[email protected]94f206c12012-08-25 00:09:141389}
1390
[email protected]18ce59702013-04-09 04:58:401391void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) {
1392 if (device_viewport_size == device_viewport_size_)
[email protected]c1bb5af2013-03-13 19:06:271393 return;
[email protected]94f206c12012-08-25 00:09:141394
[email protected]c1bb5af2013-03-13 19:06:271395 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1396 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271397
[email protected]c1bb5af2013-03-13 19:06:271398 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141399
[email protected]c1bb5af2013-03-13 19:06:271400 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141401
[email protected]c1bb5af2013-03-13 19:06:271402 if (renderer_)
1403 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211404
[email protected]c1bb5af2013-03-13 19:06:271405 client_->OnCanDrawStateChanged(CanDraw());
[email protected]59adb112013-04-09 04:48:441406 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141407}
1408
[email protected]d9083762013-03-24 01:36:401409void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) {
1410 if (overdraw_bottom_height == overdraw_bottom_height_)
1411 return;
1412 overdraw_bottom_height_ = overdraw_bottom_height;
1413
1414 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441415 SetFullRootLayerDamage();
[email protected]d9083762013-03-24 01:36:401416}
1417
[email protected]c1bb5af2013-03-13 19:06:271418void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1419 if (device_scale_factor == device_scale_factor_)
1420 return;
1421 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271422
[email protected]c1bb5af2013-03-13 19:06:271423 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441424 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141425}
1426
[email protected]c1bb5af2013-03-13 19:06:271427void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1428 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141429}
1430
[email protected]59adb112013-04-09 04:48:441431void LayerTreeHostImpl::DidChangeTopControlsPosition() {
[email protected]c1bb5af2013-03-13 19:06:271432 client_->SetNeedsRedrawOnImplThread();
[email protected]59adb112013-04-09 04:48:441433 active_tree_->set_needs_update_draw_properties();
1434 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141435}
1436
[email protected]c1bb5af2013-03-13 19:06:271437bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1438 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
[email protected]3209161d2013-03-29 19:17:341439 return !active_tree_->RenderSurfaceLayerList().empty();
[email protected]94f206c12012-08-25 00:09:141440}
1441
[email protected]c1bb5af2013-03-13 19:06:271442InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1443 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
[email protected]ed511b8d2013-03-25 03:29:291444 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
[email protected]94f206c12012-08-25 00:09:141445
[email protected]c1bb5af2013-03-13 19:06:271446 if (top_controls_manager_)
1447 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381448
[email protected]c1bb5af2013-03-13 19:06:271449 DCHECK(!CurrentlyScrollingLayer());
1450 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141451
[email protected]c1bb5af2013-03-13 19:06:271452 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141453 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141454
[email protected]c1bb5af2013-03-13 19:06:271455 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1456 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141457
[email protected]c1bb5af2013-03-13 19:06:271458 // First find out which layer was hit from the saved list of visible layers
1459 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:391460 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:271461 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521462
[email protected]c1bb5af2013-03-13 19:06:271463 // Walk up the hierarchy and look for a scrollable layer.
1464 LayerImpl* potentially_scrolling_layer_impl = 0;
1465 for (; layer_impl; layer_impl = layer_impl->parent()) {
1466 // The content layer can also block attempts to scroll outside the main
1467 // thread.
1468 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1469 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431470 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271471 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421472 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271473 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141474 }
1475
[email protected]c1bb5af2013-03-13 19:06:271476 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1477 if (!scroll_layer_impl)
1478 continue;
[email protected]94f206c12012-08-25 00:09:141479
[email protected]c1bb5af2013-03-13 19:06:271480 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141481
[email protected]c1bb5af2013-03-13 19:06:271482 // If any layer wants to divert the scroll event to the main thread, abort.
1483 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431484 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271485 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421486 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271487 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141488 }
1489
[email protected]c1bb5af2013-03-13 19:06:271490 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1491 potentially_scrolling_layer_impl = scroll_layer_impl;
1492 }
1493
1494 // When hiding top controls is enabled and the controls are hidden or
1495 // overlaying the content, force scrolls to be enabled on the root layer to
1496 // allow bringing the top controls back into view.
1497 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1498 top_controls_manager_->content_top_offset() !=
[email protected]8e0176d2013-03-21 03:14:521499 settings_.top_controls_height) {
[email protected]c1bb5af2013-03-13 19:06:271500 potentially_scrolling_layer_impl = RootScrollLayer();
1501 }
1502
1503 if (potentially_scrolling_layer_impl) {
[email protected]0fc818e2013-03-18 06:45:201504 active_tree_->SetCurrentlyScrollingLayer(
[email protected]c1bb5af2013-03-13 19:06:271505 potentially_scrolling_layer_impl);
1506 should_bubble_scrolls_ = (type != NonBubblingGesture);
1507 wheel_scrolling_ = (type == Wheel);
[email protected]372bad5f2013-03-21 16:38:431508 rendering_stats_instrumentation_->IncrementImplThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271509 client_->RenewTreePriority();
1510 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421511 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271512 return ScrollStarted;
1513 }
1514 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141515}
1516
[email protected]c1bb5af2013-03-13 19:06:271517gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1518 LayerImpl* layer_impl,
1519 float scale_from_viewport_to_screen_space,
1520 gfx::PointF viewport_point,
1521 gfx::Vector2dF viewport_delta) {
1522 // Layers with non-invertible screen space transforms should not have passed
1523 // the scroll hit test in the first place.
1524 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1525 gfx::Transform inverse_screen_space_transform(
1526 gfx::Transform::kSkipInitialization);
1527 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1528 &inverse_screen_space_transform);
[email protected]ca2902e92013-03-28 01:45:351529 // TODO(shawnsingh): With the advent of impl-side crolling for non-root
1530 // layers, we may need to explicitly handle uninvertible transforms here.
[email protected]c1bb5af2013-03-13 19:06:271531 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141532
[email protected]c1bb5af2013-03-13 19:06:271533 gfx::PointF screen_space_point =
1534 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141535
[email protected]c1bb5af2013-03-13 19:06:271536 gfx::Vector2dF screen_space_delta = viewport_delta;
1537 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1538
1539 // First project the scroll start and end points to local layer space to find
1540 // the scroll delta in layer coordinates.
1541 bool start_clipped, end_clipped;
1542 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1543 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211544 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271545 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211546 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271547 gfx::PointF local_end_point =
[email protected]fa816c62013-03-18 04:24:211548 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271549 screen_space_end_point,
[email protected]fa816c62013-03-18 04:24:211550 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271551
1552 // In general scroll point coordinates should not get clipped.
1553 DCHECK(!start_clipped);
1554 DCHECK(!end_clipped);
1555 if (start_clipped || end_clipped)
1556 return gfx::Vector2dF();
1557
1558 // local_start_point and local_end_point are in content space but we want to
1559 // move them to layer space for scrolling.
1560 float width_scale = 1.f / layer_impl->contents_scale_x();
1561 float height_scale = 1.f / layer_impl->contents_scale_y();
1562 local_start_point.Scale(width_scale, height_scale);
1563 local_end_point.Scale(width_scale, height_scale);
1564
1565 // Apply the scroll delta.
1566 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1567 layer_impl->ScrollBy(local_end_point - local_start_point);
1568
1569 // Get the end point in the layer's content space so we can apply its
1570 // ScreenSpaceTransform.
1571 gfx::PointF actual_local_end_point = local_start_point +
1572 layer_impl->scroll_delta() -
1573 previous_delta;
1574 gfx::PointF actual_local_content_end_point =
1575 gfx::ScalePoint(actual_local_end_point,
1576 1.f / width_scale,
1577 1.f / height_scale);
1578
1579 // Calculate the applied scroll delta in viewport space coordinates.
1580 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211581 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271582 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211583 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271584 DCHECK(!end_clipped);
1585 if (end_clipped)
1586 return gfx::Vector2dF();
1587 gfx::PointF actual_viewport_end_point =
1588 gfx::ScalePoint(actual_screen_space_end_point,
1589 1.f / scale_from_viewport_to_screen_space);
1590 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141591}
1592
[email protected]c1bb5af2013-03-13 19:06:271593static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1594 gfx::Vector2dF local_delta) {
1595 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1596 layer_impl->ScrollBy(local_delta);
1597 return layer_impl->scroll_delta() - previous_delta;
1598}
1599
1600bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1601 gfx::Vector2dF scroll_delta) {
1602 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1603 if (!CurrentlyScrollingLayer())
1604 return false;
1605
1606 gfx::Vector2dF pending_delta = scroll_delta;
1607 bool did_scroll = false;
[email protected]60b4d252013-03-23 18:49:421608 bool consume_by_top_controls = top_controls_manager_ &&
1609 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0);
[email protected]a91e4f82013-03-15 06:58:061610
[email protected]c1bb5af2013-03-13 19:06:271611 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1612 layer_impl;
1613 layer_impl = layer_impl->parent()) {
1614 if (!layer_impl->scrollable())
1615 continue;
1616
[email protected]60b4d252013-03-23 18:49:421617 // Only allow bubble scrolling when the scroll is in the direction to make
1618 // the top controls visible.
1619 if (consume_by_top_controls && layer_impl == RootScrollLayer()) {
1620 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
1621 UpdateMaxScrollOffset();
1622 }
1623
[email protected]c1bb5af2013-03-13 19:06:271624 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271625 // Gesture events need to be transformed from viewport coordinates to local
1626 // layer coordinates so that the scrolling contents exactly follow the
1627 // user's finger. In contrast, wheel events represent a fixed amount of
1628 // scrolling so we can just apply them directly.
1629 if (!wheel_scrolling_) {
1630 float scale_from_viewport_to_screen_space = device_scale_factor_;
1631 applied_delta =
1632 ScrollLayerWithViewportSpaceDelta(layer_impl,
1633 scale_from_viewport_to_screen_space,
1634 viewport_point, pending_delta);
1635 } else {
1636 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141637 }
[email protected]94f206c12012-08-25 00:09:141638
[email protected]c1bb5af2013-03-13 19:06:271639 // If the layer wasn't able to move, try the next one in the hierarchy.
1640 float move_threshold_squared = 0.1f * 0.1f;
1641 if (applied_delta.LengthSquared() < move_threshold_squared) {
1642 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1643 continue;
1644 else
1645 break;
[email protected]94f206c12012-08-25 00:09:141646 }
[email protected]c1bb5af2013-03-13 19:06:271647 did_scroll = true;
1648 did_lock_scrolling_layer_ = true;
1649 if (!should_bubble_scrolls_) {
[email protected]0fc818e2013-03-18 06:45:201650 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
[email protected]c1bb5af2013-03-13 19:06:271651 break;
[email protected]94f206c12012-08-25 00:09:141652 }
[email protected]94f206c12012-08-25 00:09:141653
[email protected]c1bb5af2013-03-13 19:06:271654 // If the applied delta is within 45 degrees of the input delta, bail out to
1655 // make it easier to scroll just one layer in one direction without
1656 // affecting any of its parents.
1657 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211658 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271659 applied_delta, pending_delta) < angle_threshold) {
1660 pending_delta = gfx::Vector2d();
1661 break;
[email protected]4a23c374c2012-12-08 08:38:551662 }
[email protected]c1bb5af2013-03-13 19:06:271663
1664 // Allow further movement only on an axis perpendicular to the direction in
1665 // which the layer moved.
1666 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211667 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271668
1669 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1670 break;
1671 }
1672
[email protected]b7c4783f2013-03-15 23:11:421673 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271674 if (did_scroll) {
1675 client_->SetNeedsCommitOnImplThread();
1676 client_->SetNeedsRedrawOnImplThread();
1677 client_->RenewTreePriority();
1678 }
1679 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551680}
1681
[email protected]be782f52013-03-23 21:36:141682// This implements scrolling by page as described here:
1683// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel
1684// for events with WHEEL_PAGESCROLL set.
1685bool LayerTreeHostImpl::ScrollVerticallyByPage(
1686 gfx::Point viewport_point,
1687 WebKit::WebScrollbar::ScrollDirection direction) {
1688 DCHECK(wheel_scrolling_);
1689
1690 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1691 layer_impl;
1692 layer_impl = layer_impl->parent()) {
1693 if (!layer_impl->scrollable())
1694 continue;
1695
1696 if (!layer_impl->vertical_scrollbar_layer())
1697 continue;
1698
1699 float height = layer_impl->vertical_scrollbar_layer()->bounds().height();
1700
1701 // These magical values match WebKit and are designed to scroll nearly the
1702 // entire visible content height but leave a bit of overlap.
1703 float page = std::max(height * 0.875f, 1.f);
1704 if (direction == WebKit::WebScrollbar::ScrollBackward)
1705 page = -page;
1706
1707 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page);
1708
1709 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta);
1710
1711 if (!applied_delta.IsZero()) {
1712 active_tree()->DidUpdateScroll();
1713 client_->SetNeedsCommitOnImplThread();
1714 client_->SetNeedsRedrawOnImplThread();
1715 client_->RenewTreePriority();
1716 return true;
1717 }
1718
1719 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
1720 }
1721
1722 return false;
1723}
1724
[email protected]c1bb5af2013-03-13 19:06:271725void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1726 active_tree_->ClearCurrentlyScrollingLayer();
1727 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141728}
1729
[email protected]c1bb5af2013-03-13 19:06:271730void LayerTreeHostImpl::ScrollEnd() {
1731 if (top_controls_manager_)
1732 top_controls_manager_->ScrollEnd();
1733 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421734 active_tree()->DidEndScroll();
[email protected]fb7425a2013-04-22 16:28:551735 StartScrollbarAnimation(CurrentFrameTimeTicks());
[email protected]94f206c12012-08-25 00:09:141736}
1737
[email protected]c1bb5af2013-03-13 19:06:271738void LayerTreeHostImpl::PinchGestureBegin() {
1739 pinch_gesture_active_ = true;
1740 previous_pinch_anchor_ = gfx::Point();
1741 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141742}
1743
[email protected]c1bb5af2013-03-13 19:06:271744void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1745 gfx::Point anchor) {
1746 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281747
[email protected]c1bb5af2013-03-13 19:06:271748 if (!RootScrollLayer())
1749 return;
[email protected]d3afa112012-12-08 06:24:281750
[email protected]c1bb5af2013-03-13 19:06:271751 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1752 // position over the course of the magnify.
1753 float page_scale_delta = active_tree_->page_scale_delta();
1754 gfx::PointF previous_scale_anchor =
1755 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1756 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1757 page_scale_delta = active_tree_->page_scale_delta();
1758 gfx::PointF new_scale_anchor =
1759 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1760 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1761
1762 previous_pinch_anchor_ = anchor;
1763
1764 move.Scale(1 / active_tree_->page_scale_factor());
1765
1766 RootScrollLayer()->ScrollBy(move);
1767
[email protected]c1bb5af2013-03-13 19:06:271768 client_->SetNeedsCommitOnImplThread();
1769 client_->SetNeedsRedrawOnImplThread();
1770 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281771}
1772
[email protected]c1bb5af2013-03-13 19:06:271773void LayerTreeHostImpl::PinchGestureEnd() {
1774 pinch_gesture_active_ = false;
[email protected]c1bb5af2013-03-13 19:06:271775 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141776}
1777
[email protected]c1bb5af2013-03-13 19:06:271778static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1779 LayerImpl* layer_impl) {
1780 if (!layer_impl)
1781 return;
[email protected]94f206c12012-08-25 00:09:141782
[email protected]c1bb5af2013-03-13 19:06:271783 gfx::Vector2d scroll_delta =
1784 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1785 if (!scroll_delta.IsZero()) {
1786 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]6ba914122013-03-22 16:26:391787 scroll.layer_id = layer_impl->id();
1788 scroll.scroll_delta = scroll_delta;
[email protected]c1bb5af2013-03-13 19:06:271789 scroll_info->scrolls.push_back(scroll);
1790 layer_impl->SetSentScrollDelta(scroll_delta);
1791 }
[email protected]94f206c12012-08-25 00:09:141792
[email protected]c1bb5af2013-03-13 19:06:271793 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1794 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141795}
1796
[email protected]c1bb5af2013-03-13 19:06:271797scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1798 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301799
[email protected]c1bb5af2013-03-13 19:06:271800 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
[email protected]6ba914122013-03-22 16:26:391801 scroll_info->page_scale_delta = active_tree_->page_scale_delta();
1802 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
[email protected]362f1e8b2013-01-21 16:54:301803
[email protected]c1bb5af2013-03-13 19:06:271804 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301805}
1806
[email protected]c1bb5af2013-03-13 19:06:271807void LayerTreeHostImpl::SetFullRootLayerDamage() {
[email protected]878705be2013-04-15 22:44:021808 SetViewportDamage(gfx::Rect(device_viewport_size_));
[email protected]829ad972013-01-28 23:36:101809}
1810
[email protected]c1bb5af2013-03-13 19:06:271811void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1812 if (!page_scale_animation_ || !RootScrollLayer())
1813 return;
1814
1815 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1816 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1817 RootScrollLayer()->scroll_delta();
1818
1819 active_tree_->SetPageScaleDelta(
1820 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1821 active_tree_->page_scale_factor());
1822 gfx::Vector2dF next_scroll =
1823 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1824
1825 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1826 client_->SetNeedsRedrawOnImplThread();
1827
1828 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1829 page_scale_animation_.reset();
1830 client_->SetNeedsCommitOnImplThread();
1831 client_->RenewTreePriority();
1832 }
[email protected]829ad972013-01-28 23:36:101833}
1834
[email protected]ffb2720f2013-03-15 19:18:371835void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1836 if (!top_controls_manager_ || !RootScrollLayer())
1837 return;
1838 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1839 UpdateMaxScrollOffset();
1840 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1841 scroll, 1.f / active_tree_->total_page_scale_factor()));
1842}
1843
[email protected]c1bb5af2013-03-13 19:06:271844void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1845 base::Time wall_clock_time) {
[email protected]8e0176d2013-03-21 03:14:521846 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271847 animation_registrar_->active_animation_controllers().empty() ||
1848 !active_tree_->root_layer())
1849 return;
1850
1851 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1852
1853 last_animation_time_ = wall_clock_time;
1854 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1855
1856 AnimationRegistrar::AnimationControllerMap copy =
1857 animation_registrar_->active_animation_controllers();
1858 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1859 iter != copy.end();
1860 ++iter)
1861 (*iter).second->Animate(monotonic_seconds);
1862
1863 client_->SetNeedsRedrawOnImplThread();
[email protected]131a0c22013-02-12 18:31:081864}
1865
[email protected]3d9f7432013-04-06 00:35:181866void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
[email protected]8e0176d2013-03-21 03:14:521867 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271868 animation_registrar_->active_animation_controllers().empty() ||
1869 !active_tree_->root_layer())
1870 return;
1871
1872 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1873 scoped_ptr<AnimationEventsVector> events =
1874 make_scoped_ptr(new AnimationEventsVector);
1875 AnimationRegistrar::AnimationControllerMap copy =
1876 animation_registrar_->active_animation_controllers();
1877 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1878 iter != copy.end();
1879 ++iter)
[email protected]3d9f7432013-04-06 00:35:181880 (*iter).second->UpdateState(start_ready_animations, events.get());
[email protected]c1bb5af2013-03-13 19:06:271881
1882 if (!events->empty()) {
1883 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1884 last_animation_time_);
1885 }
[email protected]131a0c22013-02-12 18:31:081886}
1887
[email protected]c1bb5af2013-03-13 19:06:271888base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1889 return base::TimeDelta::FromSeconds(1);
1890}
1891
1892void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1893 DCHECK(current);
1894 current->DidLoseOutputSurface();
1895 if (current->mask_layer())
1896 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1897 if (current->replica_layer())
1898 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1899 for (size_t i = 0; i < current->children().size(); ++i)
1900 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1901}
1902
1903void LayerTreeHostImpl::ClearRenderSurfaces() {
1904 active_tree_->ClearRenderSurfaces();
1905 if (pending_tree_)
1906 pending_tree_->ClearRenderSurfaces();
1907}
1908
1909std::string LayerTreeHostImpl::LayerTreeAsText() const {
1910 std::string str;
1911 if (active_tree_->root_layer()) {
1912 str = active_tree_->root_layer()->LayerTreeAsText();
1913 str += "RenderSurfaces:\n";
1914 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1915 }
1916 return str;
1917}
1918
1919std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1920 std::string str;
1921 if (active_tree_->root_layer()) {
1922 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1923 base::JSONWriter::WriteWithOptions(
1924 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1925 }
1926 return str;
1927}
1928
1929void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1930 int indent,
1931 const LayerImpl* layer) const {
1932 if (layer->render_surface())
1933 layer->render_surface()->DumpSurface(str, indent);
1934
1935 for (size_t i = 0; i < layer->children().size(); ++i)
1936 DumpRenderSurfaces(str, indent, layer->children()[i]);
1937}
1938
1939int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:361940 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:271941}
1942
[email protected]c1bb5af2013-03-13 19:06:271943void LayerTreeHostImpl::SendManagedMemoryStats(
1944 size_t memory_visible_bytes,
1945 size_t memory_visible_and_nearby_bytes,
1946 size_t memory_use_bytes) {
1947 if (!renderer_)
1948 return;
1949
1950 // Round the numbers being sent up to the next 8MB, to throttle the rate
1951 // at which we spam the GPU process.
1952 static const size_t rounding_step = 8 * 1024 * 1024;
1953 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1954 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1955 rounding_step);
1956 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1957 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1958 last_sent_memory_visible_and_nearby_bytes_ ==
1959 memory_visible_and_nearby_bytes &&
1960 last_sent_memory_use_bytes_ == memory_use_bytes) {
1961 return;
1962 }
1963 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1964 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1965 last_sent_memory_use_bytes_ = memory_use_bytes;
1966
1967 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
1968 last_sent_memory_visible_and_nearby_bytes_,
1969 last_sent_memory_use_bytes_);
1970}
1971
1972void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
1973 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
1974}
1975
1976void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
1977 base::TimeTicks time) {
1978 if (!layer)
1979 return;
1980
1981 ScrollbarAnimationController* scrollbar_controller =
1982 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:351983 if (scrollbar_controller && scrollbar_controller->Animate(time)) {
[email protected]0fc818e2013-03-18 06:45:201984 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:421985 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
1986 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:271987 client_->SetNeedsRedrawOnImplThread();
[email protected]0fc818e2013-03-18 06:45:201988 }
[email protected]c1bb5af2013-03-13 19:06:271989
1990 for (size_t i = 0; i < layer->children().size(); ++i)
1991 AnimateScrollbarsRecursive(layer->children()[i], time);
1992}
1993
[email protected]0fc818e2013-03-18 06:45:201994void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time) {
1995 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
1996 StartScrollbarAnimationRecursive(RootLayer(), time);
1997}
1998
1999void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
2000 base::TimeTicks time) {
2001 if (!layer)
2002 return;
2003
2004 ScrollbarAnimationController* scrollbar_controller =
2005 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352006 if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
2007 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
[email protected]0fc818e2013-03-18 06:45:202008 if (delay > base::TimeDelta())
2009 client_->RequestScrollbarAnimationOnImplThread(delay);
[email protected]6bc09e82013-03-19 03:48:352010 else if (scrollbar_controller->Animate(time))
[email protected]0fc818e2013-03-18 06:45:202011 client_->SetNeedsRedrawOnImplThread();
2012 }
2013
2014 for (size_t i = 0; i < layer->children().size(); ++i)
2015 StartScrollbarAnimationRecursive(layer->children()[i], time);
2016}
2017
[email protected]c1bb5af2013-03-13 19:06:272018void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
2019 if (!tile_manager_)
2020 return;
2021
2022 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
2023 if (new_state.tree_priority == priority)
2024 return;
2025
2026 new_state.tree_priority = priority;
2027 tile_manager_->SetGlobalState(new_state);
2028}
2029
2030void LayerTreeHostImpl::BeginNextFrame() {
[email protected]fb7425a2013-04-22 16:28:552031 current_frame_timeticks_ = base::TimeTicks();
2032 current_frame_time_ = base::Time();
[email protected]c1bb5af2013-03-13 19:06:272033}
2034
[email protected]fb7425a2013-04-22 16:28:552035static void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) {
2036 if (ticks->is_null()) {
2037 DCHECK(now->is_null());
2038 *ticks = base::TimeTicks::Now();
2039 *now = base::Time::Now();
2040 }
2041}
2042
2043base::TimeTicks LayerTreeHostImpl::CurrentFrameTimeTicks() {
2044 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
2045 return current_frame_timeticks_;
2046}
2047
2048base::Time LayerTreeHostImpl::CurrentFrameTime() {
2049 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
[email protected]c1bb5af2013-03-13 19:06:272050 return current_frame_time_;
2051}
2052
2053scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
2054 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
2055 state->Set("activation_state", ActivationStateAsValue().release());
2056 state->Set("frame_state", FrameStateAsValue().release());
2057 return state.PassAs<base::Value>();
2058}
2059
2060scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
2061 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042062 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272063 state->SetBoolean("visible_resources_ready",
2064 pending_tree_->AreVisibleResourcesReady());
2065 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
2066 return state.PassAs<base::Value>();
2067}
2068
2069scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
2070 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042071 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272072 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:212073 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:272074 if (tile_manager_)
2075 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
2076 state->Set("active_tree", active_tree_->AsValue().release());
2077 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:082078}
2079
[email protected]b9dcf43a2013-01-09 00:15:292080// static
[email protected]c1bb5af2013-03-13 19:06:272081LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
2082 LayerImpl* layer) {
2083 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:292084 return NULL;
[email protected]c1bb5af2013-03-13 19:06:272085
2086 if (layer->DrawsContent())
2087 return layer;
2088
[email protected]50761e92013-03-29 20:51:282089 for (LayerImplList::const_iterator it = layer->children().begin();
[email protected]c1bb5af2013-03-13 19:06:272090 it != layer->children().end(); ++it) {
2091 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
2092 if (nccr)
2093 return nccr;
2094 }
2095
2096 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:292097}
2098
[email protected]c1bb5af2013-03-13 19:06:272099skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
2100 LayerTreeImpl* tree =
2101 pending_tree_ ? pending_tree_.get() : active_tree_.get();
2102 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
2103 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:292104}
2105
[email protected]c1bb5af2013-03-13 19:06:272106void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
[email protected]846f455b2013-03-18 19:07:412107 if (debug_state_.continuous_painting != debug_state.continuous_painting)
[email protected]c1bb5af2013-03-13 19:06:272108 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:242109
[email protected]c1bb5af2013-03-13 19:06:272110 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:022111}
2112
[email protected]d3143c732012-10-05 19:17:592113} // namespace cc