blob: a96608952e5dde5824227e42ee3184b2f741a01e [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]85d136f782013-04-26 22:04:4016#include "cc/animation/timing_function.h"
[email protected]681ccff2013-03-18 06:13:5217#include "cc/base/math_util.h"
18#include "cc/base/util.h"
[email protected]6e84de22013-03-18 06:54:2719#include "cc/debug/debug_rect_history.h"
20#include "cc/debug/frame_rate_counter.h"
21#include "cc/debug/overdraw_metrics.h"
22#include "cc/debug/paint_time_counter.h"
[email protected]372bad5f2013-03-21 16:38:4323#include "cc/debug/rendering_stats_instrumentation.h"
[email protected]3052b10f2013-03-18 07:41:2124#include "cc/input/page_scale_animation.h"
25#include "cc/input/top_controls_manager.h"
[email protected]cc3cfaa2013-03-18 09:05:5226#include "cc/layers/append_quads_data.h"
27#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]50761e92013-03-29 20:51:2828#include "cc/layers/layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5229#include "cc/layers/layer_iterator.h"
[email protected]50761e92013-03-29 20:51:2830#include "cc/layers/render_surface_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5231#include "cc/layers/scrollbar_layer_impl.h"
[email protected]7f0d825f2013-03-18 07:24:3032#include "cc/output/compositor_frame_metadata.h"
33#include "cc/output/delegating_renderer.h"
34#include "cc/output/gl_renderer.h"
35#include "cc/output/software_renderer.h"
[email protected]89e82672013-03-18 07:50:5636#include "cc/quads/render_pass_draw_quad.h"
37#include "cc/quads/shared_quad_state.h"
38#include "cc/quads/solid_color_draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4039#include "cc/resources/memory_history.h"
40#include "cc/resources/picture_layer_tiling.h"
41#include "cc/resources/prioritized_resource_manager.h"
[email protected]be4655a2013-03-18 08:36:3142#include "cc/scheduler/delay_based_time_source.h"
43#include "cc/scheduler/texture_uploader.h"
[email protected]556fd292013-03-18 08:03:0444#include "cc/trees/damage_tracker.h"
45#include "cc/trees/layer_tree_host.h"
46#include "cc/trees/layer_tree_host_common.h"
47#include "cc/trees/layer_tree_impl.h"
48#include "cc/trees/quad_culler.h"
49#include "cc/trees/single_thread_proxy.h"
50#include "cc/trees/tree_synchronizer.h"
[email protected]d455d552012-11-02 00:19:0651#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1352#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1453
[email protected]94f206c12012-08-25 00:09:1454namespace {
55
[email protected]c1bb5af2013-03-13 19:06:2756void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) {
57 if (visible) {
58 TRACE_EVENT_ASYNC_BEGIN1("webkit",
59 "LayerTreeHostImpl::SetVisible",
60 id,
61 "LayerTreeHostImpl",
62 id);
63 return;
64 }
[email protected]94f206c12012-08-25 00:09:1465
[email protected]c1bb5af2013-03-13 19:06:2766 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id);
[email protected]94f206c12012-08-25 00:09:1467}
68
[email protected]c1bb5af2013-03-13 19:06:2769std::string ValueToString(scoped_ptr<base::Value> value) {
70 std::string str;
71 base::JSONWriter::Write(value.get(), &str);
72 return str;
[email protected]131a0c22013-02-12 18:31:0873}
74
[email protected]c1bb5af2013-03-13 19:06:2775} // namespace
[email protected]94f206c12012-08-25 00:09:1476
[email protected]9c88e562012-09-14 22:21:3077namespace cc {
[email protected]94f206c12012-08-25 00:09:1478
[email protected]96baf3e2012-10-22 23:09:5579class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]c1bb5af2013-03-13 19:06:2780 public:
81 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
82 LayerTreeHostImpl* layer_tree_host_impl,
83 scoped_refptr<DelayBasedTimeSource> time_source) {
84 return make_scoped_ptr(
85 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
86 time_source));
87 }
88 virtual ~LayerTreeHostImplTimeSourceAdapter() {
[email protected]6d0e69d2013-03-20 14:53:2689 time_source_->SetClient(NULL);
90 time_source_->SetActive(false);
[email protected]c1bb5af2013-03-13 19:06:2791 }
92
[email protected]6d0e69d2013-03-20 14:53:2693 virtual void OnTimerTick() OVERRIDE {
[email protected]c1bb5af2013-03-13 19:06:2794 // In single threaded mode we attempt to simulate changing the current
95 // thread by maintaining a fake thread id. When we switch from one
96 // thread to another, we construct DebugScopedSetXXXThread objects that
97 // update the thread id. This lets DCHECKS that ensure we're on the
98 // right thread to work correctly in single threaded mode. The problem
99 // here is that the timer tasks are run via the message loop, and when
100 // they run, we've had no chance to construct a DebugScopedSetXXXThread
101 // object. The result is that we report that we're running on the main
102 // thread. In multi-threaded mode, this timer is run on the compositor
103 // thread, so to keep this consistent in single-threaded mode, we'll
104 // construct a DebugScopedSetImplThread object. There is no need to do
105 // this in multi-threaded mode since the real thread id's will be
106 // correct. In fact, setting fake thread id's interferes with the real
107 // thread id's and causes breakage.
108 scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
109 if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
110 set_impl_thread.reset(
111 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
[email protected]94f206c12012-08-25 00:09:14112 }
113
[email protected]c1bb5af2013-03-13 19:06:27114 layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
[email protected]fb7425a2013-04-22 16:28:55115 layer_tree_host_impl_->Animate(
116 layer_tree_host_impl_->CurrentFrameTimeTicks(),
117 layer_tree_host_impl_->CurrentFrameTime());
[email protected]3d9f7432013-04-06 00:35:18118 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
119 bool start_ready_animations = true;
120 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]c1bb5af2013-03-13 19:06:27121 layer_tree_host_impl_->BeginNextFrame();
122 }
[email protected]373974232013-01-10 22:20:50123
[email protected]c1bb5af2013-03-13 19:06:27124 void SetActive(bool active) {
[email protected]6d0e69d2013-03-20 14:53:26125 if (active != time_source_->Active())
126 time_source_->SetActive(active);
[email protected]c1bb5af2013-03-13 19:06:27127 }
[email protected]94f206c12012-08-25 00:09:14128
[email protected]c1bb5af2013-03-13 19:06:27129 private:
130 LayerTreeHostImplTimeSourceAdapter(
131 LayerTreeHostImpl* layer_tree_host_impl,
132 scoped_refptr<DelayBasedTimeSource> time_source)
133 : layer_tree_host_impl_(layer_tree_host_impl),
134 time_source_(time_source) {
[email protected]6d0e69d2013-03-20 14:53:26135 time_source_->SetClient(this);
[email protected]c1bb5af2013-03-13 19:06:27136 }
[email protected]94f206c12012-08-25 00:09:14137
[email protected]c1bb5af2013-03-13 19:06:27138 LayerTreeHostImpl* layer_tree_host_impl_;
139 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14140
[email protected]c1bb5af2013-03-13 19:06:27141 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14142};
143
[email protected]96baf3e2012-10-22 23:09:55144LayerTreeHostImpl::FrameData::FrameData()
[email protected]e0341352013-04-06 05:01:20145 : contains_incomplete_tile(false), has_no_damage(false) {}
[email protected]c1bb5af2013-03-13 19:06:27146
147LayerTreeHostImpl::FrameData::~FrameData() {}
148
149scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
150 const LayerTreeSettings& settings,
151 LayerTreeHostImplClient* client,
[email protected]372bad5f2013-03-21 16:38:43152 Proxy* proxy,
153 RenderingStatsInstrumentation* rendering_stats_instrumentation) {
154 return make_scoped_ptr(
155 new LayerTreeHostImpl(settings,
156 client,
157 proxy,
158 rendering_stats_instrumentation));
[email protected]493067512012-09-19 23:34:10159}
160
[email protected]372bad5f2013-03-21 16:38:43161LayerTreeHostImpl::LayerTreeHostImpl(
162 const LayerTreeSettings& settings,
163 LayerTreeHostImplClient* client,
164 Proxy* proxy,
165 RenderingStatsInstrumentation* rendering_stats_instrumentation)
[email protected]c1bb5af2013-03-13 19:06:27166 : client_(client),
167 proxy_(proxy),
168 did_lock_scrolling_layer_(false),
169 should_bubble_scrolls_(false),
170 wheel_scrolling_(false),
171 settings_(settings),
[email protected]d9083762013-03-24 01:36:40172 overdraw_bottom_height_(0.f),
[email protected]c1bb5af2013-03-13 19:06:27173 device_scale_factor_(1.f),
174 visible_(true),
175 managed_memory_policy_(
[email protected]b56c1302013-03-20 21:17:34176 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
[email protected]c1bb5af2013-03-13 19:06:27177 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
178 0,
179 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
180 pinch_gesture_active_(false),
[email protected]9e3594522013-03-18 00:57:36181 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29182 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27183 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02184 debug_rect_history_(DebugRectHistory::Create()),
[email protected]d7626ffd2013-03-29 00:17:42185 max_memory_needed_bytes_(0),
[email protected]c1bb5af2013-03-13 19:06:27186 last_sent_memory_visible_bytes_(0),
187 last_sent_memory_visible_and_nearby_bytes_(0),
188 last_sent_memory_use_bytes_(0),
[email protected]372bad5f2013-03-21 16:38:43189 animation_registrar_(AnimationRegistrar::Create()),
190 rendering_stats_instrumentation_(rendering_stats_instrumentation) {
[email protected]c1bb5af2013-03-13 19:06:27191 DCHECK(proxy_->IsImplThread());
192 DidVisibilityChange(this, visible_);
193
[email protected]8e0176d2013-03-21 03:14:52194 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27195
[email protected]8e0176d2013-03-21 03:14:52196 if (settings.calculate_top_controls_position) {
[email protected]c1bb5af2013-03-13 19:06:27197 top_controls_manager_ =
198 TopControlsManager::Create(this,
[email protected]8e0176d2013-03-21 03:14:52199 settings.top_controls_height,
200 settings.top_controls_show_threshold,
201 settings.top_controls_hide_threshold);
[email protected]c1bb5af2013-03-13 19:06:27202 }
203
[email protected]8e0176d2013-03-21 03:14:52204 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27205
206 // LTHI always has an active tree.
207 active_tree_ = LayerTreeImpl::create(this);
[email protected]493067512012-09-19 23:34:10208}
209
[email protected]c1bb5af2013-03-13 19:06:27210LayerTreeHostImpl::~LayerTreeHostImpl() {
211 DCHECK(proxy_->IsImplThread());
212 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
213
214 if (active_tree_->root_layer()) {
215 ClearRenderSurfaces();
216 // The layer trees must be destroyed before the layer tree host. We've
217 // made a contract with our animation controllers that the registrar
218 // will outlive them, and we must make good.
219 recycle_tree_.reset();
220 pending_tree_.reset();
221 active_tree_.reset();
222 }
[email protected]94f206c12012-08-25 00:09:14223}
224
[email protected]c1bb5af2013-03-13 19:06:27225void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29226
[email protected]c1bb5af2013-03-13 19:06:27227void LayerTreeHostImpl::CommitComplete() {
228 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08229
[email protected]c1bb5af2013-03-13 19:06:27230 // Impl-side painting needs an update immediately post-commit to have the
231 // opportunity to create tilings. Other paths can call UpdateDrawProperties
232 // more lazily when needed prior to drawing.
[email protected]8e0176d2013-03-21 03:14:52233 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:27234 pending_tree_->set_needs_update_draw_properties();
235 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
236 } else {
237 active_tree_->set_needs_update_draw_properties();
238 }
[email protected]3ba4cae2013-01-16 03:58:38239
[email protected]c1bb5af2013-03-13 19:06:27240 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14241}
242
[email protected]c1bb5af2013-03-13 19:06:27243bool LayerTreeHostImpl::CanDraw() {
244 // Note: If you are changing this function or any other function that might
245 // affect the result of CanDraw, make sure to call
246 // client_->OnCanDrawStateChanged in the proper places and update the
247 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14248
[email protected]c1bb5af2013-03-13 19:06:27249 if (!active_tree_->root_layer()) {
[email protected]c76faea2013-03-26 07:42:42250 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
251 TRACE_EVENT_SCOPE_THREAD);
[email protected]2f1acc262012-11-16 21:42:22252 return false;
[email protected]c1bb5af2013-03-13 19:06:27253 }
254 if (device_viewport_size_.IsEmpty()) {
[email protected]c76faea2013-03-26 07:42:42255 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
256 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27257 return false;
258 }
259 if (active_tree_->ViewportSizeInvalid()) {
260 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42261 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed",
262 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27263 return false;
264 }
265 if (!renderer_) {
[email protected]c76faea2013-03-26 07:42:42266 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer",
267 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27268 return false;
269 }
270 if (active_tree_->ContentsTexturesPurged()) {
271 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42272 "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
273 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27274 return false;
275 }
276 return true;
[email protected]2f1acc262012-11-16 21:42:22277}
278
[email protected]c1bb5af2013-03-13 19:06:27279void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
280 base::Time wall_clock_time) {
281 AnimatePageScale(monotonic_time);
282 AnimateLayers(monotonic_time, wall_clock_time);
283 AnimateScrollbars(monotonic_time);
[email protected]ffb2720f2013-03-15 19:18:37284 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14285}
286
[email protected]c1bb5af2013-03-13 19:06:27287void LayerTreeHostImpl::ManageTiles() {
288 DCHECK(tile_manager_);
289 tile_manager_->ManageTiles();
290
291 size_t memory_required_bytes;
292 size_t memory_nice_to_have_bytes;
293 size_t memory_used_bytes;
294 tile_manager_->GetMemoryStats(&memory_required_bytes,
295 &memory_nice_to_have_bytes,
296 &memory_used_bytes);
297 SendManagedMemoryStats(memory_required_bytes,
298 memory_nice_to_have_bytes,
299 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15300}
301
[email protected]80334ba2013-03-20 17:33:50302void LayerTreeHostImpl::SetAnticipatedDrawTime(base::TimeTicks time) {
[email protected]f8456612013-03-19 20:56:09303 if (tile_manager_)
304 tile_manager_->SetAnticipatedDrawTime(time);
305}
306
[email protected]c1bb5af2013-03-13 19:06:27307void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
308 bool anchor_point,
309 float page_scale,
310 base::TimeTicks start_time,
311 base::TimeDelta duration) {
312 if (!RootScrollLayer())
313 return;
314
315 gfx::Vector2dF scroll_total =
316 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
317 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
[email protected]6fc4ee002013-03-26 23:39:51318 gfx::SizeF viewport_size = VisibleViewportSize();
[email protected]c1bb5af2013-03-13 19:06:27319
320 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
[email protected]85d136f782013-04-26 22:04:40321
322 // Easing constants experimentally determined.
323 scoped_ptr<TimingFunction> timing_function =
324 CubicBezierTimingFunction::Create(.8, 0, .3, .9).PassAs<TimingFunction>();
325
[email protected]c1bb5af2013-03-13 19:06:27326 page_scale_animation_ =
327 PageScaleAnimation::Create(scroll_total,
328 active_tree_->total_page_scale_factor(),
329 viewport_size,
330 scaled_scrollable_size,
[email protected]85d136f782013-04-26 22:04:40331 start_time_seconds,
332 timing_function.Pass());
[email protected]c1bb5af2013-03-13 19:06:27333
334 if (anchor_point) {
335 gfx::Vector2dF anchor(target_offset);
336 page_scale_animation_->ZoomWithAnchor(anchor,
337 page_scale,
338 duration.InSecondsF());
339 } else {
340 gfx::Vector2dF scaled_target_offset = target_offset;
341 page_scale_animation_->ZoomTo(scaled_target_offset,
342 page_scale,
343 duration.InSecondsF());
344 }
345
346 client_->SetNeedsRedrawOnImplThread();
347 client_->SetNeedsCommitOnImplThread();
348 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15349}
350
[email protected]c1bb5af2013-03-13 19:06:27351void LayerTreeHostImpl::ScheduleAnimation() {
352 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15353}
354
[email protected]c1bb5af2013-03-13 19:06:27355bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
356 if (!EnsureRenderSurfaceLayerList())
357 return false;
[email protected]f57bbc02012-11-21 07:02:15358
[email protected]c1bb5af2013-03-13 19:06:27359 gfx::PointF device_viewport_point =
360 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15361
[email protected]c1bb5af2013-03-13 19:06:27362 // First find out which layer was hit from the saved list of visible layers
363 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:39364 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:27365 device_viewport_point,
366 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15367
[email protected]c1bb5af2013-03-13 19:06:27368 // Walk up the hierarchy and look for a layer with a touch event handler
369 // region that the given point hits.
370 for (; layer_impl; layer_impl = layer_impl->parent()) {
[email protected]6ba914122013-03-22 16:26:39371 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point,
[email protected]c1bb5af2013-03-13 19:06:27372 layer_impl))
373 return true;
374 }
[email protected]f57bbc02012-11-21 07:02:15375
[email protected]c1bb5af2013-03-13 19:06:27376 return false;
377}
378
[email protected]ef915f532013-04-22 20:56:32379void LayerTreeHostImpl::DidReceiveLastInputEventForVSync(
380 base::TimeTicks frame_time) {
381 client_->DidReceiveLastInputEventForVSync(frame_time);
382}
383
[email protected]c1bb5af2013-03-13 19:06:27384void LayerTreeHostImpl::TrackDamageForAllSurfaces(
385 LayerImpl* root_draw_layer,
[email protected]50761e92013-03-29 20:51:28386 const LayerImplList& render_surface_layer_list) {
[email protected]c1bb5af2013-03-13 19:06:27387 // For now, we use damage tracking to compute a global scissor. To do this, we
388 // must compute all damage tracking before drawing anything, so that we know
389 // the root damage rect. The root damage rect is then used to scissor each
390 // surface.
391
392 for (int surface_index = render_surface_layer_list.size() - 1;
[email protected]bf691c22013-03-26 21:15:06393 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27394 --surface_index) {
395 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
396 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
397 DCHECK(render_surface);
398 render_surface->damage_tracker()->UpdateDamageTrackingState(
399 render_surface->layer_list(),
400 render_surface_layer->id(),
401 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
402 render_surface->content_rect(),
403 render_surface_layer->mask_layer(),
404 render_surface_layer->filters(),
405 render_surface_layer->filter().get());
406 }
407}
408
409void LayerTreeHostImpl::FrameData::AppendRenderPass(
410 scoped_ptr<RenderPass> render_pass) {
411 render_passes_by_id[render_pass->id] = render_pass.get();
412 render_passes.push_back(render_pass.Pass());
413}
414
415static void AppendQuadsForLayer(RenderPass* target_render_pass,
416 LayerImpl* layer,
417 const OcclusionTrackerImpl& occlusion_tracker,
418 AppendQuadsData* append_quads_data) {
419 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49420 QuadCuller quad_culler(&target_render_pass->quad_list,
421 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27422 layer,
423 occlusion_tracker,
424 layer->ShowDebugBorders(),
425 for_surface);
426 layer->AppendQuads(&quad_culler, append_quads_data);
427}
428
429static void AppendQuadsForRenderSurfaceLayer(
430 RenderPass* target_render_pass,
431 LayerImpl* layer,
432 const RenderPass* contributing_render_pass,
433 const OcclusionTrackerImpl& occlusion_tracker,
434 AppendQuadsData* append_quads_data) {
435 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49436 QuadCuller quad_culler(&target_render_pass->quad_list,
437 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27438 layer,
439 occlusion_tracker,
440 layer->ShowDebugBorders(),
441 for_surface);
442
443 bool is_replica = false;
444 layer->render_surface()->AppendQuads(&quad_culler,
445 append_quads_data,
446 is_replica,
447 contributing_render_pass->id);
448
449 // Add replica after the surface so that it appears below the surface.
450 if (layer->has_replica()) {
451 is_replica = true;
452 layer->render_surface()->AppendQuads(&quad_culler,
453 append_quads_data,
454 is_replica,
455 contributing_render_pass->id);
456 }
457}
458
459static void AppendQuadsToFillScreen(
460 RenderPass* target_render_pass,
461 LayerImpl* root_layer,
462 SkColor screen_background_color,
463 const OcclusionTrackerImpl& occlusion_tracker) {
464 if (!root_layer || !SkColorGetA(screen_background_color))
465 return;
466
467 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
468 if (fill_region.IsEmpty())
469 return;
470
471 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49472 QuadCuller quad_culler(&target_render_pass->quad_list,
473 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27474 root_layer,
475 occlusion_tracker,
476 root_layer->ShowDebugBorders(),
477 for_surface);
478
479 // Manually create the quad state for the gutter quads, as the root layer
480 // doesn't have any bounds and so can't generate this itself.
481 // TODO(danakj): Make the gutter quads generated by the solid color layer
482 // (make it smarter about generating quads to fill unoccluded areas).
483
484 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
485 float opacity = 1.f;
486 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49487 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27488 shared_quad_state->SetAll(root_layer->draw_transform(),
489 root_target_rect.size(),
490 root_target_rect,
491 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01492 false,
[email protected]f57bbc02012-11-21 07:02:15493 opacity);
494
[email protected]c1bb5af2013-03-13 19:06:27495 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17496
[email protected]c1bb5af2013-03-13 19:06:27497 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
498 bool did_invert = root_layer->screen_space_transform().GetInverse(
499 &transform_to_layer_space);
500 DCHECK(did_invert);
501 for (Region::Iterator fill_rects(fill_region);
502 fill_rects.has_rect();
503 fill_rects.next()) {
504 // The root layer transform is composed of translations and scales only,
505 // no perspective, so mapping is sufficient (as opposed to projecting).
506 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21507 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27508 // Skip the quad culler and just append the quads directly to avoid
509 // occlusion checks.
510 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
511 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
[email protected]c7e95b42013-03-18 01:13:49512 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27513 }
[email protected]467b3612012-08-28 07:41:16514}
515
[email protected]c1bb5af2013-03-13 19:06:27516bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
517 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14518
[email protected]c1bb5af2013-03-13 19:06:27519 if (!CanDraw() || !active_tree_->root_layer())
520 return false;
[email protected]2d692992012-12-19 01:19:32521
[email protected]c1bb5af2013-03-13 19:06:27522 TrackDamageForAllSurfaces(active_tree_->root_layer(),
523 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14524
[email protected]e0341352013-04-06 05:01:20525 // If the root render surface has no visible damage, then don't generate a
526 // frame at all.
527 RenderSurfaceImpl* root_surface =
528 active_tree_->root_layer()->render_surface();
529 bool root_surface_has_no_visible_damage =
530 !root_surface->damage_tracker()->current_damage_rect().Intersects(
531 root_surface->content_rect());
532 bool root_surface_has_contributing_layers =
533 !root_surface->layer_list().empty();
534 if (root_surface_has_contributing_layers &&
535 root_surface_has_no_visible_damage) {
536 TRACE_EVENT0("cc",
537 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
538 frame->has_no_damage = true;
539 return true;
540 }
541
[email protected]c1bb5af2013-03-13 19:06:27542 TRACE_EVENT1("cc",
543 "LayerTreeHostImpl::CalculateRenderPasses",
544 "render_surface_layer_list.size()",
[email protected]bf691c22013-03-26 21:15:06545 static_cast<uint64>(frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14546
[email protected]c1bb5af2013-03-13 19:06:27547 // Create the render passes in dependency order.
548 for (int surface_index = frame->render_surface_layer_list->size() - 1;
[email protected]bf691c22013-03-26 21:15:06549 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27550 --surface_index) {
551 LayerImpl* render_surface_layer =
552 (*frame->render_surface_layer_list)[surface_index];
553 render_surface_layer->render_surface()->AppendRenderPasses(frame);
554 }
[email protected]94f206c12012-08-25 00:09:14555
[email protected]c1bb5af2013-03-13 19:06:27556 bool record_metrics_for_frame =
[email protected]8e0176d2013-03-21 03:14:52557 settings_.show_overdraw_in_tracing &&
[email protected]c1bb5af2013-03-13 19:06:27558 base::debug::TraceLog::GetInstance() &&
559 base::debug::TraceLog::GetInstance()->IsEnabled();
560 OcclusionTrackerImpl occlusion_tracker(
561 active_tree_->root_layer()->render_surface()->content_rect(),
562 record_metrics_for_frame);
563 occlusion_tracker.set_minimum_tracking_size(
[email protected]8e0176d2013-03-21 03:14:52564 settings_.minimum_occlusion_tracking_size);
[email protected]94f206c12012-08-25 00:09:14565
[email protected]846f455b2013-03-18 19:07:41566 if (debug_state_.show_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27567 occlusion_tracker.set_occluding_screen_space_rects_container(
568 &frame->occluding_screen_space_rects);
569 }
[email protected]846f455b2013-03-18 19:07:41570 if (debug_state_.show_non_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27571 occlusion_tracker.set_non_occluding_screen_space_rects_container(
572 &frame->non_occluding_screen_space_rects);
573 }
[email protected]94f206c12012-08-25 00:09:14574
[email protected]c1bb5af2013-03-13 19:06:27575 // Add quads to the Render passes in FrontToBack order to allow for testing
576 // occlusion and performing culling during the tree walk.
577 typedef LayerIterator<LayerImpl,
[email protected]50761e92013-03-29 20:51:28578 LayerImplList,
[email protected]c1bb5af2013-03-13 19:06:27579 RenderSurfaceImpl,
580 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14581
[email protected]c1bb5af2013-03-13 19:06:27582 // Typically when we are missing a texture and use a checkerboard quad, we
583 // still draw the frame. However when the layer being checkerboarded is moving
584 // due to an impl-animation, we drop the frame to avoid flashing due to the
585 // texture suddenly appearing in the future.
586 bool draw_frame = true;
[email protected]18a70192013-04-26 16:18:25587 // When we have a copy request for a layer, we need to draw no matter
588 // what, as the layer may disappear after this frame.
589 bool have_copy_request = false;
[email protected]94f206c12012-08-25 00:09:14590
[email protected]372bad5f2013-03-21 16:38:43591 int layers_drawn = 0;
592
[email protected]c1bb5af2013-03-13 19:06:27593 LayerIteratorType end =
[email protected]71dfcc72013-03-20 21:30:09594 LayerIteratorType::End(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27595 for (LayerIteratorType it =
[email protected]71dfcc72013-03-20 21:30:09596 LayerIteratorType::Begin(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27597 it != end;
598 ++it) {
599 RenderPass::Id target_render_pass_id =
[email protected]71dfcc72013-03-20 21:30:09600 it.target_render_surface_layer()->render_surface()->RenderPassId();
[email protected]c1bb5af2013-03-13 19:06:27601 RenderPass* target_render_pass =
602 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14603
[email protected]2ea5e6c2013-04-26 21:52:23604 bool prevent_occlusion =
605 it.target_render_surface_layer()->HasRequestCopyCallback();
606 occlusion_tracker.EnterLayer(it, prevent_occlusion);
[email protected]94f206c12012-08-25 00:09:14607
[email protected]c1bb5af2013-03-13 19:06:27608 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30609
[email protected]18a70192013-04-26 16:18:25610 if (it.represents_target_render_surface()) {
611 if (it->HasRequestCopyCallback()) {
612 have_copy_request = true;
613 it->TakeRequestCopyCallbacks(&target_render_pass->copy_callbacks);
614 }
615 } else if (it.represents_contributing_render_surface()) {
[email protected]c1bb5af2013-03-13 19:06:27616 RenderPass::Id contributing_render_pass_id =
617 it->render_surface()->RenderPassId();
618 RenderPass* contributing_render_pass =
619 frame->render_passes_by_id[contributing_render_pass_id];
620 AppendQuadsForRenderSurfaceLayer(target_render_pass,
621 *it,
622 contributing_render_pass,
623 occlusion_tracker,
624 &append_quads_data);
[email protected]e1e768f2013-03-26 08:48:09625 } else if (it.represents_itself() &&
626 !it->visible_content_rect().IsEmpty()) {
[email protected]c1bb5af2013-03-13 19:06:27627 bool has_occlusion_from_outside_target_surface;
628 bool impl_draw_transform_is_unknown = false;
629 if (occlusion_tracker.Occluded(
630 it->render_target(),
631 it->visible_content_rect(),
632 it->draw_transform(),
633 impl_draw_transform_is_unknown,
634 it->is_clipped(),
635 it->clip_rect(),
636 &has_occlusion_from_outside_target_surface)) {
[email protected]e1e768f2013-03-26 08:48:09637 append_quads_data.had_occlusion_from_outside_target_surface |=
[email protected]c1bb5af2013-03-13 19:06:27638 has_occlusion_from_outside_target_surface;
639 } else {
640 DCHECK_EQ(active_tree_, it->layer_tree_impl());
641 it->WillDraw(resource_provider_.get());
642 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57643
[email protected]c1bb5af2013-03-13 19:06:27644 if (it->HasContributingDelegatedRenderPasses()) {
645 RenderPass::Id contributing_render_pass_id =
646 it->FirstContributingRenderPassId();
647 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
648 frame->render_passes_by_id.end()) {
649 RenderPass* render_pass =
650 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14651
[email protected]c1bb5af2013-03-13 19:06:27652 AppendQuadsData append_quads_data(render_pass->id);
653 AppendQuadsForLayer(render_pass,
654 *it,
655 occlusion_tracker,
656 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57657
[email protected]c1bb5af2013-03-13 19:06:27658 contributing_render_pass_id =
659 it->NextContributingRenderPassId(contributing_render_pass_id);
660 }
[email protected]94f206c12012-08-25 00:09:14661 }
662
[email protected]c1bb5af2013-03-13 19:06:27663 AppendQuadsForLayer(target_render_pass,
664 *it,
665 occlusion_tracker,
666 &append_quads_data);
667 }
[email protected]89228202012-08-29 03:20:30668
[email protected]372bad5f2013-03-21 16:38:43669 ++layers_drawn;
[email protected]94f206c12012-08-25 00:09:14670 }
671
[email protected]e1e768f2013-03-26 08:48:09672 if (append_quads_data.had_occlusion_from_outside_target_surface)
[email protected]c1bb5af2013-03-13 19:06:27673 target_render_pass->has_occlusion_from_outside_target_surface = true;
674
[email protected]e1e768f2013-03-26 08:48:09675 if (append_quads_data.num_missing_tiles) {
[email protected]372bad5f2013-03-21 16:38:43676 rendering_stats_instrumentation_->AddMissingTiles(
[email protected]e1e768f2013-03-26 08:48:09677 append_quads_data.num_missing_tiles);
[email protected]c1bb5af2013-03-13 19:06:27678 bool layer_has_animating_transform =
679 it->screen_space_transform_is_animating() ||
680 it->draw_transform_is_animating();
681 if (layer_has_animating_transform)
682 draw_frame = false;
683 }
684
[email protected]e1e768f2013-03-26 08:48:09685 if (append_quads_data.had_incomplete_tile)
[email protected]c1bb5af2013-03-13 19:06:27686 frame->contains_incomplete_tile = true;
687
688 occlusion_tracker.LeaveLayer(it);
689 }
690
[email protected]18a70192013-04-26 16:18:25691 if (have_copy_request)
692 draw_frame = true;
693
[email protected]372bad5f2013-03-21 16:38:43694 rendering_stats_instrumentation_->AddLayersDrawn(layers_drawn);
695
[email protected]1d993172012-10-18 18:15:04696#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27697 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
698 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
699 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
700 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
701 != frame->render_passes_by_id.end());
702 }
[email protected]94f206c12012-08-25 00:09:14703#endif
[email protected]c1bb5af2013-03-13 19:06:27704 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14705
[email protected]c1bb5af2013-03-13 19:06:27706 if (!active_tree_->has_transparent_background()) {
707 frame->render_passes.back()->has_transparent_background = false;
708 AppendQuadsToFillScreen(frame->render_passes.back(),
709 active_tree_->root_layer(),
710 active_tree_->background_color(),
711 occlusion_tracker);
712 }
[email protected]94f206c12012-08-25 00:09:14713
[email protected]c1bb5af2013-03-13 19:06:27714 if (draw_frame)
715 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]18a70192013-04-26 16:18:25716 else
717 DCHECK(!have_copy_request);
[email protected]94f206c12012-08-25 00:09:14718
[email protected]c1bb5af2013-03-13 19:06:27719 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
720 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
[email protected]bf691c22013-03-26 21:15:06721 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()),
722 frame);
[email protected]94f206c12012-08-25 00:09:14723
[email protected]e0341352013-04-06 05:01:20724 // If we're making a frame to draw, it better have at least one render pass.
725 DCHECK(!frame->render_passes.empty());
[email protected]c1bb5af2013-03-13 19:06:27726 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14727}
728
[email protected]3d9f7432013-04-06 00:35:18729void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
730 bool should_background_tick) {
731 bool enabled = should_background_tick &&
732 !animation_registrar_->active_animation_controllers().empty();
733
[email protected]c1bb5af2013-03-13 19:06:27734 // Lazily create the time_source adapter so that we can vary the interval for
735 // testing.
736 if (!time_source_client_adapter_) {
737 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
738 this,
[email protected]6d0e69d2013-03-20 14:53:26739 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
[email protected]c1bb5af2013-03-13 19:06:27740 proxy_->CurrentThread()));
741 }
[email protected]94f206c12012-08-25 00:09:14742
[email protected]c1bb5af2013-03-13 19:06:27743 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14744}
745
[email protected]b9d4a362013-04-23 05:36:27746void LayerTreeHostImpl::SetViewportDamage(gfx::Rect damage_rect) {
[email protected]878705be2013-04-15 22:44:02747 viewport_damage_rect_.Union(damage_rect);
748}
749
[email protected]c1bb5af2013-03-13 19:06:27750static inline RenderPass* FindRenderPassById(
751 RenderPass::Id render_pass_id,
752 const LayerTreeHostImpl::FrameData& frame) {
753 RenderPassIdHashMap::const_iterator it =
754 frame.render_passes_by_id.find(render_pass_id);
755 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14756}
757
[email protected]c1bb5af2013-03-13 19:06:27758static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
759 LayerTreeHostImpl::FrameData* frame) {
760 RenderPass* remove_render_pass =
761 FindRenderPassById(remove_render_pass_id, *frame);
762 // The pass was already removed by another quad - probably the original, and
763 // we are the replica.
764 if (!remove_render_pass)
765 return;
766 RenderPassList& render_passes = frame->render_passes;
767 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
768 render_passes.end(),
769 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14770
[email protected]c1bb5af2013-03-13 19:06:27771 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14772
[email protected]c1bb5af2013-03-13 19:06:27773 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
774 frame->render_passes.erase(to_remove);
775 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14776
[email protected]c1bb5af2013-03-13 19:06:27777 // Now follow up for all RenderPass quads and remove their RenderPasses
778 // recursively.
779 const QuadList& quad_list = removed_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29780 QuadList::ConstBackToFrontIterator quad_list_iterator =
781 quad_list.BackToFrontBegin();
782 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27783 ++quad_list_iterator) {
784 DrawQuad* current_quad = (*quad_list_iterator);
785 if (current_quad->material != DrawQuad::RENDER_PASS)
786 continue;
[email protected]94f206c12012-08-25 00:09:14787
[email protected]c1bb5af2013-03-13 19:06:27788 RenderPass::Id next_remove_render_pass_id =
789 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
790 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
791 }
[email protected]94f206c12012-08-25 00:09:14792}
793
[email protected]c1bb5af2013-03-13 19:06:27794bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
795 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
796 const FrameData& frame) const {
797 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
798 bool quad_has_cached_resource =
[email protected]bf691c22013-03-26 21:15:06799 renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id);
[email protected]c1bb5af2013-03-13 19:06:27800 if (quad_has_damage) {
801 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
802 return false;
803 } else if (!quad_has_cached_resource) {
804 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
805 return false;
806 }
807 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
808 return true;
[email protected]94f206c12012-08-25 00:09:14809}
810
[email protected]c1bb5af2013-03-13 19:06:27811bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
812 const RenderPassDrawQuad& quad, const FrameData& frame) const {
813 const RenderPass* render_pass =
814 FindRenderPassById(quad.render_pass_id, frame);
815 if (!render_pass)
816 return false;
[email protected]94f206c12012-08-25 00:09:14817
[email protected]c1bb5af2013-03-13 19:06:27818 // If any quad or RenderPass draws into this RenderPass, then keep it.
819 const QuadList& quad_list = render_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29820 for (QuadList::ConstBackToFrontIterator quad_list_iterator =
821 quad_list.BackToFrontBegin();
822 quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27823 ++quad_list_iterator) {
824 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14825
[email protected]c1bb5af2013-03-13 19:06:27826 if (current_quad->material != DrawQuad::RENDER_PASS)
827 return false;
[email protected]94f206c12012-08-25 00:09:14828
[email protected]c1bb5af2013-03-13 19:06:27829 const RenderPass* contributing_pass = FindRenderPassById(
830 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
831 if (contributing_pass)
832 return false;
833 }
834 return true;
[email protected]94f206c12012-08-25 00:09:14835}
836
837// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27838template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
839 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
840 CullRenderPassesWithCachedTextures culler, FrameData* frame);
841template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
842 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
843 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14844
845// static
[email protected]c1bb5af2013-03-13 19:06:27846template <typename RenderPassCuller>
847void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
848 FrameData* frame) {
849 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
850 it != culler.RenderPassListEnd(frame->render_passes);
851 it = culler.RenderPassListNext(it)) {
852 const RenderPass* current_pass = frame->render_passes[it];
853 const QuadList& quad_list = current_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29854 QuadList::ConstBackToFrontIterator quad_list_iterator =
855 quad_list.BackToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14856
[email protected]ed511b8d2013-03-25 03:29:29857 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27858 ++quad_list_iterator) {
859 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14860
[email protected]c1bb5af2013-03-13 19:06:27861 if (current_quad->material != DrawQuad::RENDER_PASS)
862 continue;
[email protected]94f206c12012-08-25 00:09:14863
[email protected]c1bb5af2013-03-13 19:06:27864 const RenderPassDrawQuad* render_pass_quad =
865 RenderPassDrawQuad::MaterialCast(current_quad);
866 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
867 continue;
[email protected]94f206c12012-08-25 00:09:14868
[email protected]c1bb5af2013-03-13 19:06:27869 // We are changing the vector in the middle of iteration. Because we
870 // delete render passes that draw into the current pass, we are
871 // guaranteed that any data from the iterator to the end will not
872 // change. So, capture the iterator position from the end of the
873 // list, and restore it after the change.
874 size_t position_from_end = frame->render_passes.size() - it;
875 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
876 it = frame->render_passes.size() - position_from_end;
877 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14878 }
[email protected]c1bb5af2013-03-13 19:06:27879 }
[email protected]94f206c12012-08-25 00:09:14880}
881
[email protected]e0341352013-04-06 05:01:20882bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
883 gfx::Rect device_viewport_damage_rect) {
[email protected]c1bb5af2013-03-13 19:06:27884 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14885
[email protected]c1bb5af2013-03-13 19:06:27886 active_tree_->UpdateDrawProperties(
887 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27888
[email protected]c1bb5af2013-03-13 19:06:27889 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
890 frame->render_passes.clear();
891 frame->render_passes_by_id.clear();
892 frame->will_draw_layers.clear();
[email protected]e0341352013-04-06 05:01:20893 frame->contains_incomplete_tile = false;
894 frame->has_no_damage = false;
895
896 if (active_tree_->root_layer()) {
[email protected]878705be2013-04-15 22:44:02897 device_viewport_damage_rect.Union(viewport_damage_rect_);
898 viewport_damage_rect_ = gfx::Rect();
[email protected]e0341352013-04-06 05:01:20899
900 active_tree_->root_layer()->render_surface()->damage_tracker()->
901 AddDamageNextUpdate(device_viewport_damage_rect);
902 }
[email protected]94f206c12012-08-25 00:09:14903
[email protected]c1bb5af2013-03-13 19:06:27904 if (!CalculateRenderPasses(frame))
905 return false;
[email protected]94f206c12012-08-25 00:09:14906
[email protected]e4c3c87a2013-04-22 02:28:40907 frame->latency_info = active_tree_->GetLatencyInfo();
908
[email protected]c1bb5af2013-03-13 19:06:27909 // If we return true, then we expect DrawLayers() to be called before this
910 // function is called again.
911 return true;
[email protected]94f206c12012-08-25 00:09:14912}
913
[email protected]c1bb5af2013-03-13 19:06:27914void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
915 const ManagedMemoryPolicy& policy) {
916 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
[email protected]46b8acc2013-03-19 22:38:35917 visible_ ? policy.bytes_limit_when_visible
918 : policy.bytes_limit_when_not_visible,
919 ManagedMemoryPolicy::PriorityCutoffToValue(
920 visible_ ? policy.priority_cutoff_when_visible
921 : policy.priority_cutoff_when_not_visible));
[email protected]c1bb5af2013-03-13 19:06:27922 if (evicted_resources) {
923 active_tree_->SetContentsTexturesPurged();
924 if (pending_tree_)
925 pending_tree_->SetContentsTexturesPurged();
926 client_->SetNeedsCommitOnImplThread();
927 client_->OnCanDrawStateChanged(CanDraw());
928 client_->RenewTreePriority();
929 }
930 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43931
[email protected]c1bb5af2013-03-13 19:06:27932 if (tile_manager_) {
933 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
934 new_state.memory_limit_in_bytes = visible_ ?
[email protected]46b8acc2013-03-19 22:38:35935 policy.bytes_limit_when_visible :
936 policy.bytes_limit_when_not_visible;
[email protected]41124c52013-03-28 23:26:57937 // TODO(reveman): We should avoid keeping around unused resources if
938 // possible. crbug.com/224475
[email protected]9d52c1c32013-04-09 19:11:36939 new_state.unused_memory_limit_in_bytes = static_cast<size_t>(
940 (static_cast<int64>(new_state.memory_limit_in_bytes) *
941 settings_.max_unused_resource_memory_percentage) / 100);
[email protected]c1bb5af2013-03-13 19:06:27942 new_state.memory_limit_policy =
[email protected]46b8acc2013-03-19 22:38:35943 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
[email protected]c1bb5af2013-03-13 19:06:27944 visible_ ?
[email protected]46b8acc2013-03-19 22:38:35945 policy.priority_cutoff_when_visible :
946 policy.priority_cutoff_when_not_visible);
[email protected]c1bb5af2013-03-13 19:06:27947 tile_manager_->SetGlobalState(new_state);
948 }
[email protected]94f206c12012-08-25 00:09:14949}
950
[email protected]c1bb5af2013-03-13 19:06:27951bool LayerTreeHostImpl::HasImplThread() const {
952 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44953}
954
[email protected]c1bb5af2013-03-13 19:06:27955void LayerTreeHostImpl::ScheduleManageTiles() {
956 if (client_)
957 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43958}
959
[email protected]86126792013-03-16 20:07:54960void LayerTreeHostImpl::DidInitializeVisibleTile() {
961 // TODO(reveman): Determine tiles that changed and only damage
962 // what's necessary.
963 SetFullRootLayerDamage();
[email protected]c1bb5af2013-03-13 19:06:27964 if (client_)
[email protected]86126792013-03-16 20:07:54965 client_->DidInitializeVisibleTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47966}
967
[email protected]c1bb5af2013-03-13 19:06:27968bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
[email protected]8e0176d2013-03-21 03:14:52969 return settings_.should_clear_root_render_pass;
[email protected]f35e2322012-12-15 21:45:52970}
971
[email protected]c1bb5af2013-03-13 19:06:27972void LayerTreeHostImpl::SetManagedMemoryPolicy(
973 const ManagedMemoryPolicy& policy) {
974 if (managed_memory_policy_ == policy)
975 return;
[email protected]61de5812012-11-08 07:03:44976
[email protected]d7626ffd2013-03-29 00:17:42977 // If there is already enough memory to draw everything imaginable and the
978 // new memory limit does not change this, then do not re-commit. Don't bother
979 // skipping commits if this is not visible (commits don't happen when not
980 // visible, there will almost always be a commit when this becomes visible).
981 bool needs_commit = true;
982 if (visible() &&
983 policy.bytes_limit_when_visible >=
984 max_memory_needed_bytes_ &&
985 managed_memory_policy_.bytes_limit_when_visible >=
986 max_memory_needed_bytes_ &&
987 policy.priority_cutoff_when_visible ==
988 managed_memory_policy_.priority_cutoff_when_visible) {
989 needs_commit = false;
990 }
991
[email protected]c1bb5af2013-03-13 19:06:27992 managed_memory_policy_ = policy;
993 if (!proxy_->HasImplThread()) {
[email protected]d7626ffd2013-03-29 00:17:42994 // In single-thread mode, this can be called on the main thread by
995 // GLRenderer::OnMemoryAllocationChanged.
[email protected]c1bb5af2013-03-13 19:06:27996 DebugScopedSetImplThread impl_thread(proxy_);
997 EnforceManagedMemoryPolicy(managed_memory_policy_);
998 } else {
999 DCHECK(proxy_->IsImplThread());
1000 EnforceManagedMemoryPolicy(managed_memory_policy_);
1001 }
[email protected]d7626ffd2013-03-29 00:17:421002
1003 if (needs_commit)
1004 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141005}
1006
[email protected]1cd9f5552013-04-26 04:22:031007void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) {
1008 client_->SetNeedsRedrawRectOnImplThread(damage_rect);
1009}
1010
[email protected]c1bb5af2013-03-13 19:06:271011void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
1012 base::TimeDelta interval) {
1013 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:141014}
1015
[email protected]7ed47512013-03-26 22:28:451016void LayerTreeHostImpl::DidVSync(base::TimeTicks frame_time) {
1017 client_->DidVSync(frame_time);
1018}
1019
[email protected]c1bb5af2013-03-13 19:06:271020void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
1021 const CompositorFrameAck& ack) {
1022 if (!renderer_)
1023 return;
[email protected]b6f3d7e2012-12-08 00:11:211024
[email protected]c1bb5af2013-03-13 19:06:271025 // TODO(piman): We may need to do some validation on this ack before
1026 // processing it.
1027 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]bb1e2822013-04-17 22:06:011028
1029 // When using compositor frame data, the ack doubles as a swap complete ack.
1030 OnSwapBuffersComplete();
[email protected]a46f32932012-12-07 21:43:161031}
1032
[email protected]c1bb5af2013-03-13 19:06:271033void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
1034 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:291035}
1036
[email protected]c1bb5af2013-03-13 19:06:271037CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
1038 CompositorFrameMetadata metadata;
1039 metadata.device_scale_factor = device_scale_factor_;
1040 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
1041 metadata.viewport_size = active_tree_->ScrollableViewportSize();
1042 metadata.root_layer_size = active_tree_->ScrollableSize();
1043 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
1044 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
1045 if (top_controls_manager_) {
1046 metadata.location_bar_offset =
1047 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
1048 metadata.location_bar_content_translation =
1049 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
[email protected]5a54b2822013-03-26 10:00:011050 metadata.overdraw_bottom_height = overdraw_bottom_height_;
[email protected]c1bb5af2013-03-13 19:06:271051 }
[email protected]bf189f62012-12-18 03:42:111052
[email protected]c1bb5af2013-03-13 19:06:271053 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:111054 return metadata;
[email protected]c1bb5af2013-03-13 19:06:271055
[email protected]ffb2720f2013-03-15 19:18:371056 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
[email protected]e4c3c87a2013-04-22 02:28:401057 metadata.latency_info = active_tree_->GetLatencyInfo();
[email protected]c1bb5af2013-03-13 19:06:271058
1059 return metadata;
[email protected]bf189f62012-12-18 03:42:111060}
1061
[email protected]73673592013-04-03 22:14:321062bool LayerTreeHostImpl::AllowPartialSwap() const {
1063 // We don't track damage on the HUD layer (it interacts with damage tracking
1064 // visualizations), so disable partial swaps to make the HUD layer display
1065 // properly.
1066 return !debug_state_.ShowHudRects();
1067}
1068
[email protected]f0c2a242013-03-15 19:34:521069void LayerTreeHostImpl::DrawLayers(FrameData* frame,
1070 base::TimeTicks frame_begin_time) {
[email protected]c1bb5af2013-03-13 19:06:271071 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
1072 DCHECK(CanDraw());
[email protected]e0341352013-04-06 05:01:201073
1074 if (frame->has_no_damage)
1075 return;
1076
[email protected]c1bb5af2013-03-13 19:06:271077 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:141078
[email protected]9e3594522013-03-18 00:57:361079 fps_counter_->SaveTimeStamp(frame_begin_time);
[email protected]94f206c12012-08-25 00:09:141080
[email protected]372bad5f2013-03-21 16:38:431081 rendering_stats_instrumentation_->SetScreenFrameCount(
1082 fps_counter_->current_frame_number());
1083 rendering_stats_instrumentation_->SetDroppedFrameCount(
1084 fps_counter_->dropped_frame_count());
1085
[email protected]c1bb5af2013-03-13 19:06:271086 if (tile_manager_) {
1087 memory_history_->SaveEntry(
1088 tile_manager_->memory_stats_from_last_assign());
1089 }
[email protected]1191d9d2013-02-02 06:00:331090
[email protected]846f455b2013-03-18 19:07:411091 if (debug_state_.ShowHudRects()) {
[email protected]d35992782013-03-14 14:54:021092 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:271093 active_tree_->root_layer(),
1094 *frame->render_surface_layer_list,
1095 frame->occluding_screen_space_rects,
1096 frame->non_occluding_screen_space_rects,
1097 debug_state_);
1098 }
[email protected]94f206c12012-08-25 00:09:141099
[email protected]a848c102013-03-26 08:59:091100 if (!settings_.impl_side_painting && debug_state_.continuous_painting) {
1101 const RenderingStats& stats =
1102 rendering_stats_instrumentation_->GetRenderingStats();
1103 paint_time_counter_->SavePaintTime(stats.total_paint_time);
1104 }
1105
[email protected]846f455b2013-03-18 19:07:411106 if (debug_state_.trace_all_rendered_frames) {
[email protected]c76faea2013-03-26 07:42:421107 TRACE_EVENT_INSTANT1("cc.debug", "Frame", TRACE_EVENT_SCOPE_THREAD,
[email protected]c1bb5af2013-03-13 19:06:271108 "frame", ValueToString(FrameStateAsValue()));
1109 }
[email protected]131a0c22013-02-12 18:31:081110
[email protected]c1bb5af2013-03-13 19:06:271111 // Because the contents of the HUD depend on everything else in the frame, the
1112 // contents of its texture are updated as the last thing before the frame is
1113 // drawn.
1114 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:541115 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:141116
[email protected]d002dd02013-03-27 07:40:401117 renderer_->DrawFrame(&frame->render_passes);
[email protected]c1bb5af2013-03-13 19:06:271118 // The render passes should be consumed by the renderer.
1119 DCHECK(frame->render_passes.empty());
1120 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:141121
[email protected]c1bb5af2013-03-13 19:06:271122 // The next frame should start by assuming nothing has changed, and changes
1123 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:541124 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:271125 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
1126 DidDrawDamagedArea();
1127 }
1128 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:141129}
1130
[email protected]c1bb5af2013-03-13 19:06:271131void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
1132 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
1133 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:521134
[email protected]c1bb5af2013-03-13 19:06:271135 // Once all layers have been drawn, pending texture uploads should no
1136 // longer block future uploads.
1137 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:141138}
1139
[email protected]c1bb5af2013-03-13 19:06:271140void LayerTreeHostImpl::FinishAllRendering() {
1141 if (renderer_)
1142 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:141143}
1144
[email protected]c1bb5af2013-03-13 19:06:271145bool LayerTreeHostImpl::IsContextLost() {
1146 DCHECK(proxy_->IsImplThread());
1147 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141148}
1149
[email protected]c1bb5af2013-03-13 19:06:271150const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1151 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141152}
1153
[email protected]e0341352013-04-06 05:01:201154bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
1155 if (frame.has_no_damage)
1156 return false;
[email protected]e4c3c87a2013-04-22 02:28:401157 bool result = renderer_->SwapBuffers(frame.latency_info);
1158 if (result)
1159 active_tree_->ClearLatencyInfo();
1160 return result;
[email protected]94f206c12012-08-25 00:09:141161}
1162
[email protected]7ed47512013-03-26 22:28:451163void LayerTreeHostImpl::EnableVSyncNotification(bool enable) {
1164 if (output_surface_)
1165 output_surface_->EnableVSyncNotification(enable);
1166}
1167
[email protected]c1bb5af2013-03-13 19:06:271168gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1169 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101170}
1171
[email protected]ffb2720f2013-03-15 19:18:371172gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1173 gfx::SizeF dip_size =
1174 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1175
1176 // The clip layer should be used if non-overlay scrollbars may exist since
1177 // it adjusts for them.
1178 LayerImpl* clip_layer = active_tree_->RootClipLayer();
[email protected]8e0176d2013-03-21 03:14:521179 if (!Settings().solid_color_scrollbars && clip_layer &&
[email protected]ffb2720f2013-03-15 19:18:371180 clip_layer->masks_to_bounds())
1181 dip_size = clip_layer->bounds();
1182
[email protected]ed511b8d2013-03-25 03:29:291183 float top_offset =
[email protected]ffb2720f2013-03-15 19:18:371184 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
[email protected]d9083762013-03-24 01:36:401185 return gfx::SizeF(dip_size.width(),
[email protected]ed511b8d2013-03-25 03:29:291186 dip_size.height() - top_offset - overdraw_bottom_height_);
[email protected]ffb2720f2013-03-15 19:18:371187}
1188
[email protected]c1bb5af2013-03-13 19:06:271189const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1190 return settings();
[email protected]493067512012-09-19 23:34:101191}
1192
[email protected]c1bb5af2013-03-13 19:06:271193void LayerTreeHostImpl::DidLoseOutputSurface() {
[email protected]bb1e2822013-04-17 22:06:011194 // TODO(jamesr): The renderer_ check is needed to make some of the
1195 // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or
1196 // important) in production. We should adjust the test to not need this.
1197 if (renderer_)
1198 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141199}
1200
[email protected]c1bb5af2013-03-13 19:06:271201void LayerTreeHostImpl::OnSwapBuffersComplete() {
1202 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141203}
1204
[email protected]c1bb5af2013-03-13 19:06:271205void LayerTreeHostImpl::Readback(void* pixels,
1206 gfx::Rect rect_in_device_viewport) {
1207 DCHECK(renderer_);
1208 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141209}
1210
[email protected]59adb112013-04-09 04:48:441211bool LayerTreeHostImpl::HaveRootScrollLayer() const {
[email protected]3209161d2013-03-29 19:17:341212 return !!RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011213}
1214
[email protected]c1bb5af2013-03-13 19:06:271215LayerImpl* LayerTreeHostImpl::RootLayer() const {
1216 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081217}
1218
[email protected]c1bb5af2013-03-13 19:06:271219LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1220 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081221}
1222
[email protected]c1bb5af2013-03-13 19:06:271223LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1224 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081225}
1226
[email protected]94f206c12012-08-25 00:09:141227// Content layers can be either directly scrollable or contained in an outer
1228// scrolling layer which applies the scroll transform. Given a content layer,
1229// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271230static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1231 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141232 return 0;
[email protected]c1bb5af2013-03-13 19:06:271233
1234 if (layer_impl->scrollable())
1235 return layer_impl;
1236
1237 if (layer_impl->DrawsContent() &&
1238 layer_impl->parent() &&
1239 layer_impl->parent()->scrollable())
1240 return layer_impl->parent();
1241
1242 return 0;
[email protected]94f206c12012-08-25 00:09:141243}
1244
[email protected]c1bb5af2013-03-13 19:06:271245void LayerTreeHostImpl::CreatePendingTree() {
1246 CHECK(!pending_tree_);
1247 if (recycle_tree_)
1248 recycle_tree_.swap(pending_tree_);
1249 else
1250 pending_tree_ = LayerTreeImpl::create(this);
1251 client_->OnCanDrawStateChanged(CanDraw());
1252 client_->OnHasPendingTreeStateChanged(pending_tree_);
1253 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1254 TRACE_EVENT_ASYNC_STEP0("cc",
1255 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271256}
1257
[email protected]c1bb5af2013-03-13 19:06:271258void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1259 DCHECK(!client_->IsInsideDraw()) <<
1260 "Checking for completed uploads within a draw may trigger "
1261 "spurious redraws.";
1262 if (tile_manager_)
1263 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481264}
1265
[email protected]c1bb5af2013-03-13 19:06:271266bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1267 if (!pending_tree_)
1268 return false;
[email protected]2e7ca422012-12-20 02:57:271269
[email protected]c1bb5af2013-03-13 19:06:271270 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091271
[email protected]c1bb5af2013-03-13 19:06:271272 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161273
[email protected]c1bb5af2013-03-13 19:06:271274 TRACE_EVENT_ASYNC_STEP1("cc",
1275 "PendingTree", pending_tree_.get(), "activate",
1276 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271277
[email protected]8ca1e6c2013-04-02 03:49:261278 // Activate once all visible resources in pending tree are ready.
1279 if (!pending_tree_->AreVisibleResourcesReady())
1280 return false;
[email protected]2e7ca422012-12-20 02:57:271281
[email protected]c1bb5af2013-03-13 19:06:271282 ActivatePendingTree();
1283 return true;
[email protected]2e7ca422012-12-20 02:57:271284}
1285
[email protected]c1bb5af2013-03-13 19:06:271286void LayerTreeHostImpl::ActivatePendingTree() {
1287 CHECK(pending_tree_);
1288 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351289
[email protected]c1bb5af2013-03-13 19:06:271290 active_tree_->PushPersistedState(pending_tree_.get());
1291 if (pending_tree_->needs_full_tree_sync()) {
1292 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331293 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271294 active_tree_->DetachLayerTree(),
1295 active_tree_.get()));
1296 }
[email protected]b5651c22013-03-14 15:06:331297 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271298 active_tree_->root_layer());
1299 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511300
[email protected]c1bb5af2013-03-13 19:06:271301 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511302
[email protected]c1bb5af2013-03-13 19:06:271303 // Now that we've synced everything from the pending tree to the active
1304 // tree, rename the pending tree the recycle tree so we can reuse it on the
1305 // next sync.
1306 pending_tree_.swap(recycle_tree_);
1307 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511308
[email protected]c1bb5af2013-03-13 19:06:271309 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221310
[email protected]c1bb5af2013-03-13 19:06:271311 // Reduce wasted memory now that unlinked resources are guaranteed not
1312 // to be used.
1313 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411314
[email protected]c1bb5af2013-03-13 19:06:271315 client_->OnCanDrawStateChanged(CanDraw());
1316 client_->OnHasPendingTreeStateChanged(pending_tree_);
1317 client_->SetNeedsRedrawOnImplThread();
1318 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241319
[email protected]a848c102013-03-26 08:59:091320 if (debug_state_.continuous_painting) {
1321 const RenderingStats& stats =
[email protected]372bad5f2013-03-21 16:38:431322 rendering_stats_instrumentation_->GetRenderingStats();
[email protected]a848c102013-03-26 08:59:091323 paint_time_counter_->SavePaintTime(
[email protected]41abb6d92013-04-26 16:38:501324 stats.total_paint_time + stats.total_record_time +
[email protected]a848c102013-03-26 08:59:091325 stats.total_rasterize_time_for_now_bins_on_pending_tree);
[email protected]c1bb5af2013-03-13 19:06:271326 }
[email protected]2e7ca422012-12-20 02:57:271327}
1328
[email protected]c1bb5af2013-03-13 19:06:271329void LayerTreeHostImpl::SetVisible(bool visible) {
1330 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141331
[email protected]c1bb5af2013-03-13 19:06:271332 if (visible_ == visible)
1333 return;
1334 visible_ = visible;
1335 DidVisibilityChange(this, visible_);
1336 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141337
[email protected]c1bb5af2013-03-13 19:06:271338 if (!renderer_)
1339 return;
[email protected]94f206c12012-08-25 00:09:141340
[email protected]c1bb5af2013-03-13 19:06:271341 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141342}
1343
[email protected]c1bb5af2013-03-13 19:06:271344bool LayerTreeHostImpl::InitializeRenderer(
1345 scoped_ptr<OutputSurface> output_surface) {
1346 // Since we will create a new resource provider, we cannot continue to use
1347 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1348 // before we destroy the old resource provider.
1349 if (active_tree_->root_layer())
1350 ClearRenderSurfaces();
1351 if (active_tree_->root_layer())
1352 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1353 if (pending_tree_ && pending_tree_->root_layer())
1354 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1355 if (recycle_tree_ && recycle_tree_->root_layer())
1356 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]7ba3ca72013-04-11 06:37:251357 if (resource_provider_)
1358 resource_provider_->DidLoseOutputSurface();
[email protected]45c4b1e2013-01-16 02:19:401359
[email protected]c1bb5af2013-03-13 19:06:271360 // Note: order is important here.
1361 renderer_.reset();
1362 tile_manager_.reset();
1363 resource_provider_.reset();
1364 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141365
[email protected]c1bb5af2013-03-13 19:06:271366 if (!output_surface->BindToClient(this))
1367 return false;
[email protected]be3181652012-09-25 13:02:131368
[email protected]075d8aa2013-04-01 23:03:111369 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1370 output_surface.get(), settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271371 if (!resource_provider)
1372 return false;
[email protected]be3181652012-09-25 13:02:131373
[email protected]8e0176d2013-03-21 03:14:521374 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:271375 tile_manager_.reset(new TileManager(this,
1376 resource_provider.get(),
[email protected]8e0176d2013-03-21 03:14:521377 settings_.num_raster_threads,
1378 settings_.use_cheapness_estimator,
1379 settings_.use_color_estimator,
[email protected]372bad5f2013-03-21 16:38:431380 settings_.prediction_benchmarking,
1381 rendering_stats_instrumentation_));
[email protected]c1bb5af2013-03-13 19:06:271382 }
[email protected]8947cbe2012-11-28 05:27:431383
[email protected]c1bb5af2013-03-13 19:06:271384 if (output_surface->capabilities().has_parent_compositor) {
1385 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1386 resource_provider.get());
1387 } else if (output_surface->context3d()) {
1388 renderer_ = GLRenderer::Create(this,
1389 output_surface.get(),
[email protected]075d8aa2013-04-01 23:03:111390 resource_provider.get(),
1391 settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271392 } else if (output_surface->software_device()) {
1393 renderer_ = SoftwareRenderer::Create(this,
1394 output_surface.get(),
1395 resource_provider.get());
1396 }
1397 if (!renderer_)
1398 return false;
[email protected]be3181652012-09-25 13:02:131399
[email protected]c1bb5af2013-03-13 19:06:271400 resource_provider_ = resource_provider.Pass();
1401 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141402
[email protected]c1bb5af2013-03-13 19:06:271403 if (!visible_)
1404 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141405
[email protected]c1bb5af2013-03-13 19:06:271406 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211407
[email protected]c1bb5af2013-03-13 19:06:271408 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1409 // to be initialized to get max texture size.
1410 active_tree_->set_needs_update_draw_properties();
1411 if (pending_tree_)
1412 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161413
[email protected]c1bb5af2013-03-13 19:06:271414 return true;
[email protected]94f206c12012-08-25 00:09:141415}
1416
[email protected]18ce59702013-04-09 04:58:401417void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) {
1418 if (device_viewport_size == device_viewport_size_)
[email protected]c1bb5af2013-03-13 19:06:271419 return;
[email protected]94f206c12012-08-25 00:09:141420
[email protected]c1bb5af2013-03-13 19:06:271421 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1422 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271423
[email protected]c1bb5af2013-03-13 19:06:271424 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141425
[email protected]c1bb5af2013-03-13 19:06:271426 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141427
[email protected]c1bb5af2013-03-13 19:06:271428 if (renderer_)
1429 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211430
[email protected]c1bb5af2013-03-13 19:06:271431 client_->OnCanDrawStateChanged(CanDraw());
[email protected]59adb112013-04-09 04:48:441432 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141433}
1434
[email protected]d9083762013-03-24 01:36:401435void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) {
1436 if (overdraw_bottom_height == overdraw_bottom_height_)
1437 return;
1438 overdraw_bottom_height_ = overdraw_bottom_height;
1439
1440 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441441 SetFullRootLayerDamage();
[email protected]d9083762013-03-24 01:36:401442}
1443
[email protected]c1bb5af2013-03-13 19:06:271444void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1445 if (device_scale_factor == device_scale_factor_)
1446 return;
1447 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271448
[email protected]c1bb5af2013-03-13 19:06:271449 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441450 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141451}
1452
[email protected]c1bb5af2013-03-13 19:06:271453void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1454 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141455}
1456
[email protected]59adb112013-04-09 04:48:441457void LayerTreeHostImpl::DidChangeTopControlsPosition() {
[email protected]c1bb5af2013-03-13 19:06:271458 client_->SetNeedsRedrawOnImplThread();
[email protected]59adb112013-04-09 04:48:441459 active_tree_->set_needs_update_draw_properties();
1460 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141461}
1462
[email protected]c1bb5af2013-03-13 19:06:271463bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1464 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
[email protected]3209161d2013-03-29 19:17:341465 return !active_tree_->RenderSurfaceLayerList().empty();
[email protected]94f206c12012-08-25 00:09:141466}
1467
[email protected]c1bb5af2013-03-13 19:06:271468InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1469 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
[email protected]ed511b8d2013-03-25 03:29:291470 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
[email protected]94f206c12012-08-25 00:09:141471
[email protected]c1bb5af2013-03-13 19:06:271472 if (top_controls_manager_)
1473 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381474
[email protected]c1bb5af2013-03-13 19:06:271475 DCHECK(!CurrentlyScrollingLayer());
1476 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141477
[email protected]c1bb5af2013-03-13 19:06:271478 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141479 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141480
[email protected]c1bb5af2013-03-13 19:06:271481 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1482 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141483
[email protected]c1bb5af2013-03-13 19:06:271484 // First find out which layer was hit from the saved list of visible layers
1485 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:391486 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:271487 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521488
[email protected]c1bb5af2013-03-13 19:06:271489 // Walk up the hierarchy and look for a scrollable layer.
1490 LayerImpl* potentially_scrolling_layer_impl = 0;
1491 for (; layer_impl; layer_impl = layer_impl->parent()) {
1492 // The content layer can also block attempts to scroll outside the main
1493 // thread.
1494 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1495 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431496 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271497 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421498 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271499 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141500 }
1501
[email protected]c1bb5af2013-03-13 19:06:271502 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1503 if (!scroll_layer_impl)
1504 continue;
[email protected]94f206c12012-08-25 00:09:141505
[email protected]c1bb5af2013-03-13 19:06:271506 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141507
[email protected]c1bb5af2013-03-13 19:06:271508 // If any layer wants to divert the scroll event to the main thread, abort.
1509 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431510 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271511 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421512 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271513 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141514 }
1515
[email protected]c1bb5af2013-03-13 19:06:271516 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1517 potentially_scrolling_layer_impl = scroll_layer_impl;
1518 }
1519
1520 // When hiding top controls is enabled and the controls are hidden or
1521 // overlaying the content, force scrolls to be enabled on the root layer to
1522 // allow bringing the top controls back into view.
1523 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1524 top_controls_manager_->content_top_offset() !=
[email protected]8e0176d2013-03-21 03:14:521525 settings_.top_controls_height) {
[email protected]c1bb5af2013-03-13 19:06:271526 potentially_scrolling_layer_impl = RootScrollLayer();
1527 }
1528
1529 if (potentially_scrolling_layer_impl) {
[email protected]0fc818e2013-03-18 06:45:201530 active_tree_->SetCurrentlyScrollingLayer(
[email protected]c1bb5af2013-03-13 19:06:271531 potentially_scrolling_layer_impl);
1532 should_bubble_scrolls_ = (type != NonBubblingGesture);
1533 wheel_scrolling_ = (type == Wheel);
[email protected]372bad5f2013-03-21 16:38:431534 rendering_stats_instrumentation_->IncrementImplThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271535 client_->RenewTreePriority();
1536 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421537 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271538 return ScrollStarted;
1539 }
1540 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141541}
1542
[email protected]c1bb5af2013-03-13 19:06:271543gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1544 LayerImpl* layer_impl,
1545 float scale_from_viewport_to_screen_space,
1546 gfx::PointF viewport_point,
1547 gfx::Vector2dF viewport_delta) {
1548 // Layers with non-invertible screen space transforms should not have passed
1549 // the scroll hit test in the first place.
1550 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1551 gfx::Transform inverse_screen_space_transform(
1552 gfx::Transform::kSkipInitialization);
1553 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1554 &inverse_screen_space_transform);
[email protected]ca2902e92013-03-28 01:45:351555 // TODO(shawnsingh): With the advent of impl-side crolling for non-root
1556 // layers, we may need to explicitly handle uninvertible transforms here.
[email protected]c1bb5af2013-03-13 19:06:271557 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141558
[email protected]c1bb5af2013-03-13 19:06:271559 gfx::PointF screen_space_point =
1560 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141561
[email protected]c1bb5af2013-03-13 19:06:271562 gfx::Vector2dF screen_space_delta = viewport_delta;
1563 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1564
1565 // First project the scroll start and end points to local layer space to find
1566 // the scroll delta in layer coordinates.
1567 bool start_clipped, end_clipped;
1568 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1569 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211570 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271571 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211572 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271573 gfx::PointF local_end_point =
[email protected]fa816c62013-03-18 04:24:211574 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271575 screen_space_end_point,
[email protected]fa816c62013-03-18 04:24:211576 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271577
1578 // In general scroll point coordinates should not get clipped.
1579 DCHECK(!start_clipped);
1580 DCHECK(!end_clipped);
1581 if (start_clipped || end_clipped)
1582 return gfx::Vector2dF();
1583
1584 // local_start_point and local_end_point are in content space but we want to
1585 // move them to layer space for scrolling.
1586 float width_scale = 1.f / layer_impl->contents_scale_x();
1587 float height_scale = 1.f / layer_impl->contents_scale_y();
1588 local_start_point.Scale(width_scale, height_scale);
1589 local_end_point.Scale(width_scale, height_scale);
1590
1591 // Apply the scroll delta.
1592 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1593 layer_impl->ScrollBy(local_end_point - local_start_point);
1594
1595 // Get the end point in the layer's content space so we can apply its
1596 // ScreenSpaceTransform.
1597 gfx::PointF actual_local_end_point = local_start_point +
1598 layer_impl->scroll_delta() -
1599 previous_delta;
1600 gfx::PointF actual_local_content_end_point =
1601 gfx::ScalePoint(actual_local_end_point,
1602 1.f / width_scale,
1603 1.f / height_scale);
1604
1605 // Calculate the applied scroll delta in viewport space coordinates.
1606 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211607 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271608 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211609 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271610 DCHECK(!end_clipped);
1611 if (end_clipped)
1612 return gfx::Vector2dF();
1613 gfx::PointF actual_viewport_end_point =
1614 gfx::ScalePoint(actual_screen_space_end_point,
1615 1.f / scale_from_viewport_to_screen_space);
1616 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141617}
1618
[email protected]c1bb5af2013-03-13 19:06:271619static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1620 gfx::Vector2dF local_delta) {
1621 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1622 layer_impl->ScrollBy(local_delta);
1623 return layer_impl->scroll_delta() - previous_delta;
1624}
1625
1626bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1627 gfx::Vector2dF scroll_delta) {
1628 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1629 if (!CurrentlyScrollingLayer())
1630 return false;
1631
1632 gfx::Vector2dF pending_delta = scroll_delta;
1633 bool did_scroll = false;
[email protected]60b4d252013-03-23 18:49:421634 bool consume_by_top_controls = top_controls_manager_ &&
1635 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0);
[email protected]a91e4f82013-03-15 06:58:061636
[email protected]c1bb5af2013-03-13 19:06:271637 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1638 layer_impl;
1639 layer_impl = layer_impl->parent()) {
1640 if (!layer_impl->scrollable())
1641 continue;
1642
[email protected]60b4d252013-03-23 18:49:421643 // Only allow bubble scrolling when the scroll is in the direction to make
1644 // the top controls visible.
1645 if (consume_by_top_controls && layer_impl == RootScrollLayer()) {
1646 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
1647 UpdateMaxScrollOffset();
1648 }
1649
[email protected]c1bb5af2013-03-13 19:06:271650 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271651 // Gesture events need to be transformed from viewport coordinates to local
1652 // layer coordinates so that the scrolling contents exactly follow the
1653 // user's finger. In contrast, wheel events represent a fixed amount of
1654 // scrolling so we can just apply them directly.
1655 if (!wheel_scrolling_) {
1656 float scale_from_viewport_to_screen_space = device_scale_factor_;
1657 applied_delta =
1658 ScrollLayerWithViewportSpaceDelta(layer_impl,
1659 scale_from_viewport_to_screen_space,
1660 viewport_point, pending_delta);
1661 } else {
1662 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141663 }
[email protected]94f206c12012-08-25 00:09:141664
[email protected]c1bb5af2013-03-13 19:06:271665 // If the layer wasn't able to move, try the next one in the hierarchy.
1666 float move_threshold_squared = 0.1f * 0.1f;
1667 if (applied_delta.LengthSquared() < move_threshold_squared) {
1668 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1669 continue;
1670 else
1671 break;
[email protected]94f206c12012-08-25 00:09:141672 }
[email protected]c1bb5af2013-03-13 19:06:271673 did_scroll = true;
1674 did_lock_scrolling_layer_ = true;
1675 if (!should_bubble_scrolls_) {
[email protected]0fc818e2013-03-18 06:45:201676 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
[email protected]c1bb5af2013-03-13 19:06:271677 break;
[email protected]94f206c12012-08-25 00:09:141678 }
[email protected]94f206c12012-08-25 00:09:141679
[email protected]c1bb5af2013-03-13 19:06:271680 // If the applied delta is within 45 degrees of the input delta, bail out to
1681 // make it easier to scroll just one layer in one direction without
1682 // affecting any of its parents.
1683 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211684 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271685 applied_delta, pending_delta) < angle_threshold) {
1686 pending_delta = gfx::Vector2d();
1687 break;
[email protected]4a23c374c2012-12-08 08:38:551688 }
[email protected]c1bb5af2013-03-13 19:06:271689
1690 // Allow further movement only on an axis perpendicular to the direction in
1691 // which the layer moved.
1692 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211693 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271694
1695 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1696 break;
1697 }
1698
[email protected]b7c4783f2013-03-15 23:11:421699 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271700 if (did_scroll) {
1701 client_->SetNeedsCommitOnImplThread();
1702 client_->SetNeedsRedrawOnImplThread();
1703 client_->RenewTreePriority();
1704 }
1705 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551706}
1707
[email protected]be782f52013-03-23 21:36:141708// This implements scrolling by page as described here:
1709// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel
1710// for events with WHEEL_PAGESCROLL set.
1711bool LayerTreeHostImpl::ScrollVerticallyByPage(
1712 gfx::Point viewport_point,
1713 WebKit::WebScrollbar::ScrollDirection direction) {
1714 DCHECK(wheel_scrolling_);
1715
1716 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1717 layer_impl;
1718 layer_impl = layer_impl->parent()) {
1719 if (!layer_impl->scrollable())
1720 continue;
1721
1722 if (!layer_impl->vertical_scrollbar_layer())
1723 continue;
1724
1725 float height = layer_impl->vertical_scrollbar_layer()->bounds().height();
1726
1727 // These magical values match WebKit and are designed to scroll nearly the
1728 // entire visible content height but leave a bit of overlap.
1729 float page = std::max(height * 0.875f, 1.f);
1730 if (direction == WebKit::WebScrollbar::ScrollBackward)
1731 page = -page;
1732
1733 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page);
1734
1735 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta);
1736
1737 if (!applied_delta.IsZero()) {
1738 active_tree()->DidUpdateScroll();
1739 client_->SetNeedsCommitOnImplThread();
1740 client_->SetNeedsRedrawOnImplThread();
1741 client_->RenewTreePriority();
1742 return true;
1743 }
1744
1745 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
1746 }
1747
1748 return false;
1749}
1750
[email protected]c1bb5af2013-03-13 19:06:271751void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1752 active_tree_->ClearCurrentlyScrollingLayer();
1753 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141754}
1755
[email protected]c1bb5af2013-03-13 19:06:271756void LayerTreeHostImpl::ScrollEnd() {
1757 if (top_controls_manager_)
1758 top_controls_manager_->ScrollEnd();
1759 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421760 active_tree()->DidEndScroll();
[email protected]fb7425a2013-04-22 16:28:551761 StartScrollbarAnimation(CurrentFrameTimeTicks());
[email protected]94f206c12012-08-25 00:09:141762}
1763
[email protected]7c45d8152013-04-23 18:27:211764InputHandlerClient::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() {
1765 if (active_tree_->CurrentlyScrollingLayer())
1766 return ScrollStarted;
1767
1768 return ScrollIgnored;
1769}
1770
[email protected]c1bb5af2013-03-13 19:06:271771void LayerTreeHostImpl::PinchGestureBegin() {
1772 pinch_gesture_active_ = true;
1773 previous_pinch_anchor_ = gfx::Point();
1774 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141775}
1776
[email protected]c1bb5af2013-03-13 19:06:271777void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1778 gfx::Point anchor) {
1779 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281780
[email protected]c1bb5af2013-03-13 19:06:271781 if (!RootScrollLayer())
1782 return;
[email protected]d3afa112012-12-08 06:24:281783
[email protected]c1bb5af2013-03-13 19:06:271784 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1785 // position over the course of the magnify.
1786 float page_scale_delta = active_tree_->page_scale_delta();
1787 gfx::PointF previous_scale_anchor =
1788 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1789 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1790 page_scale_delta = active_tree_->page_scale_delta();
1791 gfx::PointF new_scale_anchor =
1792 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1793 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1794
1795 previous_pinch_anchor_ = anchor;
1796
1797 move.Scale(1 / active_tree_->page_scale_factor());
1798
1799 RootScrollLayer()->ScrollBy(move);
1800
[email protected]c1bb5af2013-03-13 19:06:271801 client_->SetNeedsCommitOnImplThread();
1802 client_->SetNeedsRedrawOnImplThread();
1803 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281804}
1805
[email protected]c1bb5af2013-03-13 19:06:271806void LayerTreeHostImpl::PinchGestureEnd() {
1807 pinch_gesture_active_ = false;
[email protected]c1bb5af2013-03-13 19:06:271808 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141809}
1810
[email protected]c1bb5af2013-03-13 19:06:271811static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1812 LayerImpl* layer_impl) {
1813 if (!layer_impl)
1814 return;
[email protected]94f206c12012-08-25 00:09:141815
[email protected]c1bb5af2013-03-13 19:06:271816 gfx::Vector2d scroll_delta =
1817 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1818 if (!scroll_delta.IsZero()) {
1819 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]6ba914122013-03-22 16:26:391820 scroll.layer_id = layer_impl->id();
1821 scroll.scroll_delta = scroll_delta;
[email protected]c1bb5af2013-03-13 19:06:271822 scroll_info->scrolls.push_back(scroll);
1823 layer_impl->SetSentScrollDelta(scroll_delta);
1824 }
[email protected]94f206c12012-08-25 00:09:141825
[email protected]c1bb5af2013-03-13 19:06:271826 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1827 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141828}
1829
[email protected]c1bb5af2013-03-13 19:06:271830scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1831 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301832
[email protected]c1bb5af2013-03-13 19:06:271833 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
[email protected]6ba914122013-03-22 16:26:391834 scroll_info->page_scale_delta = active_tree_->page_scale_delta();
1835 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
[email protected]362f1e8b2013-01-21 16:54:301836
[email protected]c1bb5af2013-03-13 19:06:271837 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301838}
1839
[email protected]c1bb5af2013-03-13 19:06:271840void LayerTreeHostImpl::SetFullRootLayerDamage() {
[email protected]878705be2013-04-15 22:44:021841 SetViewportDamage(gfx::Rect(device_viewport_size_));
[email protected]829ad972013-01-28 23:36:101842}
1843
[email protected]c1bb5af2013-03-13 19:06:271844void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1845 if (!page_scale_animation_ || !RootScrollLayer())
1846 return;
1847
1848 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1849 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1850 RootScrollLayer()->scroll_delta();
1851
1852 active_tree_->SetPageScaleDelta(
1853 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1854 active_tree_->page_scale_factor());
1855 gfx::Vector2dF next_scroll =
1856 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1857
1858 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1859 client_->SetNeedsRedrawOnImplThread();
1860
1861 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1862 page_scale_animation_.reset();
1863 client_->SetNeedsCommitOnImplThread();
1864 client_->RenewTreePriority();
1865 }
[email protected]829ad972013-01-28 23:36:101866}
1867
[email protected]ffb2720f2013-03-15 19:18:371868void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1869 if (!top_controls_manager_ || !RootScrollLayer())
1870 return;
1871 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1872 UpdateMaxScrollOffset();
1873 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1874 scroll, 1.f / active_tree_->total_page_scale_factor()));
1875}
1876
[email protected]c1bb5af2013-03-13 19:06:271877void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1878 base::Time wall_clock_time) {
[email protected]8e0176d2013-03-21 03:14:521879 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271880 animation_registrar_->active_animation_controllers().empty() ||
1881 !active_tree_->root_layer())
1882 return;
1883
1884 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1885
1886 last_animation_time_ = wall_clock_time;
1887 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1888
1889 AnimationRegistrar::AnimationControllerMap copy =
1890 animation_registrar_->active_animation_controllers();
1891 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1892 iter != copy.end();
1893 ++iter)
1894 (*iter).second->Animate(monotonic_seconds);
1895
1896 client_->SetNeedsRedrawOnImplThread();
[email protected]131a0c22013-02-12 18:31:081897}
1898
[email protected]3d9f7432013-04-06 00:35:181899void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
[email protected]8e0176d2013-03-21 03:14:521900 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271901 animation_registrar_->active_animation_controllers().empty() ||
1902 !active_tree_->root_layer())
1903 return;
1904
1905 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1906 scoped_ptr<AnimationEventsVector> events =
1907 make_scoped_ptr(new AnimationEventsVector);
1908 AnimationRegistrar::AnimationControllerMap copy =
1909 animation_registrar_->active_animation_controllers();
1910 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1911 iter != copy.end();
1912 ++iter)
[email protected]3d9f7432013-04-06 00:35:181913 (*iter).second->UpdateState(start_ready_animations, events.get());
[email protected]c1bb5af2013-03-13 19:06:271914
1915 if (!events->empty()) {
1916 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1917 last_animation_time_);
1918 }
[email protected]131a0c22013-02-12 18:31:081919}
1920
[email protected]c1bb5af2013-03-13 19:06:271921base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1922 return base::TimeDelta::FromSeconds(1);
1923}
1924
1925void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1926 DCHECK(current);
1927 current->DidLoseOutputSurface();
1928 if (current->mask_layer())
1929 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1930 if (current->replica_layer())
1931 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1932 for (size_t i = 0; i < current->children().size(); ++i)
1933 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1934}
1935
1936void LayerTreeHostImpl::ClearRenderSurfaces() {
1937 active_tree_->ClearRenderSurfaces();
1938 if (pending_tree_)
1939 pending_tree_->ClearRenderSurfaces();
1940}
1941
1942std::string LayerTreeHostImpl::LayerTreeAsText() const {
1943 std::string str;
1944 if (active_tree_->root_layer()) {
1945 str = active_tree_->root_layer()->LayerTreeAsText();
1946 str += "RenderSurfaces:\n";
1947 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1948 }
1949 return str;
1950}
1951
1952std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1953 std::string str;
1954 if (active_tree_->root_layer()) {
1955 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1956 base::JSONWriter::WriteWithOptions(
1957 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1958 }
1959 return str;
1960}
1961
1962void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1963 int indent,
1964 const LayerImpl* layer) const {
1965 if (layer->render_surface())
1966 layer->render_surface()->DumpSurface(str, indent);
1967
1968 for (size_t i = 0; i < layer->children().size(); ++i)
1969 DumpRenderSurfaces(str, indent, layer->children()[i]);
1970}
1971
1972int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:361973 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:271974}
1975
[email protected]c1bb5af2013-03-13 19:06:271976void LayerTreeHostImpl::SendManagedMemoryStats(
1977 size_t memory_visible_bytes,
1978 size_t memory_visible_and_nearby_bytes,
1979 size_t memory_use_bytes) {
1980 if (!renderer_)
1981 return;
1982
1983 // Round the numbers being sent up to the next 8MB, to throttle the rate
1984 // at which we spam the GPU process.
1985 static const size_t rounding_step = 8 * 1024 * 1024;
1986 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1987 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1988 rounding_step);
1989 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1990 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1991 last_sent_memory_visible_and_nearby_bytes_ ==
1992 memory_visible_and_nearby_bytes &&
1993 last_sent_memory_use_bytes_ == memory_use_bytes) {
1994 return;
1995 }
1996 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1997 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1998 last_sent_memory_use_bytes_ = memory_use_bytes;
1999
2000 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
2001 last_sent_memory_visible_and_nearby_bytes_,
2002 last_sent_memory_use_bytes_);
2003}
2004
2005void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
2006 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
2007}
2008
2009void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
2010 base::TimeTicks time) {
2011 if (!layer)
2012 return;
2013
2014 ScrollbarAnimationController* scrollbar_controller =
2015 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352016 if (scrollbar_controller && scrollbar_controller->Animate(time)) {
[email protected]0fc818e2013-03-18 06:45:202017 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:422018 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
2019 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:272020 client_->SetNeedsRedrawOnImplThread();
[email protected]0fc818e2013-03-18 06:45:202021 }
[email protected]c1bb5af2013-03-13 19:06:272022
2023 for (size_t i = 0; i < layer->children().size(); ++i)
2024 AnimateScrollbarsRecursive(layer->children()[i], time);
2025}
2026
[email protected]0fc818e2013-03-18 06:45:202027void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time) {
2028 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
2029 StartScrollbarAnimationRecursive(RootLayer(), time);
2030}
2031
2032void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
2033 base::TimeTicks time) {
2034 if (!layer)
2035 return;
2036
2037 ScrollbarAnimationController* scrollbar_controller =
2038 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352039 if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
2040 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
[email protected]0fc818e2013-03-18 06:45:202041 if (delay > base::TimeDelta())
2042 client_->RequestScrollbarAnimationOnImplThread(delay);
[email protected]6bc09e82013-03-19 03:48:352043 else if (scrollbar_controller->Animate(time))
[email protected]0fc818e2013-03-18 06:45:202044 client_->SetNeedsRedrawOnImplThread();
2045 }
2046
2047 for (size_t i = 0; i < layer->children().size(); ++i)
2048 StartScrollbarAnimationRecursive(layer->children()[i], time);
2049}
2050
[email protected]c1bb5af2013-03-13 19:06:272051void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
2052 if (!tile_manager_)
2053 return;
2054
2055 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
2056 if (new_state.tree_priority == priority)
2057 return;
2058
2059 new_state.tree_priority = priority;
2060 tile_manager_->SetGlobalState(new_state);
2061}
2062
2063void LayerTreeHostImpl::BeginNextFrame() {
[email protected]fb7425a2013-04-22 16:28:552064 current_frame_timeticks_ = base::TimeTicks();
2065 current_frame_time_ = base::Time();
[email protected]c1bb5af2013-03-13 19:06:272066}
2067
[email protected]fb7425a2013-04-22 16:28:552068static void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) {
2069 if (ticks->is_null()) {
2070 DCHECK(now->is_null());
2071 *ticks = base::TimeTicks::Now();
2072 *now = base::Time::Now();
2073 }
2074}
2075
2076base::TimeTicks LayerTreeHostImpl::CurrentFrameTimeTicks() {
2077 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
2078 return current_frame_timeticks_;
2079}
2080
2081base::Time LayerTreeHostImpl::CurrentFrameTime() {
2082 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
[email protected]c1bb5af2013-03-13 19:06:272083 return current_frame_time_;
2084}
2085
2086scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
2087 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
2088 state->Set("activation_state", ActivationStateAsValue().release());
2089 state->Set("frame_state", FrameStateAsValue().release());
2090 return state.PassAs<base::Value>();
2091}
2092
2093scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
2094 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042095 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272096 state->SetBoolean("visible_resources_ready",
2097 pending_tree_->AreVisibleResourcesReady());
2098 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
2099 return state.PassAs<base::Value>();
2100}
2101
2102scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
2103 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:042104 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:272105 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:212106 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:272107 if (tile_manager_)
2108 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
2109 state->Set("active_tree", active_tree_->AsValue().release());
2110 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:082111}
2112
[email protected]b9dcf43a2013-01-09 00:15:292113// static
[email protected]c1bb5af2013-03-13 19:06:272114LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
2115 LayerImpl* layer) {
2116 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:292117 return NULL;
[email protected]c1bb5af2013-03-13 19:06:272118
2119 if (layer->DrawsContent())
2120 return layer;
2121
[email protected]50761e92013-03-29 20:51:282122 for (LayerImplList::const_iterator it = layer->children().begin();
[email protected]c1bb5af2013-03-13 19:06:272123 it != layer->children().end(); ++it) {
2124 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
2125 if (nccr)
2126 return nccr;
2127 }
2128
2129 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:292130}
2131
[email protected]c1bb5af2013-03-13 19:06:272132skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
2133 LayerTreeImpl* tree =
2134 pending_tree_ ? pending_tree_.get() : active_tree_.get();
2135 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
2136 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:292137}
2138
[email protected]c1bb5af2013-03-13 19:06:272139void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
[email protected]846f455b2013-03-18 19:07:412140 if (debug_state_.continuous_painting != debug_state.continuous_painting)
[email protected]c1bb5af2013-03-13 19:06:272141 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:242142
[email protected]c1bb5af2013-03-13 19:06:272143 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:022144}
2145
[email protected]d3143c732012-10-05 19:17:592146} // namespace cc