blob: 7152fcbb5f7bb94c98e6a163deeb4eef3d01d7d2 [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();
114 layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now());
[email protected]3d9f7432013-04-06 00:35:18115 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
116 bool start_ready_animations = true;
117 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]c1bb5af2013-03-13 19:06:27118 layer_tree_host_impl_->BeginNextFrame();
119 }
[email protected]373974232013-01-10 22:20:50120
[email protected]c1bb5af2013-03-13 19:06:27121 void SetActive(bool active) {
[email protected]6d0e69d2013-03-20 14:53:26122 if (active != time_source_->Active())
123 time_source_->SetActive(active);
[email protected]c1bb5af2013-03-13 19:06:27124 }
[email protected]94f206c12012-08-25 00:09:14125
[email protected]c1bb5af2013-03-13 19:06:27126 private:
127 LayerTreeHostImplTimeSourceAdapter(
128 LayerTreeHostImpl* layer_tree_host_impl,
129 scoped_refptr<DelayBasedTimeSource> time_source)
130 : layer_tree_host_impl_(layer_tree_host_impl),
131 time_source_(time_source) {
[email protected]6d0e69d2013-03-20 14:53:26132 time_source_->SetClient(this);
[email protected]c1bb5af2013-03-13 19:06:27133 }
[email protected]94f206c12012-08-25 00:09:14134
[email protected]c1bb5af2013-03-13 19:06:27135 LayerTreeHostImpl* layer_tree_host_impl_;
136 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14137
[email protected]c1bb5af2013-03-13 19:06:27138 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14139};
140
[email protected]96baf3e2012-10-22 23:09:55141LayerTreeHostImpl::FrameData::FrameData()
[email protected]e0341352013-04-06 05:01:20142 : contains_incomplete_tile(false), has_no_damage(false) {}
[email protected]c1bb5af2013-03-13 19:06:27143
144LayerTreeHostImpl::FrameData::~FrameData() {}
145
146scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
147 const LayerTreeSettings& settings,
148 LayerTreeHostImplClient* client,
[email protected]372bad5f2013-03-21 16:38:43149 Proxy* proxy,
150 RenderingStatsInstrumentation* rendering_stats_instrumentation) {
151 return make_scoped_ptr(
152 new LayerTreeHostImpl(settings,
153 client,
154 proxy,
155 rendering_stats_instrumentation));
[email protected]493067512012-09-19 23:34:10156}
157
[email protected]372bad5f2013-03-21 16:38:43158LayerTreeHostImpl::LayerTreeHostImpl(
159 const LayerTreeSettings& settings,
160 LayerTreeHostImplClient* client,
161 Proxy* proxy,
162 RenderingStatsInstrumentation* rendering_stats_instrumentation)
[email protected]c1bb5af2013-03-13 19:06:27163 : client_(client),
164 proxy_(proxy),
165 did_lock_scrolling_layer_(false),
166 should_bubble_scrolls_(false),
167 wheel_scrolling_(false),
168 settings_(settings),
[email protected]d9083762013-03-24 01:36:40169 overdraw_bottom_height_(0.f),
[email protected]c1bb5af2013-03-13 19:06:27170 device_scale_factor_(1.f),
171 visible_(true),
172 managed_memory_policy_(
[email protected]b56c1302013-03-20 21:17:34173 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
[email protected]c1bb5af2013-03-13 19:06:27174 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
175 0,
176 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
177 pinch_gesture_active_(false),
[email protected]9e3594522013-03-18 00:57:36178 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29179 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27180 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02181 debug_rect_history_(DebugRectHistory::Create()),
[email protected]d7626ffd2013-03-29 00:17:42182 max_memory_needed_bytes_(0),
[email protected]c1bb5af2013-03-13 19:06:27183 last_sent_memory_visible_bytes_(0),
184 last_sent_memory_visible_and_nearby_bytes_(0),
185 last_sent_memory_use_bytes_(0),
[email protected]e0341352013-04-06 05:01:20186 next_frame_damages_full_device_viewport_(false),
[email protected]372bad5f2013-03-21 16:38:43187 animation_registrar_(AnimationRegistrar::Create()),
188 rendering_stats_instrumentation_(rendering_stats_instrumentation) {
[email protected]c1bb5af2013-03-13 19:06:27189 DCHECK(proxy_->IsImplThread());
190 DidVisibilityChange(this, visible_);
191
[email protected]8e0176d2013-03-21 03:14:52192 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27193
[email protected]8e0176d2013-03-21 03:14:52194 if (settings.calculate_top_controls_position) {
[email protected]c1bb5af2013-03-13 19:06:27195 top_controls_manager_ =
196 TopControlsManager::Create(this,
[email protected]8e0176d2013-03-21 03:14:52197 settings.top_controls_height,
198 settings.top_controls_show_threshold,
199 settings.top_controls_hide_threshold);
[email protected]c1bb5af2013-03-13 19:06:27200 }
201
[email protected]8e0176d2013-03-21 03:14:52202 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27203
204 // LTHI always has an active tree.
205 active_tree_ = LayerTreeImpl::create(this);
[email protected]493067512012-09-19 23:34:10206}
207
[email protected]c1bb5af2013-03-13 19:06:27208LayerTreeHostImpl::~LayerTreeHostImpl() {
209 DCHECK(proxy_->IsImplThread());
210 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
211
212 if (active_tree_->root_layer()) {
213 ClearRenderSurfaces();
214 // The layer trees must be destroyed before the layer tree host. We've
215 // made a contract with our animation controllers that the registrar
216 // will outlive them, and we must make good.
217 recycle_tree_.reset();
218 pending_tree_.reset();
219 active_tree_.reset();
220 }
[email protected]94f206c12012-08-25 00:09:14221}
222
[email protected]c1bb5af2013-03-13 19:06:27223void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29224
[email protected]c1bb5af2013-03-13 19:06:27225void LayerTreeHostImpl::CommitComplete() {
226 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08227
[email protected]c1bb5af2013-03-13 19:06:27228 // Impl-side painting needs an update immediately post-commit to have the
229 // opportunity to create tilings. Other paths can call UpdateDrawProperties
230 // more lazily when needed prior to drawing.
[email protected]8e0176d2013-03-21 03:14:52231 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:27232 pending_tree_->set_needs_update_draw_properties();
233 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
234 } else {
235 active_tree_->set_needs_update_draw_properties();
236 }
[email protected]3ba4cae2013-01-16 03:58:38237
[email protected]c1bb5af2013-03-13 19:06:27238 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14239}
240
[email protected]c1bb5af2013-03-13 19:06:27241bool LayerTreeHostImpl::CanDraw() {
242 // Note: If you are changing this function or any other function that might
243 // affect the result of CanDraw, make sure to call
244 // client_->OnCanDrawStateChanged in the proper places and update the
245 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14246
[email protected]c1bb5af2013-03-13 19:06:27247 if (!active_tree_->root_layer()) {
[email protected]c76faea2013-03-26 07:42:42248 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
249 TRACE_EVENT_SCOPE_THREAD);
[email protected]2f1acc262012-11-16 21:42:22250 return false;
[email protected]c1bb5af2013-03-13 19:06:27251 }
252 if (device_viewport_size_.IsEmpty()) {
[email protected]c76faea2013-03-26 07:42:42253 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
254 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27255 return false;
256 }
257 if (active_tree_->ViewportSizeInvalid()) {
258 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42259 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed",
260 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27261 return false;
262 }
263 if (!renderer_) {
[email protected]c76faea2013-03-26 07:42:42264 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer",
265 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27266 return false;
267 }
268 if (active_tree_->ContentsTexturesPurged()) {
269 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42270 "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
271 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27272 return false;
273 }
274 return true;
[email protected]2f1acc262012-11-16 21:42:22275}
276
[email protected]c1bb5af2013-03-13 19:06:27277void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
278 base::Time wall_clock_time) {
279 AnimatePageScale(monotonic_time);
280 AnimateLayers(monotonic_time, wall_clock_time);
281 AnimateScrollbars(monotonic_time);
[email protected]ffb2720f2013-03-15 19:18:37282 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14283}
284
[email protected]c1bb5af2013-03-13 19:06:27285void LayerTreeHostImpl::ManageTiles() {
286 DCHECK(tile_manager_);
287 tile_manager_->ManageTiles();
288
289 size_t memory_required_bytes;
290 size_t memory_nice_to_have_bytes;
291 size_t memory_used_bytes;
292 tile_manager_->GetMemoryStats(&memory_required_bytes,
293 &memory_nice_to_have_bytes,
294 &memory_used_bytes);
295 SendManagedMemoryStats(memory_required_bytes,
296 memory_nice_to_have_bytes,
297 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15298}
299
[email protected]80334ba2013-03-20 17:33:50300void LayerTreeHostImpl::SetAnticipatedDrawTime(base::TimeTicks time) {
[email protected]f8456612013-03-19 20:56:09301 if (tile_manager_)
302 tile_manager_->SetAnticipatedDrawTime(time);
303}
304
[email protected]c1bb5af2013-03-13 19:06:27305void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
306 bool anchor_point,
307 float page_scale,
308 base::TimeTicks start_time,
309 base::TimeDelta duration) {
310 if (!RootScrollLayer())
311 return;
312
313 gfx::Vector2dF scroll_total =
314 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
315 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
[email protected]6fc4ee002013-03-26 23:39:51316 gfx::SizeF viewport_size = VisibleViewportSize();
[email protected]c1bb5af2013-03-13 19:06:27317
318 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
319 page_scale_animation_ =
320 PageScaleAnimation::Create(scroll_total,
321 active_tree_->total_page_scale_factor(),
322 viewport_size,
323 scaled_scrollable_size,
324 start_time_seconds);
325
326 if (anchor_point) {
327 gfx::Vector2dF anchor(target_offset);
328 page_scale_animation_->ZoomWithAnchor(anchor,
329 page_scale,
330 duration.InSecondsF());
331 } else {
332 gfx::Vector2dF scaled_target_offset = target_offset;
333 page_scale_animation_->ZoomTo(scaled_target_offset,
334 page_scale,
335 duration.InSecondsF());
336 }
337
338 client_->SetNeedsRedrawOnImplThread();
339 client_->SetNeedsCommitOnImplThread();
340 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15341}
342
[email protected]c1bb5af2013-03-13 19:06:27343void LayerTreeHostImpl::ScheduleAnimation() {
344 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15345}
346
[email protected]c1bb5af2013-03-13 19:06:27347bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
348 if (!EnsureRenderSurfaceLayerList())
349 return false;
[email protected]f57bbc02012-11-21 07:02:15350
[email protected]c1bb5af2013-03-13 19:06:27351 gfx::PointF device_viewport_point =
352 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15353
[email protected]c1bb5af2013-03-13 19:06:27354 // First find out which layer was hit from the saved list of visible layers
355 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:39356 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:27357 device_viewport_point,
358 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15359
[email protected]c1bb5af2013-03-13 19:06:27360 // Walk up the hierarchy and look for a layer with a touch event handler
361 // region that the given point hits.
362 for (; layer_impl; layer_impl = layer_impl->parent()) {
[email protected]6ba914122013-03-22 16:26:39363 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point,
[email protected]c1bb5af2013-03-13 19:06:27364 layer_impl))
365 return true;
366 }
[email protected]f57bbc02012-11-21 07:02:15367
[email protected]c1bb5af2013-03-13 19:06:27368 return false;
369}
370
371void LayerTreeHostImpl::TrackDamageForAllSurfaces(
372 LayerImpl* root_draw_layer,
[email protected]50761e92013-03-29 20:51:28373 const LayerImplList& render_surface_layer_list) {
[email protected]c1bb5af2013-03-13 19:06:27374 // For now, we use damage tracking to compute a global scissor. To do this, we
375 // must compute all damage tracking before drawing anything, so that we know
376 // the root damage rect. The root damage rect is then used to scissor each
377 // surface.
378
379 for (int surface_index = render_surface_layer_list.size() - 1;
[email protected]bf691c22013-03-26 21:15:06380 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27381 --surface_index) {
382 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
383 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
384 DCHECK(render_surface);
385 render_surface->damage_tracker()->UpdateDamageTrackingState(
386 render_surface->layer_list(),
387 render_surface_layer->id(),
388 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
389 render_surface->content_rect(),
390 render_surface_layer->mask_layer(),
391 render_surface_layer->filters(),
392 render_surface_layer->filter().get());
393 }
394}
395
396void LayerTreeHostImpl::FrameData::AppendRenderPass(
397 scoped_ptr<RenderPass> render_pass) {
398 render_passes_by_id[render_pass->id] = render_pass.get();
399 render_passes.push_back(render_pass.Pass());
400}
401
402static void AppendQuadsForLayer(RenderPass* target_render_pass,
403 LayerImpl* layer,
404 const OcclusionTrackerImpl& occlusion_tracker,
405 AppendQuadsData* append_quads_data) {
406 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49407 QuadCuller quad_culler(&target_render_pass->quad_list,
408 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27409 layer,
410 occlusion_tracker,
411 layer->ShowDebugBorders(),
412 for_surface);
413 layer->AppendQuads(&quad_culler, append_quads_data);
414}
415
416static void AppendQuadsForRenderSurfaceLayer(
417 RenderPass* target_render_pass,
418 LayerImpl* layer,
419 const RenderPass* contributing_render_pass,
420 const OcclusionTrackerImpl& occlusion_tracker,
421 AppendQuadsData* append_quads_data) {
422 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49423 QuadCuller quad_culler(&target_render_pass->quad_list,
424 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27425 layer,
426 occlusion_tracker,
427 layer->ShowDebugBorders(),
428 for_surface);
429
430 bool is_replica = false;
431 layer->render_surface()->AppendQuads(&quad_culler,
432 append_quads_data,
433 is_replica,
434 contributing_render_pass->id);
435
436 // Add replica after the surface so that it appears below the surface.
437 if (layer->has_replica()) {
438 is_replica = true;
439 layer->render_surface()->AppendQuads(&quad_culler,
440 append_quads_data,
441 is_replica,
442 contributing_render_pass->id);
443 }
444}
445
446static void AppendQuadsToFillScreen(
447 RenderPass* target_render_pass,
448 LayerImpl* root_layer,
449 SkColor screen_background_color,
450 const OcclusionTrackerImpl& occlusion_tracker) {
451 if (!root_layer || !SkColorGetA(screen_background_color))
452 return;
453
454 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
455 if (fill_region.IsEmpty())
456 return;
457
458 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49459 QuadCuller quad_culler(&target_render_pass->quad_list,
460 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27461 root_layer,
462 occlusion_tracker,
463 root_layer->ShowDebugBorders(),
464 for_surface);
465
466 // Manually create the quad state for the gutter quads, as the root layer
467 // doesn't have any bounds and so can't generate this itself.
468 // TODO(danakj): Make the gutter quads generated by the solid color layer
469 // (make it smarter about generating quads to fill unoccluded areas).
470
471 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
472 float opacity = 1.f;
473 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49474 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27475 shared_quad_state->SetAll(root_layer->draw_transform(),
476 root_target_rect.size(),
477 root_target_rect,
478 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01479 false,
[email protected]f57bbc02012-11-21 07:02:15480 opacity);
481
[email protected]c1bb5af2013-03-13 19:06:27482 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17483
[email protected]c1bb5af2013-03-13 19:06:27484 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
485 bool did_invert = root_layer->screen_space_transform().GetInverse(
486 &transform_to_layer_space);
487 DCHECK(did_invert);
488 for (Region::Iterator fill_rects(fill_region);
489 fill_rects.has_rect();
490 fill_rects.next()) {
491 // The root layer transform is composed of translations and scales only,
492 // no perspective, so mapping is sufficient (as opposed to projecting).
493 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21494 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27495 // Skip the quad culler and just append the quads directly to avoid
496 // occlusion checks.
497 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
498 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
[email protected]c7e95b42013-03-18 01:13:49499 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27500 }
[email protected]467b3612012-08-28 07:41:16501}
502
[email protected]c1bb5af2013-03-13 19:06:27503bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
504 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14505
[email protected]c1bb5af2013-03-13 19:06:27506 if (!CanDraw() || !active_tree_->root_layer())
507 return false;
[email protected]2d692992012-12-19 01:19:32508
[email protected]c1bb5af2013-03-13 19:06:27509 TrackDamageForAllSurfaces(active_tree_->root_layer(),
510 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14511
[email protected]e0341352013-04-06 05:01:20512 // If the root render surface has no visible damage, then don't generate a
513 // frame at all.
514 RenderSurfaceImpl* root_surface =
515 active_tree_->root_layer()->render_surface();
516 bool root_surface_has_no_visible_damage =
517 !root_surface->damage_tracker()->current_damage_rect().Intersects(
518 root_surface->content_rect());
519 bool root_surface_has_contributing_layers =
520 !root_surface->layer_list().empty();
521 if (root_surface_has_contributing_layers &&
522 root_surface_has_no_visible_damage) {
523 TRACE_EVENT0("cc",
524 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
525 frame->has_no_damage = true;
526 return true;
527 }
528
[email protected]c1bb5af2013-03-13 19:06:27529 TRACE_EVENT1("cc",
530 "LayerTreeHostImpl::CalculateRenderPasses",
531 "render_surface_layer_list.size()",
[email protected]bf691c22013-03-26 21:15:06532 static_cast<uint64>(frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14533
[email protected]c1bb5af2013-03-13 19:06:27534 // Create the render passes in dependency order.
535 for (int surface_index = frame->render_surface_layer_list->size() - 1;
[email protected]bf691c22013-03-26 21:15:06536 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27537 --surface_index) {
538 LayerImpl* render_surface_layer =
539 (*frame->render_surface_layer_list)[surface_index];
540 render_surface_layer->render_surface()->AppendRenderPasses(frame);
541 }
[email protected]94f206c12012-08-25 00:09:14542
[email protected]c1bb5af2013-03-13 19:06:27543 bool record_metrics_for_frame =
[email protected]8e0176d2013-03-21 03:14:52544 settings_.show_overdraw_in_tracing &&
[email protected]c1bb5af2013-03-13 19:06:27545 base::debug::TraceLog::GetInstance() &&
546 base::debug::TraceLog::GetInstance()->IsEnabled();
547 OcclusionTrackerImpl occlusion_tracker(
548 active_tree_->root_layer()->render_surface()->content_rect(),
549 record_metrics_for_frame);
550 occlusion_tracker.set_minimum_tracking_size(
[email protected]8e0176d2013-03-21 03:14:52551 settings_.minimum_occlusion_tracking_size);
[email protected]94f206c12012-08-25 00:09:14552
[email protected]846f455b2013-03-18 19:07:41553 if (debug_state_.show_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27554 occlusion_tracker.set_occluding_screen_space_rects_container(
555 &frame->occluding_screen_space_rects);
556 }
[email protected]846f455b2013-03-18 19:07:41557 if (debug_state_.show_non_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27558 occlusion_tracker.set_non_occluding_screen_space_rects_container(
559 &frame->non_occluding_screen_space_rects);
560 }
[email protected]94f206c12012-08-25 00:09:14561
[email protected]c1bb5af2013-03-13 19:06:27562 // Add quads to the Render passes in FrontToBack order to allow for testing
563 // occlusion and performing culling during the tree walk.
564 typedef LayerIterator<LayerImpl,
[email protected]50761e92013-03-29 20:51:28565 LayerImplList,
[email protected]c1bb5af2013-03-13 19:06:27566 RenderSurfaceImpl,
567 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14568
[email protected]c1bb5af2013-03-13 19:06:27569 // Typically when we are missing a texture and use a checkerboard quad, we
570 // still draw the frame. However when the layer being checkerboarded is moving
571 // due to an impl-animation, we drop the frame to avoid flashing due to the
572 // texture suddenly appearing in the future.
573 bool draw_frame = true;
[email protected]94f206c12012-08-25 00:09:14574
[email protected]372bad5f2013-03-21 16:38:43575 int layers_drawn = 0;
576
[email protected]c1bb5af2013-03-13 19:06:27577 LayerIteratorType end =
[email protected]71dfcc72013-03-20 21:30:09578 LayerIteratorType::End(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27579 for (LayerIteratorType it =
[email protected]71dfcc72013-03-20 21:30:09580 LayerIteratorType::Begin(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27581 it != end;
582 ++it) {
583 RenderPass::Id target_render_pass_id =
[email protected]71dfcc72013-03-20 21:30:09584 it.target_render_surface_layer()->render_surface()->RenderPassId();
[email protected]c1bb5af2013-03-13 19:06:27585 RenderPass* target_render_pass =
586 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14587
[email protected]c1bb5af2013-03-13 19:06:27588 occlusion_tracker.EnterLayer(it);
[email protected]94f206c12012-08-25 00:09:14589
[email protected]c1bb5af2013-03-13 19:06:27590 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30591
[email protected]71dfcc72013-03-20 21:30:09592 if (it.represents_contributing_render_surface()) {
[email protected]c1bb5af2013-03-13 19:06:27593 RenderPass::Id contributing_render_pass_id =
594 it->render_surface()->RenderPassId();
595 RenderPass* contributing_render_pass =
596 frame->render_passes_by_id[contributing_render_pass_id];
597 AppendQuadsForRenderSurfaceLayer(target_render_pass,
598 *it,
599 contributing_render_pass,
600 occlusion_tracker,
601 &append_quads_data);
[email protected]e1e768f2013-03-26 08:48:09602 } else if (it.represents_itself() &&
603 !it->visible_content_rect().IsEmpty()) {
[email protected]c1bb5af2013-03-13 19:06:27604 bool has_occlusion_from_outside_target_surface;
605 bool impl_draw_transform_is_unknown = false;
606 if (occlusion_tracker.Occluded(
607 it->render_target(),
608 it->visible_content_rect(),
609 it->draw_transform(),
610 impl_draw_transform_is_unknown,
611 it->is_clipped(),
612 it->clip_rect(),
613 &has_occlusion_from_outside_target_surface)) {
[email protected]e1e768f2013-03-26 08:48:09614 append_quads_data.had_occlusion_from_outside_target_surface |=
[email protected]c1bb5af2013-03-13 19:06:27615 has_occlusion_from_outside_target_surface;
616 } else {
617 DCHECK_EQ(active_tree_, it->layer_tree_impl());
618 it->WillDraw(resource_provider_.get());
619 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57620
[email protected]c1bb5af2013-03-13 19:06:27621 if (it->HasContributingDelegatedRenderPasses()) {
622 RenderPass::Id contributing_render_pass_id =
623 it->FirstContributingRenderPassId();
624 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
625 frame->render_passes_by_id.end()) {
626 RenderPass* render_pass =
627 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14628
[email protected]c1bb5af2013-03-13 19:06:27629 AppendQuadsData append_quads_data(render_pass->id);
630 AppendQuadsForLayer(render_pass,
631 *it,
632 occlusion_tracker,
633 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57634
[email protected]c1bb5af2013-03-13 19:06:27635 contributing_render_pass_id =
636 it->NextContributingRenderPassId(contributing_render_pass_id);
637 }
[email protected]94f206c12012-08-25 00:09:14638 }
639
[email protected]c1bb5af2013-03-13 19:06:27640 AppendQuadsForLayer(target_render_pass,
641 *it,
642 occlusion_tracker,
643 &append_quads_data);
644 }
[email protected]89228202012-08-29 03:20:30645
[email protected]372bad5f2013-03-21 16:38:43646 ++layers_drawn;
[email protected]94f206c12012-08-25 00:09:14647 }
648
[email protected]e1e768f2013-03-26 08:48:09649 if (append_quads_data.had_occlusion_from_outside_target_surface)
[email protected]c1bb5af2013-03-13 19:06:27650 target_render_pass->has_occlusion_from_outside_target_surface = true;
651
[email protected]e1e768f2013-03-26 08:48:09652 if (append_quads_data.num_missing_tiles) {
[email protected]372bad5f2013-03-21 16:38:43653 rendering_stats_instrumentation_->AddMissingTiles(
[email protected]e1e768f2013-03-26 08:48:09654 append_quads_data.num_missing_tiles);
[email protected]c1bb5af2013-03-13 19:06:27655 bool layer_has_animating_transform =
656 it->screen_space_transform_is_animating() ||
657 it->draw_transform_is_animating();
658 if (layer_has_animating_transform)
659 draw_frame = false;
660 }
661
[email protected]e1e768f2013-03-26 08:48:09662 if (append_quads_data.had_incomplete_tile)
[email protected]c1bb5af2013-03-13 19:06:27663 frame->contains_incomplete_tile = true;
664
665 occlusion_tracker.LeaveLayer(it);
666 }
667
[email protected]372bad5f2013-03-21 16:38:43668 rendering_stats_instrumentation_->AddLayersDrawn(layers_drawn);
669
[email protected]1d993172012-10-18 18:15:04670#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27671 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
672 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
673 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
674 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
675 != frame->render_passes_by_id.end());
676 }
[email protected]94f206c12012-08-25 00:09:14677#endif
[email protected]c1bb5af2013-03-13 19:06:27678 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14679
[email protected]c1bb5af2013-03-13 19:06:27680 if (!active_tree_->has_transparent_background()) {
681 frame->render_passes.back()->has_transparent_background = false;
682 AppendQuadsToFillScreen(frame->render_passes.back(),
683 active_tree_->root_layer(),
684 active_tree_->background_color(),
685 occlusion_tracker);
686 }
[email protected]94f206c12012-08-25 00:09:14687
[email protected]c1bb5af2013-03-13 19:06:27688 if (draw_frame)
689 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]94f206c12012-08-25 00:09:14690
[email protected]c1bb5af2013-03-13 19:06:27691 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
692 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
[email protected]bf691c22013-03-26 21:15:06693 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()),
694 frame);
[email protected]94f206c12012-08-25 00:09:14695
[email protected]e0341352013-04-06 05:01:20696 // If we're making a frame to draw, it better have at least one render pass.
697 DCHECK(!frame->render_passes.empty());
[email protected]c1bb5af2013-03-13 19:06:27698 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14699}
700
[email protected]3d9f7432013-04-06 00:35:18701void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
702 bool should_background_tick) {
703 bool enabled = should_background_tick &&
704 !animation_registrar_->active_animation_controllers().empty();
705
[email protected]c1bb5af2013-03-13 19:06:27706 // Lazily create the time_source adapter so that we can vary the interval for
707 // testing.
708 if (!time_source_client_adapter_) {
709 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
710 this,
[email protected]6d0e69d2013-03-20 14:53:26711 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
[email protected]c1bb5af2013-03-13 19:06:27712 proxy_->CurrentThread()));
713 }
[email protected]94f206c12012-08-25 00:09:14714
[email protected]c1bb5af2013-03-13 19:06:27715 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14716}
717
[email protected]c1bb5af2013-03-13 19:06:27718static inline RenderPass* FindRenderPassById(
719 RenderPass::Id render_pass_id,
720 const LayerTreeHostImpl::FrameData& frame) {
721 RenderPassIdHashMap::const_iterator it =
722 frame.render_passes_by_id.find(render_pass_id);
723 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14724}
725
[email protected]c1bb5af2013-03-13 19:06:27726static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
727 LayerTreeHostImpl::FrameData* frame) {
728 RenderPass* remove_render_pass =
729 FindRenderPassById(remove_render_pass_id, *frame);
730 // The pass was already removed by another quad - probably the original, and
731 // we are the replica.
732 if (!remove_render_pass)
733 return;
734 RenderPassList& render_passes = frame->render_passes;
735 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
736 render_passes.end(),
737 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14738
[email protected]c1bb5af2013-03-13 19:06:27739 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14740
[email protected]c1bb5af2013-03-13 19:06:27741 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
742 frame->render_passes.erase(to_remove);
743 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14744
[email protected]c1bb5af2013-03-13 19:06:27745 // Now follow up for all RenderPass quads and remove their RenderPasses
746 // recursively.
747 const QuadList& quad_list = removed_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29748 QuadList::ConstBackToFrontIterator quad_list_iterator =
749 quad_list.BackToFrontBegin();
750 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27751 ++quad_list_iterator) {
752 DrawQuad* current_quad = (*quad_list_iterator);
753 if (current_quad->material != DrawQuad::RENDER_PASS)
754 continue;
[email protected]94f206c12012-08-25 00:09:14755
[email protected]c1bb5af2013-03-13 19:06:27756 RenderPass::Id next_remove_render_pass_id =
757 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
758 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
759 }
[email protected]94f206c12012-08-25 00:09:14760}
761
[email protected]c1bb5af2013-03-13 19:06:27762bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
763 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
764 const FrameData& frame) const {
765 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
766 bool quad_has_cached_resource =
[email protected]bf691c22013-03-26 21:15:06767 renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id);
[email protected]c1bb5af2013-03-13 19:06:27768 if (quad_has_damage) {
769 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
770 return false;
771 } else if (!quad_has_cached_resource) {
772 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
773 return false;
774 }
775 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
776 return true;
[email protected]94f206c12012-08-25 00:09:14777}
778
[email protected]c1bb5af2013-03-13 19:06:27779bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
780 const RenderPassDrawQuad& quad, const FrameData& frame) const {
781 const RenderPass* render_pass =
782 FindRenderPassById(quad.render_pass_id, frame);
783 if (!render_pass)
784 return false;
[email protected]94f206c12012-08-25 00:09:14785
[email protected]c1bb5af2013-03-13 19:06:27786 // If any quad or RenderPass draws into this RenderPass, then keep it.
787 const QuadList& quad_list = render_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29788 for (QuadList::ConstBackToFrontIterator quad_list_iterator =
789 quad_list.BackToFrontBegin();
790 quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27791 ++quad_list_iterator) {
792 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14793
[email protected]c1bb5af2013-03-13 19:06:27794 if (current_quad->material != DrawQuad::RENDER_PASS)
795 return false;
[email protected]94f206c12012-08-25 00:09:14796
[email protected]c1bb5af2013-03-13 19:06:27797 const RenderPass* contributing_pass = FindRenderPassById(
798 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
799 if (contributing_pass)
800 return false;
801 }
802 return true;
[email protected]94f206c12012-08-25 00:09:14803}
804
805// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27806template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
807 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
808 CullRenderPassesWithCachedTextures culler, FrameData* frame);
809template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
810 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
811 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14812
813// static
[email protected]c1bb5af2013-03-13 19:06:27814template <typename RenderPassCuller>
815void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
816 FrameData* frame) {
817 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
818 it != culler.RenderPassListEnd(frame->render_passes);
819 it = culler.RenderPassListNext(it)) {
820 const RenderPass* current_pass = frame->render_passes[it];
821 const QuadList& quad_list = current_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29822 QuadList::ConstBackToFrontIterator quad_list_iterator =
823 quad_list.BackToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14824
[email protected]ed511b8d2013-03-25 03:29:29825 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27826 ++quad_list_iterator) {
827 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14828
[email protected]c1bb5af2013-03-13 19:06:27829 if (current_quad->material != DrawQuad::RENDER_PASS)
830 continue;
[email protected]94f206c12012-08-25 00:09:14831
[email protected]c1bb5af2013-03-13 19:06:27832 const RenderPassDrawQuad* render_pass_quad =
833 RenderPassDrawQuad::MaterialCast(current_quad);
834 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
835 continue;
[email protected]94f206c12012-08-25 00:09:14836
[email protected]c1bb5af2013-03-13 19:06:27837 // We are changing the vector in the middle of iteration. Because we
838 // delete render passes that draw into the current pass, we are
839 // guaranteed that any data from the iterator to the end will not
840 // change. So, capture the iterator position from the end of the
841 // list, and restore it after the change.
842 size_t position_from_end = frame->render_passes.size() - it;
843 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
844 it = frame->render_passes.size() - position_from_end;
845 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14846 }
[email protected]c1bb5af2013-03-13 19:06:27847 }
[email protected]94f206c12012-08-25 00:09:14848}
849
[email protected]e0341352013-04-06 05:01:20850bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
851 gfx::Rect device_viewport_damage_rect) {
[email protected]c1bb5af2013-03-13 19:06:27852 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14853
[email protected]c1bb5af2013-03-13 19:06:27854 active_tree_->UpdateDrawProperties(
855 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27856
[email protected]c1bb5af2013-03-13 19:06:27857 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
858 frame->render_passes.clear();
859 frame->render_passes_by_id.clear();
860 frame->will_draw_layers.clear();
[email protected]e0341352013-04-06 05:01:20861 frame->contains_incomplete_tile = false;
862 frame->has_no_damage = false;
863
864 if (active_tree_->root_layer()) {
865 if (next_frame_damages_full_device_viewport_)
866 device_viewport_damage_rect.Union(gfx::Rect(device_viewport_size_));
867
868 active_tree_->root_layer()->render_surface()->damage_tracker()->
869 AddDamageNextUpdate(device_viewport_damage_rect);
870 }
871 next_frame_damages_full_device_viewport_ = false;
[email protected]94f206c12012-08-25 00:09:14872
[email protected]c1bb5af2013-03-13 19:06:27873 if (!CalculateRenderPasses(frame))
874 return false;
[email protected]94f206c12012-08-25 00:09:14875
[email protected]c1bb5af2013-03-13 19:06:27876 // If we return true, then we expect DrawLayers() to be called before this
877 // function is called again.
878 return true;
[email protected]94f206c12012-08-25 00:09:14879}
880
[email protected]c1bb5af2013-03-13 19:06:27881void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
882 const ManagedMemoryPolicy& policy) {
883 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
[email protected]46b8acc2013-03-19 22:38:35884 visible_ ? policy.bytes_limit_when_visible
885 : policy.bytes_limit_when_not_visible,
886 ManagedMemoryPolicy::PriorityCutoffToValue(
887 visible_ ? policy.priority_cutoff_when_visible
888 : policy.priority_cutoff_when_not_visible));
[email protected]c1bb5af2013-03-13 19:06:27889 if (evicted_resources) {
890 active_tree_->SetContentsTexturesPurged();
891 if (pending_tree_)
892 pending_tree_->SetContentsTexturesPurged();
893 client_->SetNeedsCommitOnImplThread();
894 client_->OnCanDrawStateChanged(CanDraw());
895 client_->RenewTreePriority();
896 }
897 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43898
[email protected]c1bb5af2013-03-13 19:06:27899 if (tile_manager_) {
900 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
901 new_state.memory_limit_in_bytes = visible_ ?
[email protected]46b8acc2013-03-19 22:38:35902 policy.bytes_limit_when_visible :
903 policy.bytes_limit_when_not_visible;
[email protected]41124c52013-03-28 23:26:57904 // TODO(reveman): We should avoid keeping around unused resources if
905 // possible. crbug.com/224475
906 new_state.unused_memory_limit_in_bytes =
907 (new_state.memory_limit_in_bytes *
908 settings_.max_unused_resource_memory_percentage) / 100;
[email protected]c1bb5af2013-03-13 19:06:27909 new_state.memory_limit_policy =
[email protected]46b8acc2013-03-19 22:38:35910 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
[email protected]c1bb5af2013-03-13 19:06:27911 visible_ ?
[email protected]46b8acc2013-03-19 22:38:35912 policy.priority_cutoff_when_visible :
913 policy.priority_cutoff_when_not_visible);
[email protected]c1bb5af2013-03-13 19:06:27914 tile_manager_->SetGlobalState(new_state);
915 }
[email protected]94f206c12012-08-25 00:09:14916}
917
[email protected]c1bb5af2013-03-13 19:06:27918bool LayerTreeHostImpl::HasImplThread() const {
919 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44920}
921
[email protected]c1bb5af2013-03-13 19:06:27922void LayerTreeHostImpl::ScheduleManageTiles() {
923 if (client_)
924 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43925}
926
[email protected]86126792013-03-16 20:07:54927void LayerTreeHostImpl::DidInitializeVisibleTile() {
928 // TODO(reveman): Determine tiles that changed and only damage
929 // what's necessary.
930 SetFullRootLayerDamage();
[email protected]c1bb5af2013-03-13 19:06:27931 if (client_)
[email protected]86126792013-03-16 20:07:54932 client_->DidInitializeVisibleTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47933}
934
[email protected]c1bb5af2013-03-13 19:06:27935bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
[email protected]8e0176d2013-03-21 03:14:52936 return settings_.should_clear_root_render_pass;
[email protected]f35e2322012-12-15 21:45:52937}
938
[email protected]c1bb5af2013-03-13 19:06:27939void LayerTreeHostImpl::SetManagedMemoryPolicy(
940 const ManagedMemoryPolicy& policy) {
941 if (managed_memory_policy_ == policy)
942 return;
[email protected]61de5812012-11-08 07:03:44943
[email protected]d7626ffd2013-03-29 00:17:42944 // If there is already enough memory to draw everything imaginable and the
945 // new memory limit does not change this, then do not re-commit. Don't bother
946 // skipping commits if this is not visible (commits don't happen when not
947 // visible, there will almost always be a commit when this becomes visible).
948 bool needs_commit = true;
949 if (visible() &&
950 policy.bytes_limit_when_visible >=
951 max_memory_needed_bytes_ &&
952 managed_memory_policy_.bytes_limit_when_visible >=
953 max_memory_needed_bytes_ &&
954 policy.priority_cutoff_when_visible ==
955 managed_memory_policy_.priority_cutoff_when_visible) {
956 needs_commit = false;
957 }
958
[email protected]c1bb5af2013-03-13 19:06:27959 managed_memory_policy_ = policy;
960 if (!proxy_->HasImplThread()) {
[email protected]d7626ffd2013-03-29 00:17:42961 // In single-thread mode, this can be called on the main thread by
962 // GLRenderer::OnMemoryAllocationChanged.
[email protected]c1bb5af2013-03-13 19:06:27963 DebugScopedSetImplThread impl_thread(proxy_);
964 EnforceManagedMemoryPolicy(managed_memory_policy_);
965 } else {
966 DCHECK(proxy_->IsImplThread());
967 EnforceManagedMemoryPolicy(managed_memory_policy_);
968 }
[email protected]d7626ffd2013-03-29 00:17:42969
970 if (needs_commit)
971 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:14972}
973
[email protected]c1bb5af2013-03-13 19:06:27974void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
975 base::TimeDelta interval) {
976 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14977}
978
[email protected]7ed47512013-03-26 22:28:45979void LayerTreeHostImpl::DidVSync(base::TimeTicks frame_time) {
980 client_->DidVSync(frame_time);
981}
982
[email protected]c1bb5af2013-03-13 19:06:27983void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
984 const CompositorFrameAck& ack) {
985 if (!renderer_)
986 return;
[email protected]b6f3d7e2012-12-08 00:11:21987
[email protected]c1bb5af2013-03-13 19:06:27988 // TODO(piman): We may need to do some validation on this ack before
989 // processing it.
990 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16991}
992
[email protected]c1bb5af2013-03-13 19:06:27993void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
994 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:29995}
996
[email protected]c1bb5af2013-03-13 19:06:27997CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
998 CompositorFrameMetadata metadata;
999 metadata.device_scale_factor = device_scale_factor_;
1000 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
1001 metadata.viewport_size = active_tree_->ScrollableViewportSize();
1002 metadata.root_layer_size = active_tree_->ScrollableSize();
1003 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
1004 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
1005 if (top_controls_manager_) {
1006 metadata.location_bar_offset =
1007 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
1008 metadata.location_bar_content_translation =
1009 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
[email protected]5a54b2822013-03-26 10:00:011010 metadata.overdraw_bottom_height = overdraw_bottom_height_;
[email protected]c1bb5af2013-03-13 19:06:271011 }
[email protected]bf189f62012-12-18 03:42:111012
[email protected]c1bb5af2013-03-13 19:06:271013 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:111014 return metadata;
[email protected]c1bb5af2013-03-13 19:06:271015
[email protected]ffb2720f2013-03-15 19:18:371016 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
[email protected]c1bb5af2013-03-13 19:06:271017
1018 return metadata;
[email protected]bf189f62012-12-18 03:42:111019}
1020
[email protected]73673592013-04-03 22:14:321021bool LayerTreeHostImpl::AllowPartialSwap() const {
1022 // We don't track damage on the HUD layer (it interacts with damage tracking
1023 // visualizations), so disable partial swaps to make the HUD layer display
1024 // properly.
1025 return !debug_state_.ShowHudRects();
1026}
1027
[email protected]f0c2a242013-03-15 19:34:521028void LayerTreeHostImpl::DrawLayers(FrameData* frame,
1029 base::TimeTicks frame_begin_time) {
[email protected]c1bb5af2013-03-13 19:06:271030 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
1031 DCHECK(CanDraw());
[email protected]e0341352013-04-06 05:01:201032
1033 if (frame->has_no_damage)
1034 return;
1035
[email protected]c1bb5af2013-03-13 19:06:271036 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:141037
[email protected]9e3594522013-03-18 00:57:361038 fps_counter_->SaveTimeStamp(frame_begin_time);
[email protected]94f206c12012-08-25 00:09:141039
[email protected]372bad5f2013-03-21 16:38:431040 rendering_stats_instrumentation_->SetScreenFrameCount(
1041 fps_counter_->current_frame_number());
1042 rendering_stats_instrumentation_->SetDroppedFrameCount(
1043 fps_counter_->dropped_frame_count());
1044
[email protected]c1bb5af2013-03-13 19:06:271045 if (tile_manager_) {
1046 memory_history_->SaveEntry(
1047 tile_manager_->memory_stats_from_last_assign());
1048 }
[email protected]1191d9d2013-02-02 06:00:331049
[email protected]846f455b2013-03-18 19:07:411050 if (debug_state_.ShowHudRects()) {
[email protected]d35992782013-03-14 14:54:021051 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:271052 active_tree_->root_layer(),
1053 *frame->render_surface_layer_list,
1054 frame->occluding_screen_space_rects,
1055 frame->non_occluding_screen_space_rects,
1056 debug_state_);
1057 }
[email protected]94f206c12012-08-25 00:09:141058
[email protected]a848c102013-03-26 08:59:091059 if (!settings_.impl_side_painting && debug_state_.continuous_painting) {
1060 const RenderingStats& stats =
1061 rendering_stats_instrumentation_->GetRenderingStats();
1062 paint_time_counter_->SavePaintTime(stats.total_paint_time);
1063 }
1064
[email protected]846f455b2013-03-18 19:07:411065 if (debug_state_.trace_all_rendered_frames) {
[email protected]c76faea2013-03-26 07:42:421066 TRACE_EVENT_INSTANT1("cc.debug", "Frame", TRACE_EVENT_SCOPE_THREAD,
[email protected]c1bb5af2013-03-13 19:06:271067 "frame", ValueToString(FrameStateAsValue()));
1068 }
[email protected]131a0c22013-02-12 18:31:081069
[email protected]c1bb5af2013-03-13 19:06:271070 // Because the contents of the HUD depend on everything else in the frame, the
1071 // contents of its texture are updated as the last thing before the frame is
1072 // drawn.
1073 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:541074 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:141075
[email protected]d002dd02013-03-27 07:40:401076 renderer_->DrawFrame(&frame->render_passes);
[email protected]c1bb5af2013-03-13 19:06:271077 // The render passes should be consumed by the renderer.
1078 DCHECK(frame->render_passes.empty());
1079 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:141080
[email protected]c1bb5af2013-03-13 19:06:271081 // The next frame should start by assuming nothing has changed, and changes
1082 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:541083 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:271084 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
1085 DidDrawDamagedArea();
1086 }
1087 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:141088}
1089
[email protected]c1bb5af2013-03-13 19:06:271090void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
1091 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
1092 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:521093
[email protected]c1bb5af2013-03-13 19:06:271094 // Once all layers have been drawn, pending texture uploads should no
1095 // longer block future uploads.
1096 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:141097}
1098
[email protected]c1bb5af2013-03-13 19:06:271099void LayerTreeHostImpl::FinishAllRendering() {
1100 if (renderer_)
1101 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:141102}
1103
[email protected]c1bb5af2013-03-13 19:06:271104bool LayerTreeHostImpl::IsContextLost() {
1105 DCHECK(proxy_->IsImplThread());
1106 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141107}
1108
[email protected]c1bb5af2013-03-13 19:06:271109const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1110 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141111}
1112
[email protected]e0341352013-04-06 05:01:201113bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
1114 if (frame.has_no_damage)
1115 return false;
[email protected]c1bb5af2013-03-13 19:06:271116 return renderer_->SwapBuffers();
[email protected]94f206c12012-08-25 00:09:141117}
1118
[email protected]7ed47512013-03-26 22:28:451119void LayerTreeHostImpl::EnableVSyncNotification(bool enable) {
1120 if (output_surface_)
1121 output_surface_->EnableVSyncNotification(enable);
1122}
1123
[email protected]c1bb5af2013-03-13 19:06:271124gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1125 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101126}
1127
[email protected]ffb2720f2013-03-15 19:18:371128gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1129 gfx::SizeF dip_size =
1130 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1131
1132 // The clip layer should be used if non-overlay scrollbars may exist since
1133 // it adjusts for them.
1134 LayerImpl* clip_layer = active_tree_->RootClipLayer();
[email protected]8e0176d2013-03-21 03:14:521135 if (!Settings().solid_color_scrollbars && clip_layer &&
[email protected]ffb2720f2013-03-15 19:18:371136 clip_layer->masks_to_bounds())
1137 dip_size = clip_layer->bounds();
1138
[email protected]ed511b8d2013-03-25 03:29:291139 float top_offset =
[email protected]ffb2720f2013-03-15 19:18:371140 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
[email protected]d9083762013-03-24 01:36:401141 return gfx::SizeF(dip_size.width(),
[email protected]ed511b8d2013-03-25 03:29:291142 dip_size.height() - top_offset - overdraw_bottom_height_);
[email protected]ffb2720f2013-03-15 19:18:371143}
1144
[email protected]c1bb5af2013-03-13 19:06:271145const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1146 return settings();
[email protected]493067512012-09-19 23:34:101147}
1148
[email protected]c1bb5af2013-03-13 19:06:271149void LayerTreeHostImpl::DidLoseOutputSurface() {
1150 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141151}
1152
[email protected]c1bb5af2013-03-13 19:06:271153void LayerTreeHostImpl::OnSwapBuffersComplete() {
1154 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141155}
1156
[email protected]c1bb5af2013-03-13 19:06:271157void LayerTreeHostImpl::Readback(void* pixels,
1158 gfx::Rect rect_in_device_viewport) {
1159 DCHECK(renderer_);
1160 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141161}
1162
[email protected]69b50ec2013-01-19 04:58:011163bool LayerTreeHostImpl::haveRootScrollLayer() const {
[email protected]3209161d2013-03-29 19:17:341164 return !!RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011165}
1166
[email protected]c1bb5af2013-03-13 19:06:271167LayerImpl* LayerTreeHostImpl::RootLayer() const {
1168 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081169}
1170
[email protected]c1bb5af2013-03-13 19:06:271171LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1172 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081173}
1174
[email protected]c1bb5af2013-03-13 19:06:271175LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1176 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081177}
1178
[email protected]94f206c12012-08-25 00:09:141179// Content layers can be either directly scrollable or contained in an outer
1180// scrolling layer which applies the scroll transform. Given a content layer,
1181// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271182static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1183 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141184 return 0;
[email protected]c1bb5af2013-03-13 19:06:271185
1186 if (layer_impl->scrollable())
1187 return layer_impl;
1188
1189 if (layer_impl->DrawsContent() &&
1190 layer_impl->parent() &&
1191 layer_impl->parent()->scrollable())
1192 return layer_impl->parent();
1193
1194 return 0;
[email protected]94f206c12012-08-25 00:09:141195}
1196
[email protected]c1bb5af2013-03-13 19:06:271197void LayerTreeHostImpl::CreatePendingTree() {
1198 CHECK(!pending_tree_);
1199 if (recycle_tree_)
1200 recycle_tree_.swap(pending_tree_);
1201 else
1202 pending_tree_ = LayerTreeImpl::create(this);
1203 client_->OnCanDrawStateChanged(CanDraw());
1204 client_->OnHasPendingTreeStateChanged(pending_tree_);
1205 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1206 TRACE_EVENT_ASYNC_STEP0("cc",
1207 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271208}
1209
[email protected]c1bb5af2013-03-13 19:06:271210void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1211 DCHECK(!client_->IsInsideDraw()) <<
1212 "Checking for completed uploads within a draw may trigger "
1213 "spurious redraws.";
1214 if (tile_manager_)
1215 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481216}
1217
[email protected]c1bb5af2013-03-13 19:06:271218bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1219 if (!pending_tree_)
1220 return false;
[email protected]2e7ca422012-12-20 02:57:271221
[email protected]c1bb5af2013-03-13 19:06:271222 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091223
[email protected]c1bb5af2013-03-13 19:06:271224 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161225
[email protected]c1bb5af2013-03-13 19:06:271226 TRACE_EVENT_ASYNC_STEP1("cc",
1227 "PendingTree", pending_tree_.get(), "activate",
1228 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271229
[email protected]8ca1e6c2013-04-02 03:49:261230 // Activate once all visible resources in pending tree are ready.
1231 if (!pending_tree_->AreVisibleResourcesReady())
1232 return false;
[email protected]2e7ca422012-12-20 02:57:271233
[email protected]c1bb5af2013-03-13 19:06:271234 ActivatePendingTree();
1235 return true;
[email protected]2e7ca422012-12-20 02:57:271236}
1237
[email protected]c1bb5af2013-03-13 19:06:271238void LayerTreeHostImpl::ActivatePendingTree() {
1239 CHECK(pending_tree_);
1240 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351241
[email protected]c1bb5af2013-03-13 19:06:271242 active_tree_->PushPersistedState(pending_tree_.get());
1243 if (pending_tree_->needs_full_tree_sync()) {
1244 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331245 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271246 active_tree_->DetachLayerTree(),
1247 active_tree_.get()));
1248 }
[email protected]b5651c22013-03-14 15:06:331249 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271250 active_tree_->root_layer());
1251 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511252
[email protected]c1bb5af2013-03-13 19:06:271253 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511254
[email protected]c1bb5af2013-03-13 19:06:271255 // Now that we've synced everything from the pending tree to the active
1256 // tree, rename the pending tree the recycle tree so we can reuse it on the
1257 // next sync.
1258 pending_tree_.swap(recycle_tree_);
1259 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511260
[email protected]c1bb5af2013-03-13 19:06:271261 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221262
[email protected]c1bb5af2013-03-13 19:06:271263 // Reduce wasted memory now that unlinked resources are guaranteed not
1264 // to be used.
1265 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411266
[email protected]c1bb5af2013-03-13 19:06:271267 client_->OnCanDrawStateChanged(CanDraw());
1268 client_->OnHasPendingTreeStateChanged(pending_tree_);
1269 client_->SetNeedsRedrawOnImplThread();
1270 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241271
[email protected]a848c102013-03-26 08:59:091272 if (debug_state_.continuous_painting) {
1273 const RenderingStats& stats =
[email protected]372bad5f2013-03-21 16:38:431274 rendering_stats_instrumentation_->GetRenderingStats();
[email protected]a848c102013-03-26 08:59:091275 paint_time_counter_->SavePaintTime(
1276 stats.total_paint_time +
1277 stats.total_rasterize_time_for_now_bins_on_pending_tree);
[email protected]c1bb5af2013-03-13 19:06:271278 }
[email protected]2e7ca422012-12-20 02:57:271279}
1280
[email protected]c1bb5af2013-03-13 19:06:271281void LayerTreeHostImpl::SetVisible(bool visible) {
1282 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141283
[email protected]c1bb5af2013-03-13 19:06:271284 if (visible_ == visible)
1285 return;
1286 visible_ = visible;
1287 DidVisibilityChange(this, visible_);
1288 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141289
[email protected]c1bb5af2013-03-13 19:06:271290 if (!renderer_)
1291 return;
[email protected]94f206c12012-08-25 00:09:141292
[email protected]c1bb5af2013-03-13 19:06:271293 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141294}
1295
[email protected]c1bb5af2013-03-13 19:06:271296bool LayerTreeHostImpl::InitializeRenderer(
1297 scoped_ptr<OutputSurface> output_surface) {
1298 // Since we will create a new resource provider, we cannot continue to use
1299 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1300 // before we destroy the old resource provider.
1301 if (active_tree_->root_layer())
1302 ClearRenderSurfaces();
1303 if (active_tree_->root_layer())
1304 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1305 if (pending_tree_ && pending_tree_->root_layer())
1306 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1307 if (recycle_tree_ && recycle_tree_->root_layer())
1308 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]45c4b1e2013-01-16 02:19:401309
[email protected]c1bb5af2013-03-13 19:06:271310 // Note: order is important here.
1311 renderer_.reset();
1312 tile_manager_.reset();
1313 resource_provider_.reset();
1314 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141315
[email protected]c1bb5af2013-03-13 19:06:271316 if (!output_surface->BindToClient(this))
1317 return false;
[email protected]be3181652012-09-25 13:02:131318
[email protected]075d8aa2013-04-01 23:03:111319 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1320 output_surface.get(), settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271321 if (!resource_provider)
1322 return false;
[email protected]be3181652012-09-25 13:02:131323
[email protected]8e0176d2013-03-21 03:14:521324 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:271325 tile_manager_.reset(new TileManager(this,
1326 resource_provider.get(),
[email protected]8e0176d2013-03-21 03:14:521327 settings_.num_raster_threads,
[email protected]d616de012013-03-28 07:19:101328 settings_.max_prepaint_tile_distance,
[email protected]8e0176d2013-03-21 03:14:521329 settings_.use_cheapness_estimator,
1330 settings_.use_color_estimator,
[email protected]372bad5f2013-03-21 16:38:431331 settings_.prediction_benchmarking,
1332 rendering_stats_instrumentation_));
[email protected]c1bb5af2013-03-13 19:06:271333 }
[email protected]8947cbe2012-11-28 05:27:431334
[email protected]c1bb5af2013-03-13 19:06:271335 if (output_surface->capabilities().has_parent_compositor) {
1336 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1337 resource_provider.get());
1338 } else if (output_surface->context3d()) {
1339 renderer_ = GLRenderer::Create(this,
1340 output_surface.get(),
[email protected]075d8aa2013-04-01 23:03:111341 resource_provider.get(),
1342 settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271343 } else if (output_surface->software_device()) {
1344 renderer_ = SoftwareRenderer::Create(this,
1345 output_surface.get(),
1346 resource_provider.get());
1347 }
1348 if (!renderer_)
1349 return false;
[email protected]be3181652012-09-25 13:02:131350
[email protected]c1bb5af2013-03-13 19:06:271351 resource_provider_ = resource_provider.Pass();
1352 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141353
[email protected]c1bb5af2013-03-13 19:06:271354 if (!visible_)
1355 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141356
[email protected]c1bb5af2013-03-13 19:06:271357 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211358
[email protected]c1bb5af2013-03-13 19:06:271359 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1360 // to be initialized to get max texture size.
1361 active_tree_->set_needs_update_draw_properties();
1362 if (pending_tree_)
1363 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161364
[email protected]c1bb5af2013-03-13 19:06:271365 return true;
[email protected]94f206c12012-08-25 00:09:141366}
1367
[email protected]c1bb5af2013-03-13 19:06:271368void LayerTreeHostImpl::SetViewportSize(gfx::Size layout_viewport_size,
1369 gfx::Size device_viewport_size) {
1370 if (layout_viewport_size == layout_viewport_size_ &&
1371 device_viewport_size == device_viewport_size_)
1372 return;
[email protected]94f206c12012-08-25 00:09:141373
[email protected]c1bb5af2013-03-13 19:06:271374 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1375 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271376
[email protected]c1bb5af2013-03-13 19:06:271377 layout_viewport_size_ = layout_viewport_size;
1378 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141379
[email protected]c1bb5af2013-03-13 19:06:271380 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141381
[email protected]c1bb5af2013-03-13 19:06:271382 if (renderer_)
1383 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211384
[email protected]c1bb5af2013-03-13 19:06:271385 client_->OnCanDrawStateChanged(CanDraw());
[email protected]94f206c12012-08-25 00:09:141386}
1387
[email protected]c1bb5af2013-03-13 19:06:271388static void AdjustScrollsForPageScaleChange(LayerImpl* layer_impl,
1389 float page_scale_change) {
1390 if (!layer_impl)
1391 return;
[email protected]94f206c12012-08-25 00:09:141392
[email protected]c1bb5af2013-03-13 19:06:271393 if (layer_impl->scrollable()) {
1394 // We need to convert impl-side scroll deltas to page_scale space.
1395 gfx::Vector2dF scroll_delta = layer_impl->scroll_delta();
1396 scroll_delta.Scale(page_scale_change);
1397 layer_impl->SetScrollDelta(scroll_delta);
1398 }
[email protected]94f206c12012-08-25 00:09:141399
[email protected]c1bb5af2013-03-13 19:06:271400 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1401 AdjustScrollsForPageScaleChange(layer_impl->children()[i],
1402 page_scale_change);
[email protected]94f206c12012-08-25 00:09:141403}
1404
[email protected]d9083762013-03-24 01:36:401405void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) {
1406 if (overdraw_bottom_height == overdraw_bottom_height_)
1407 return;
1408 overdraw_bottom_height_ = overdraw_bottom_height;
1409
1410 UpdateMaxScrollOffset();
1411}
1412
[email protected]c1bb5af2013-03-13 19:06:271413void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1414 if (device_scale_factor == device_scale_factor_)
1415 return;
1416 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271417
[email protected]c1bb5af2013-03-13 19:06:271418 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141419}
1420
[email protected]c1bb5af2013-03-13 19:06:271421void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1422 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141423}
1424
[email protected]c1bb5af2013-03-13 19:06:271425void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() {
1426 active_tree_->set_needs_update_draw_properties();
[email protected]3ba4cae2013-01-16 03:58:381427}
1428
[email protected]c1bb5af2013-03-13 19:06:271429void LayerTreeHostImpl::setNeedsRedraw() {
1430 client_->SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:141431}
1432
[email protected]c1bb5af2013-03-13 19:06:271433bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1434 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
[email protected]3209161d2013-03-29 19:17:341435 return !active_tree_->RenderSurfaceLayerList().empty();
[email protected]94f206c12012-08-25 00:09:141436}
1437
[email protected]c1bb5af2013-03-13 19:06:271438InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1439 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
[email protected]ed511b8d2013-03-25 03:29:291440 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
[email protected]94f206c12012-08-25 00:09:141441
[email protected]c1bb5af2013-03-13 19:06:271442 if (top_controls_manager_)
1443 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381444
[email protected]c1bb5af2013-03-13 19:06:271445 DCHECK(!CurrentlyScrollingLayer());
1446 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141447
[email protected]c1bb5af2013-03-13 19:06:271448 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141449 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141450
[email protected]c1bb5af2013-03-13 19:06:271451 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1452 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141453
[email protected]c1bb5af2013-03-13 19:06:271454 // First find out which layer was hit from the saved list of visible layers
1455 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:391456 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:271457 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521458
[email protected]c1bb5af2013-03-13 19:06:271459 // Walk up the hierarchy and look for a scrollable layer.
1460 LayerImpl* potentially_scrolling_layer_impl = 0;
1461 for (; layer_impl; layer_impl = layer_impl->parent()) {
1462 // The content layer can also block attempts to scroll outside the main
1463 // thread.
1464 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1465 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431466 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271467 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421468 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271469 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141470 }
1471
[email protected]c1bb5af2013-03-13 19:06:271472 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1473 if (!scroll_layer_impl)
1474 continue;
[email protected]94f206c12012-08-25 00:09:141475
[email protected]c1bb5af2013-03-13 19:06:271476 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141477
[email protected]c1bb5af2013-03-13 19:06:271478 // If any layer wants to divert the scroll event to the main thread, abort.
1479 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431480 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271481 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421482 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271483 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141484 }
1485
[email protected]c1bb5af2013-03-13 19:06:271486 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1487 potentially_scrolling_layer_impl = scroll_layer_impl;
1488 }
1489
1490 // When hiding top controls is enabled and the controls are hidden or
1491 // overlaying the content, force scrolls to be enabled on the root layer to
1492 // allow bringing the top controls back into view.
1493 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1494 top_controls_manager_->content_top_offset() !=
[email protected]8e0176d2013-03-21 03:14:521495 settings_.top_controls_height) {
[email protected]c1bb5af2013-03-13 19:06:271496 potentially_scrolling_layer_impl = RootScrollLayer();
1497 }
1498
1499 if (potentially_scrolling_layer_impl) {
[email protected]0fc818e2013-03-18 06:45:201500 active_tree_->SetCurrentlyScrollingLayer(
[email protected]c1bb5af2013-03-13 19:06:271501 potentially_scrolling_layer_impl);
1502 should_bubble_scrolls_ = (type != NonBubblingGesture);
1503 wheel_scrolling_ = (type == Wheel);
[email protected]372bad5f2013-03-21 16:38:431504 rendering_stats_instrumentation_->IncrementImplThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271505 client_->RenewTreePriority();
1506 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421507 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271508 return ScrollStarted;
1509 }
1510 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141511}
1512
[email protected]c1bb5af2013-03-13 19:06:271513gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1514 LayerImpl* layer_impl,
1515 float scale_from_viewport_to_screen_space,
1516 gfx::PointF viewport_point,
1517 gfx::Vector2dF viewport_delta) {
1518 // Layers with non-invertible screen space transforms should not have passed
1519 // the scroll hit test in the first place.
1520 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1521 gfx::Transform inverse_screen_space_transform(
1522 gfx::Transform::kSkipInitialization);
1523 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1524 &inverse_screen_space_transform);
[email protected]ca2902e92013-03-28 01:45:351525 // TODO(shawnsingh): With the advent of impl-side crolling for non-root
1526 // layers, we may need to explicitly handle uninvertible transforms here.
[email protected]c1bb5af2013-03-13 19:06:271527 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141528
[email protected]c1bb5af2013-03-13 19:06:271529 gfx::PointF screen_space_point =
1530 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141531
[email protected]c1bb5af2013-03-13 19:06:271532 gfx::Vector2dF screen_space_delta = viewport_delta;
1533 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1534
1535 // First project the scroll start and end points to local layer space to find
1536 // the scroll delta in layer coordinates.
1537 bool start_clipped, end_clipped;
1538 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1539 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211540 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271541 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211542 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271543 gfx::PointF local_end_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_end_point,
[email protected]fa816c62013-03-18 04:24:211546 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271547
1548 // In general scroll point coordinates should not get clipped.
1549 DCHECK(!start_clipped);
1550 DCHECK(!end_clipped);
1551 if (start_clipped || end_clipped)
1552 return gfx::Vector2dF();
1553
1554 // local_start_point and local_end_point are in content space but we want to
1555 // move them to layer space for scrolling.
1556 float width_scale = 1.f / layer_impl->contents_scale_x();
1557 float height_scale = 1.f / layer_impl->contents_scale_y();
1558 local_start_point.Scale(width_scale, height_scale);
1559 local_end_point.Scale(width_scale, height_scale);
1560
1561 // Apply the scroll delta.
1562 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1563 layer_impl->ScrollBy(local_end_point - local_start_point);
1564
1565 // Get the end point in the layer's content space so we can apply its
1566 // ScreenSpaceTransform.
1567 gfx::PointF actual_local_end_point = local_start_point +
1568 layer_impl->scroll_delta() -
1569 previous_delta;
1570 gfx::PointF actual_local_content_end_point =
1571 gfx::ScalePoint(actual_local_end_point,
1572 1.f / width_scale,
1573 1.f / height_scale);
1574
1575 // Calculate the applied scroll delta in viewport space coordinates.
1576 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211577 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271578 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211579 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271580 DCHECK(!end_clipped);
1581 if (end_clipped)
1582 return gfx::Vector2dF();
1583 gfx::PointF actual_viewport_end_point =
1584 gfx::ScalePoint(actual_screen_space_end_point,
1585 1.f / scale_from_viewport_to_screen_space);
1586 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141587}
1588
[email protected]c1bb5af2013-03-13 19:06:271589static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1590 gfx::Vector2dF local_delta) {
1591 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1592 layer_impl->ScrollBy(local_delta);
1593 return layer_impl->scroll_delta() - previous_delta;
1594}
1595
1596bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1597 gfx::Vector2dF scroll_delta) {
1598 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1599 if (!CurrentlyScrollingLayer())
1600 return false;
1601
1602 gfx::Vector2dF pending_delta = scroll_delta;
1603 bool did_scroll = false;
[email protected]60b4d252013-03-23 18:49:421604 bool consume_by_top_controls = top_controls_manager_ &&
1605 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0);
[email protected]a91e4f82013-03-15 06:58:061606
[email protected]c1bb5af2013-03-13 19:06:271607 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1608 layer_impl;
1609 layer_impl = layer_impl->parent()) {
1610 if (!layer_impl->scrollable())
1611 continue;
1612
[email protected]60b4d252013-03-23 18:49:421613 // Only allow bubble scrolling when the scroll is in the direction to make
1614 // the top controls visible.
1615 if (consume_by_top_controls && layer_impl == RootScrollLayer()) {
1616 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
1617 UpdateMaxScrollOffset();
1618 }
1619
[email protected]c1bb5af2013-03-13 19:06:271620 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271621 // Gesture events need to be transformed from viewport coordinates to local
1622 // layer coordinates so that the scrolling contents exactly follow the
1623 // user's finger. In contrast, wheel events represent a fixed amount of
1624 // scrolling so we can just apply them directly.
1625 if (!wheel_scrolling_) {
1626 float scale_from_viewport_to_screen_space = device_scale_factor_;
1627 applied_delta =
1628 ScrollLayerWithViewportSpaceDelta(layer_impl,
1629 scale_from_viewport_to_screen_space,
1630 viewport_point, pending_delta);
1631 } else {
1632 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141633 }
[email protected]94f206c12012-08-25 00:09:141634
[email protected]c1bb5af2013-03-13 19:06:271635 // If the layer wasn't able to move, try the next one in the hierarchy.
1636 float move_threshold_squared = 0.1f * 0.1f;
1637 if (applied_delta.LengthSquared() < move_threshold_squared) {
1638 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1639 continue;
1640 else
1641 break;
[email protected]94f206c12012-08-25 00:09:141642 }
[email protected]c1bb5af2013-03-13 19:06:271643 did_scroll = true;
1644 did_lock_scrolling_layer_ = true;
1645 if (!should_bubble_scrolls_) {
[email protected]0fc818e2013-03-18 06:45:201646 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
[email protected]c1bb5af2013-03-13 19:06:271647 break;
[email protected]94f206c12012-08-25 00:09:141648 }
[email protected]94f206c12012-08-25 00:09:141649
[email protected]c1bb5af2013-03-13 19:06:271650 // If the applied delta is within 45 degrees of the input delta, bail out to
1651 // make it easier to scroll just one layer in one direction without
1652 // affecting any of its parents.
1653 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211654 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271655 applied_delta, pending_delta) < angle_threshold) {
1656 pending_delta = gfx::Vector2d();
1657 break;
[email protected]4a23c374c2012-12-08 08:38:551658 }
[email protected]c1bb5af2013-03-13 19:06:271659
1660 // Allow further movement only on an axis perpendicular to the direction in
1661 // which the layer moved.
1662 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211663 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271664
1665 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1666 break;
1667 }
1668
[email protected]b7c4783f2013-03-15 23:11:421669 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271670 if (did_scroll) {
1671 client_->SetNeedsCommitOnImplThread();
1672 client_->SetNeedsRedrawOnImplThread();
1673 client_->RenewTreePriority();
1674 }
1675 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551676}
1677
[email protected]be782f52013-03-23 21:36:141678// This implements scrolling by page as described here:
1679// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel
1680// for events with WHEEL_PAGESCROLL set.
1681bool LayerTreeHostImpl::ScrollVerticallyByPage(
1682 gfx::Point viewport_point,
1683 WebKit::WebScrollbar::ScrollDirection direction) {
1684 DCHECK(wheel_scrolling_);
1685
1686 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1687 layer_impl;
1688 layer_impl = layer_impl->parent()) {
1689 if (!layer_impl->scrollable())
1690 continue;
1691
1692 if (!layer_impl->vertical_scrollbar_layer())
1693 continue;
1694
1695 float height = layer_impl->vertical_scrollbar_layer()->bounds().height();
1696
1697 // These magical values match WebKit and are designed to scroll nearly the
1698 // entire visible content height but leave a bit of overlap.
1699 float page = std::max(height * 0.875f, 1.f);
1700 if (direction == WebKit::WebScrollbar::ScrollBackward)
1701 page = -page;
1702
1703 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page);
1704
1705 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta);
1706
1707 if (!applied_delta.IsZero()) {
1708 active_tree()->DidUpdateScroll();
1709 client_->SetNeedsCommitOnImplThread();
1710 client_->SetNeedsRedrawOnImplThread();
1711 client_->RenewTreePriority();
1712 return true;
1713 }
1714
1715 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
1716 }
1717
1718 return false;
1719}
1720
[email protected]c1bb5af2013-03-13 19:06:271721void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1722 active_tree_->ClearCurrentlyScrollingLayer();
1723 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141724}
1725
[email protected]c1bb5af2013-03-13 19:06:271726void LayerTreeHostImpl::ScrollEnd() {
1727 if (top_controls_manager_)
1728 top_controls_manager_->ScrollEnd();
1729 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421730 active_tree()->DidEndScroll();
[email protected]0fc818e2013-03-18 06:45:201731 StartScrollbarAnimation(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141732}
1733
[email protected]c1bb5af2013-03-13 19:06:271734void LayerTreeHostImpl::PinchGestureBegin() {
1735 pinch_gesture_active_ = true;
1736 previous_pinch_anchor_ = gfx::Point();
1737 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141738}
1739
[email protected]c1bb5af2013-03-13 19:06:271740void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1741 gfx::Point anchor) {
1742 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281743
[email protected]c1bb5af2013-03-13 19:06:271744 if (!RootScrollLayer())
1745 return;
[email protected]d3afa112012-12-08 06:24:281746
[email protected]c1bb5af2013-03-13 19:06:271747 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1748 // position over the course of the magnify.
1749 float page_scale_delta = active_tree_->page_scale_delta();
1750 gfx::PointF previous_scale_anchor =
1751 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1752 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1753 page_scale_delta = active_tree_->page_scale_delta();
1754 gfx::PointF new_scale_anchor =
1755 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1756 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1757
1758 previous_pinch_anchor_ = anchor;
1759
1760 move.Scale(1 / active_tree_->page_scale_factor());
1761
1762 RootScrollLayer()->ScrollBy(move);
1763
[email protected]c1bb5af2013-03-13 19:06:271764 client_->SetNeedsCommitOnImplThread();
1765 client_->SetNeedsRedrawOnImplThread();
1766 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281767}
1768
[email protected]c1bb5af2013-03-13 19:06:271769void LayerTreeHostImpl::PinchGestureEnd() {
1770 pinch_gesture_active_ = false;
[email protected]c1bb5af2013-03-13 19:06:271771 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141772}
1773
[email protected]c1bb5af2013-03-13 19:06:271774static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1775 LayerImpl* layer_impl) {
1776 if (!layer_impl)
1777 return;
[email protected]94f206c12012-08-25 00:09:141778
[email protected]c1bb5af2013-03-13 19:06:271779 gfx::Vector2d scroll_delta =
1780 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1781 if (!scroll_delta.IsZero()) {
1782 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]6ba914122013-03-22 16:26:391783 scroll.layer_id = layer_impl->id();
1784 scroll.scroll_delta = scroll_delta;
[email protected]c1bb5af2013-03-13 19:06:271785 scroll_info->scrolls.push_back(scroll);
1786 layer_impl->SetSentScrollDelta(scroll_delta);
1787 }
[email protected]94f206c12012-08-25 00:09:141788
[email protected]c1bb5af2013-03-13 19:06:271789 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1790 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141791}
1792
[email protected]c1bb5af2013-03-13 19:06:271793scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1794 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301795
[email protected]c1bb5af2013-03-13 19:06:271796 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
[email protected]6ba914122013-03-22 16:26:391797 scroll_info->page_scale_delta = active_tree_->page_scale_delta();
1798 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
[email protected]362f1e8b2013-01-21 16:54:301799
[email protected]c1bb5af2013-03-13 19:06:271800 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301801}
1802
[email protected]c1bb5af2013-03-13 19:06:271803void LayerTreeHostImpl::SetFullRootLayerDamage() {
[email protected]e0341352013-04-06 05:01:201804 next_frame_damages_full_device_viewport_ = true;
[email protected]829ad972013-01-28 23:36:101805}
1806
[email protected]c1bb5af2013-03-13 19:06:271807void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1808 if (!page_scale_animation_ || !RootScrollLayer())
1809 return;
1810
1811 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1812 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1813 RootScrollLayer()->scroll_delta();
1814
1815 active_tree_->SetPageScaleDelta(
1816 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1817 active_tree_->page_scale_factor());
1818 gfx::Vector2dF next_scroll =
1819 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1820
1821 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1822 client_->SetNeedsRedrawOnImplThread();
1823
1824 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1825 page_scale_animation_.reset();
1826 client_->SetNeedsCommitOnImplThread();
1827 client_->RenewTreePriority();
1828 }
[email protected]829ad972013-01-28 23:36:101829}
1830
[email protected]ffb2720f2013-03-15 19:18:371831void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1832 if (!top_controls_manager_ || !RootScrollLayer())
1833 return;
1834 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1835 UpdateMaxScrollOffset();
1836 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1837 scroll, 1.f / active_tree_->total_page_scale_factor()));
1838}
1839
[email protected]c1bb5af2013-03-13 19:06:271840void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1841 base::Time wall_clock_time) {
[email protected]8e0176d2013-03-21 03:14:521842 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271843 animation_registrar_->active_animation_controllers().empty() ||
1844 !active_tree_->root_layer())
1845 return;
1846
1847 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1848
1849 last_animation_time_ = wall_clock_time;
1850 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1851
1852 AnimationRegistrar::AnimationControllerMap copy =
1853 animation_registrar_->active_animation_controllers();
1854 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1855 iter != copy.end();
1856 ++iter)
1857 (*iter).second->Animate(monotonic_seconds);
1858
1859 client_->SetNeedsRedrawOnImplThread();
[email protected]131a0c22013-02-12 18:31:081860}
1861
[email protected]3d9f7432013-04-06 00:35:181862void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
[email protected]8e0176d2013-03-21 03:14:521863 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271864 animation_registrar_->active_animation_controllers().empty() ||
1865 !active_tree_->root_layer())
1866 return;
1867
1868 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1869 scoped_ptr<AnimationEventsVector> events =
1870 make_scoped_ptr(new AnimationEventsVector);
1871 AnimationRegistrar::AnimationControllerMap copy =
1872 animation_registrar_->active_animation_controllers();
1873 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1874 iter != copy.end();
1875 ++iter)
[email protected]3d9f7432013-04-06 00:35:181876 (*iter).second->UpdateState(start_ready_animations, events.get());
[email protected]c1bb5af2013-03-13 19:06:271877
1878 if (!events->empty()) {
1879 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1880 last_animation_time_);
1881 }
[email protected]131a0c22013-02-12 18:31:081882}
1883
[email protected]c1bb5af2013-03-13 19:06:271884base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1885 return base::TimeDelta::FromSeconds(1);
1886}
1887
1888void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1889 DCHECK(current);
1890 current->DidLoseOutputSurface();
1891 if (current->mask_layer())
1892 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1893 if (current->replica_layer())
1894 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1895 for (size_t i = 0; i < current->children().size(); ++i)
1896 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1897}
1898
1899void LayerTreeHostImpl::ClearRenderSurfaces() {
1900 active_tree_->ClearRenderSurfaces();
1901 if (pending_tree_)
1902 pending_tree_->ClearRenderSurfaces();
1903}
1904
1905std::string LayerTreeHostImpl::LayerTreeAsText() const {
1906 std::string str;
1907 if (active_tree_->root_layer()) {
1908 str = active_tree_->root_layer()->LayerTreeAsText();
1909 str += "RenderSurfaces:\n";
1910 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1911 }
1912 return str;
1913}
1914
1915std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1916 std::string str;
1917 if (active_tree_->root_layer()) {
1918 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1919 base::JSONWriter::WriteWithOptions(
1920 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1921 }
1922 return str;
1923}
1924
1925void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1926 int indent,
1927 const LayerImpl* layer) const {
1928 if (layer->render_surface())
1929 layer->render_surface()->DumpSurface(str, indent);
1930
1931 for (size_t i = 0; i < layer->children().size(); ++i)
1932 DumpRenderSurfaces(str, indent, layer->children()[i]);
1933}
1934
1935int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:361936 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:271937}
1938
[email protected]c1bb5af2013-03-13 19:06:271939void LayerTreeHostImpl::SendManagedMemoryStats(
1940 size_t memory_visible_bytes,
1941 size_t memory_visible_and_nearby_bytes,
1942 size_t memory_use_bytes) {
1943 if (!renderer_)
1944 return;
1945
1946 // Round the numbers being sent up to the next 8MB, to throttle the rate
1947 // at which we spam the GPU process.
1948 static const size_t rounding_step = 8 * 1024 * 1024;
1949 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1950 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1951 rounding_step);
1952 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1953 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1954 last_sent_memory_visible_and_nearby_bytes_ ==
1955 memory_visible_and_nearby_bytes &&
1956 last_sent_memory_use_bytes_ == memory_use_bytes) {
1957 return;
1958 }
1959 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1960 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1961 last_sent_memory_use_bytes_ = memory_use_bytes;
1962
1963 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
1964 last_sent_memory_visible_and_nearby_bytes_,
1965 last_sent_memory_use_bytes_);
1966}
1967
1968void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
1969 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
1970}
1971
1972void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
1973 base::TimeTicks time) {
1974 if (!layer)
1975 return;
1976
1977 ScrollbarAnimationController* scrollbar_controller =
1978 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:351979 if (scrollbar_controller && scrollbar_controller->Animate(time)) {
[email protected]0fc818e2013-03-18 06:45:201980 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:421981 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
1982 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:271983 client_->SetNeedsRedrawOnImplThread();
[email protected]0fc818e2013-03-18 06:45:201984 }
[email protected]c1bb5af2013-03-13 19:06:271985
1986 for (size_t i = 0; i < layer->children().size(); ++i)
1987 AnimateScrollbarsRecursive(layer->children()[i], time);
1988}
1989
[email protected]0fc818e2013-03-18 06:45:201990void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time) {
1991 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
1992 StartScrollbarAnimationRecursive(RootLayer(), time);
1993}
1994
1995void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
1996 base::TimeTicks time) {
1997 if (!layer)
1998 return;
1999
2000 ScrollbarAnimationController* scrollbar_controller =
2001 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352002 if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
2003 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
[email protected]0fc818e2013-03-18 06:45:202004 if (delay > base::TimeDelta())
2005 client_->RequestScrollbarAnimationOnImplThread(delay);
[email protected]6bc09e82013-03-19 03:48:352006 else if (scrollbar_controller->Animate(time))
[email protected]0fc818e2013-03-18 06:45:202007 client_->SetNeedsRedrawOnImplThread();
2008 }
2009
2010 for (size_t i = 0; i < layer->children().size(); ++i)
2011 StartScrollbarAnimationRecursive(layer->children()[i], time);
2012}
2013
[email protected]c1bb5af2013-03-13 19:06:272014void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
2015 if (!tile_manager_)
2016 return;
2017
2018 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
2019 if (new_state.tree_priority == priority)
2020 return;
2021
2022 new_state.tree_priority = priority;
2023 tile_manager_->SetGlobalState(new_state);
2024}
2025
2026void LayerTreeHostImpl::BeginNextFrame() {
2027 current_frame_time_ = base::TimeTicks();
2028}
2029
2030base::TimeTicks LayerTreeHostImpl::CurrentFrameTime() {
2031 if (current_frame_time_.is_null())
2032 current_frame_time_ = base::TimeTicks::Now();
2033 return current_frame_time_;
2034}
2035
2036scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
2037 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
2038 state->Set("activation_state", ActivationStateAsValue().release());
2039 state->Set("frame_state", FrameStateAsValue().release());
2040 return state.PassAs<base::Value>();
2041}
2042
2043scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
2044 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042045 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272046 state->SetBoolean("visible_resources_ready",
2047 pending_tree_->AreVisibleResourcesReady());
2048 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
2049 return state.PassAs<base::Value>();
2050}
2051
2052scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
2053 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042054 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272055 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:212056 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:272057 if (tile_manager_)
2058 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
2059 state->Set("active_tree", active_tree_->AsValue().release());
2060 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:082061}
2062
[email protected]b9dcf43a2013-01-09 00:15:292063// static
[email protected]c1bb5af2013-03-13 19:06:272064LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
2065 LayerImpl* layer) {
2066 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:292067 return NULL;
[email protected]c1bb5af2013-03-13 19:06:272068
2069 if (layer->DrawsContent())
2070 return layer;
2071
[email protected]50761e92013-03-29 20:51:282072 for (LayerImplList::const_iterator it = layer->children().begin();
[email protected]c1bb5af2013-03-13 19:06:272073 it != layer->children().end(); ++it) {
2074 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
2075 if (nccr)
2076 return nccr;
2077 }
2078
2079 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:292080}
2081
[email protected]c1bb5af2013-03-13 19:06:272082skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
2083 LayerTreeImpl* tree =
2084 pending_tree_ ? pending_tree_.get() : active_tree_.get();
2085 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
2086 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:292087}
2088
[email protected]c1bb5af2013-03-13 19:06:272089void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
[email protected]846f455b2013-03-18 19:07:412090 if (debug_state_.continuous_painting != debug_state.continuous_painting)
[email protected]c1bb5af2013-03-13 19:06:272091 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:242092
[email protected]c1bb5af2013-03-13 19:06:272093 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:022094}
2095
[email protected]d3143c732012-10-05 19:17:592096} // namespace cc