blob: efcc5295465539f182d6628e1092abb1ea3989fe [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]4a23c374c2012-12-08 08:38:5510#include "base/json/json_writer.h"
[email protected]f5864912013-02-01 03:18:1411#include "base/metrics/histogram.h"
[email protected]de4afb5e2012-12-20 00:11:3412#include "base/stl_util.h"
[email protected]131a0c22013-02-12 18:31:0813#include "base/stringprintf.h"
[email protected]95e4e1a02013-03-18 07:09:0914#include "cc/animation/scrollbar_animation_controller.h"
[email protected]85d136f782013-04-26 22:04:4015#include "cc/animation/timing_function.h"
[email protected]681ccff2013-03-18 06:13:5216#include "cc/base/math_util.h"
17#include "cc/base/util.h"
[email protected]6e84de22013-03-18 06:54:2718#include "cc/debug/debug_rect_history.h"
19#include "cc/debug/frame_rate_counter.h"
20#include "cc/debug/overdraw_metrics.h"
21#include "cc/debug/paint_time_counter.h"
[email protected]372bad5f2013-03-21 16:38:4322#include "cc/debug/rendering_stats_instrumentation.h"
[email protected]f6742f52013-05-08 23:52:2223#include "cc/debug/traced_value.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:2769} // namespace
[email protected]94f206c12012-08-25 00:09:1470
[email protected]9c88e562012-09-14 22:21:3071namespace cc {
[email protected]94f206c12012-08-25 00:09:1472
[email protected]96baf3e2012-10-22 23:09:5573class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]c1bb5af2013-03-13 19:06:2774 public:
75 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
76 LayerTreeHostImpl* layer_tree_host_impl,
77 scoped_refptr<DelayBasedTimeSource> time_source) {
78 return make_scoped_ptr(
79 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
80 time_source));
81 }
82 virtual ~LayerTreeHostImplTimeSourceAdapter() {
[email protected]6d0e69d2013-03-20 14:53:2683 time_source_->SetClient(NULL);
84 time_source_->SetActive(false);
[email protected]c1bb5af2013-03-13 19:06:2785 }
86
[email protected]6d0e69d2013-03-20 14:53:2687 virtual void OnTimerTick() OVERRIDE {
[email protected]c1bb5af2013-03-13 19:06:2788 // In single threaded mode we attempt to simulate changing the current
89 // thread by maintaining a fake thread id. When we switch from one
90 // thread to another, we construct DebugScopedSetXXXThread objects that
91 // update the thread id. This lets DCHECKS that ensure we're on the
92 // right thread to work correctly in single threaded mode. The problem
93 // here is that the timer tasks are run via the message loop, and when
94 // they run, we've had no chance to construct a DebugScopedSetXXXThread
95 // object. The result is that we report that we're running on the main
96 // thread. In multi-threaded mode, this timer is run on the compositor
97 // thread, so to keep this consistent in single-threaded mode, we'll
98 // construct a DebugScopedSetImplThread object. There is no need to do
99 // this in multi-threaded mode since the real thread id's will be
100 // correct. In fact, setting fake thread id's interferes with the real
101 // thread id's and causes breakage.
102 scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
103 if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
104 set_impl_thread.reset(
105 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
[email protected]94f206c12012-08-25 00:09:14106 }
107
[email protected]c1bb5af2013-03-13 19:06:27108 layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
[email protected]fb7425a2013-04-22 16:28:55109 layer_tree_host_impl_->Animate(
110 layer_tree_host_impl_->CurrentFrameTimeTicks(),
111 layer_tree_host_impl_->CurrentFrameTime());
[email protected]3d9f7432013-04-06 00:35:18112 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
113 bool start_ready_animations = true;
114 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]c1bb5af2013-03-13 19:06:27115 layer_tree_host_impl_->BeginNextFrame();
116 }
[email protected]373974232013-01-10 22:20:50117
[email protected]c1bb5af2013-03-13 19:06:27118 void SetActive(bool active) {
[email protected]6d0e69d2013-03-20 14:53:26119 if (active != time_source_->Active())
120 time_source_->SetActive(active);
[email protected]c1bb5af2013-03-13 19:06:27121 }
[email protected]94f206c12012-08-25 00:09:14122
[email protected]c1bb5af2013-03-13 19:06:27123 private:
124 LayerTreeHostImplTimeSourceAdapter(
125 LayerTreeHostImpl* layer_tree_host_impl,
126 scoped_refptr<DelayBasedTimeSource> time_source)
127 : layer_tree_host_impl_(layer_tree_host_impl),
128 time_source_(time_source) {
[email protected]6d0e69d2013-03-20 14:53:26129 time_source_->SetClient(this);
[email protected]c1bb5af2013-03-13 19:06:27130 }
[email protected]94f206c12012-08-25 00:09:14131
[email protected]c1bb5af2013-03-13 19:06:27132 LayerTreeHostImpl* layer_tree_host_impl_;
133 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14134
[email protected]c1bb5af2013-03-13 19:06:27135 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14136};
137
[email protected]96baf3e2012-10-22 23:09:55138LayerTreeHostImpl::FrameData::FrameData()
[email protected]e0341352013-04-06 05:01:20139 : contains_incomplete_tile(false), has_no_damage(false) {}
[email protected]c1bb5af2013-03-13 19:06:27140
141LayerTreeHostImpl::FrameData::~FrameData() {}
142
143scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
144 const LayerTreeSettings& settings,
145 LayerTreeHostImplClient* client,
[email protected]372bad5f2013-03-21 16:38:43146 Proxy* proxy,
147 RenderingStatsInstrumentation* rendering_stats_instrumentation) {
148 return make_scoped_ptr(
149 new LayerTreeHostImpl(settings,
150 client,
151 proxy,
152 rendering_stats_instrumentation));
[email protected]493067512012-09-19 23:34:10153}
154
[email protected]372bad5f2013-03-21 16:38:43155LayerTreeHostImpl::LayerTreeHostImpl(
156 const LayerTreeSettings& settings,
157 LayerTreeHostImplClient* client,
158 Proxy* proxy,
159 RenderingStatsInstrumentation* rendering_stats_instrumentation)
[email protected]c1bb5af2013-03-13 19:06:27160 : client_(client),
161 proxy_(proxy),
162 did_lock_scrolling_layer_(false),
163 should_bubble_scrolls_(false),
164 wheel_scrolling_(false),
[email protected]1960a712013-04-30 17:06:47165 root_layer_scroll_offset_delegate_(NULL),
[email protected]c1bb5af2013-03-13 19:06:27166 settings_(settings),
[email protected]d9083762013-03-24 01:36:40167 overdraw_bottom_height_(0.f),
[email protected]c1bb5af2013-03-13 19:06:27168 device_scale_factor_(1.f),
169 visible_(true),
170 managed_memory_policy_(
[email protected]b56c1302013-03-20 21:17:34171 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
[email protected]c1bb5af2013-03-13 19:06:27172 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
173 0,
174 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
175 pinch_gesture_active_(false),
[email protected]9e3594522013-03-18 00:57:36176 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29177 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27178 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02179 debug_rect_history_(DebugRectHistory::Create()),
[email protected]d7626ffd2013-03-29 00:17:42180 max_memory_needed_bytes_(0),
[email protected]c1bb5af2013-03-13 19:06:27181 last_sent_memory_visible_bytes_(0),
182 last_sent_memory_visible_and_nearby_bytes_(0),
183 last_sent_memory_use_bytes_(0),
[email protected]372bad5f2013-03-21 16:38:43184 animation_registrar_(AnimationRegistrar::Create()),
185 rendering_stats_instrumentation_(rendering_stats_instrumentation) {
[email protected]c1bb5af2013-03-13 19:06:27186 DCHECK(proxy_->IsImplThread());
187 DidVisibilityChange(this, visible_);
188
[email protected]8e0176d2013-03-21 03:14:52189 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27190
[email protected]8e0176d2013-03-21 03:14:52191 if (settings.calculate_top_controls_position) {
[email protected]c1bb5af2013-03-13 19:06:27192 top_controls_manager_ =
193 TopControlsManager::Create(this,
[email protected]8e0176d2013-03-21 03:14:52194 settings.top_controls_height,
195 settings.top_controls_show_threshold,
196 settings.top_controls_hide_threshold);
[email protected]c1bb5af2013-03-13 19:06:27197 }
198
[email protected]8e0176d2013-03-21 03:14:52199 SetDebugState(settings.initial_debug_state);
[email protected]c1bb5af2013-03-13 19:06:27200
201 // LTHI always has an active tree.
202 active_tree_ = LayerTreeImpl::create(this);
[email protected]f6742f52013-05-08 23:52:22203 TRACE_EVENT_OBJECT_CREATED_WITH_ID("cc.debug", "cc::LayerTreeHostImpl", this);
[email protected]493067512012-09-19 23:34:10204}
205
[email protected]c1bb5af2013-03-13 19:06:27206LayerTreeHostImpl::~LayerTreeHostImpl() {
207 DCHECK(proxy_->IsImplThread());
208 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
[email protected]f6742f52013-05-08 23:52:22209 TRACE_EVENT_OBJECT_DELETED_WITH_ID("cc.debug", "cc::LayerTreeHostImpl", this);
[email protected]c1bb5af2013-03-13 19:06:27210
211 if (active_tree_->root_layer()) {
212 ClearRenderSurfaces();
213 // The layer trees must be destroyed before the layer tree host. We've
214 // made a contract with our animation controllers that the registrar
215 // will outlive them, and we must make good.
216 recycle_tree_.reset();
217 pending_tree_.reset();
218 active_tree_.reset();
219 }
[email protected]94f206c12012-08-25 00:09:14220}
221
[email protected]c1bb5af2013-03-13 19:06:27222void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29223
[email protected]c1bb5af2013-03-13 19:06:27224void LayerTreeHostImpl::CommitComplete() {
225 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08226
[email protected]c1bb5af2013-03-13 19:06:27227 // Impl-side painting needs an update immediately post-commit to have the
228 // opportunity to create tilings. Other paths can call UpdateDrawProperties
229 // more lazily when needed prior to drawing.
[email protected]8e0176d2013-03-21 03:14:52230 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:27231 pending_tree_->set_needs_update_draw_properties();
[email protected]7d19dc342013-05-02 22:02:04232 pending_tree_->UpdateDrawProperties();
[email protected]c1bb5af2013-03-13 19:06:27233 } else {
234 active_tree_->set_needs_update_draw_properties();
235 }
[email protected]3ba4cae2013-01-16 03:58:38236
[email protected]c1bb5af2013-03-13 19:06:27237 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14238}
239
[email protected]c1bb5af2013-03-13 19:06:27240bool LayerTreeHostImpl::CanDraw() {
241 // Note: If you are changing this function or any other function that might
242 // affect the result of CanDraw, make sure to call
243 // client_->OnCanDrawStateChanged in the proper places and update the
244 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14245
[email protected]c1bb5af2013-03-13 19:06:27246 if (!active_tree_->root_layer()) {
[email protected]c76faea2013-03-26 07:42:42247 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
248 TRACE_EVENT_SCOPE_THREAD);
[email protected]2f1acc262012-11-16 21:42:22249 return false;
[email protected]c1bb5af2013-03-13 19:06:27250 }
251 if (device_viewport_size_.IsEmpty()) {
[email protected]c76faea2013-03-26 07:42:42252 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
253 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27254 return false;
255 }
256 if (active_tree_->ViewportSizeInvalid()) {
257 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42258 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed",
259 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27260 return false;
261 }
262 if (!renderer_) {
[email protected]c76faea2013-03-26 07:42:42263 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer",
264 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27265 return false;
266 }
267 if (active_tree_->ContentsTexturesPurged()) {
268 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:42269 "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
270 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:27271 return false;
272 }
273 return true;
[email protected]2f1acc262012-11-16 21:42:22274}
275
[email protected]c1bb5af2013-03-13 19:06:27276void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
277 base::Time wall_clock_time) {
278 AnimatePageScale(monotonic_time);
279 AnimateLayers(monotonic_time, wall_clock_time);
280 AnimateScrollbars(monotonic_time);
[email protected]ffb2720f2013-03-15 19:18:37281 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14282}
283
[email protected]c1bb5af2013-03-13 19:06:27284void LayerTreeHostImpl::ManageTiles() {
285 DCHECK(tile_manager_);
286 tile_manager_->ManageTiles();
287
288 size_t memory_required_bytes;
289 size_t memory_nice_to_have_bytes;
290 size_t memory_used_bytes;
291 tile_manager_->GetMemoryStats(&memory_required_bytes,
292 &memory_nice_to_have_bytes,
293 &memory_used_bytes);
294 SendManagedMemoryStats(memory_required_bytes,
295 memory_nice_to_have_bytes,
296 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15297}
298
[email protected]c1bb5af2013-03-13 19:06:27299void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
300 bool anchor_point,
301 float page_scale,
302 base::TimeTicks start_time,
303 base::TimeDelta duration) {
304 if (!RootScrollLayer())
305 return;
306
307 gfx::Vector2dF scroll_total =
[email protected]1960a712013-04-30 17:06:47308 RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta();
[email protected]c1bb5af2013-03-13 19:06:27309 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
[email protected]6fc4ee002013-03-26 23:39:51310 gfx::SizeF viewport_size = VisibleViewportSize();
[email protected]c1bb5af2013-03-13 19:06:27311
312 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
[email protected]85d136f782013-04-26 22:04:40313
314 // Easing constants experimentally determined.
315 scoped_ptr<TimingFunction> timing_function =
316 CubicBezierTimingFunction::Create(.8, 0, .3, .9).PassAs<TimingFunction>();
317
[email protected]c1bb5af2013-03-13 19:06:27318 page_scale_animation_ =
319 PageScaleAnimation::Create(scroll_total,
320 active_tree_->total_page_scale_factor(),
321 viewport_size,
322 scaled_scrollable_size,
[email protected]85d136f782013-04-26 22:04:40323 start_time_seconds,
324 timing_function.Pass());
[email protected]c1bb5af2013-03-13 19:06:27325
326 if (anchor_point) {
327 gfx::Vector2dF anchor(target_offset);
328 page_scale_animation_->ZoomWithAnchor(anchor,
329 page_scale,
330 duration.InSecondsF());
331 } else {
332 gfx::Vector2dF scaled_target_offset = target_offset;
333 page_scale_animation_->ZoomTo(scaled_target_offset,
334 page_scale,
335 duration.InSecondsF());
336 }
337
338 client_->SetNeedsRedrawOnImplThread();
339 client_->SetNeedsCommitOnImplThread();
340 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15341}
342
[email protected]c1bb5af2013-03-13 19:06:27343void LayerTreeHostImpl::ScheduleAnimation() {
344 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15345}
346
[email protected]c1bb5af2013-03-13 19:06:27347bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
348 if (!EnsureRenderSurfaceLayerList())
349 return false;
[email protected]f57bbc02012-11-21 07:02:15350
[email protected]c1bb5af2013-03-13 19:06:27351 gfx::PointF device_viewport_point =
352 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15353
[email protected]c1bb5af2013-03-13 19:06:27354 // First find out which layer was hit from the saved list of visible layers
355 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:39356 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:27357 device_viewport_point,
358 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15359
[email protected]c1bb5af2013-03-13 19:06:27360 // Walk up the hierarchy and look for a layer with a touch event handler
361 // region that the given point hits.
362 for (; layer_impl; layer_impl = layer_impl->parent()) {
[email protected]6ba914122013-03-22 16:26:39363 if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point,
[email protected]c1bb5af2013-03-13 19:06:27364 layer_impl))
365 return true;
366 }
[email protected]f57bbc02012-11-21 07:02:15367
[email protected]c1bb5af2013-03-13 19:06:27368 return false;
369}
370
[email protected]ef915f532013-04-22 20:56:32371void LayerTreeHostImpl::DidReceiveLastInputEventForVSync(
372 base::TimeTicks frame_time) {
373 client_->DidReceiveLastInputEventForVSync(frame_time);
374}
375
[email protected]c1bb5af2013-03-13 19:06:27376void LayerTreeHostImpl::TrackDamageForAllSurfaces(
377 LayerImpl* root_draw_layer,
[email protected]50761e92013-03-29 20:51:28378 const LayerImplList& render_surface_layer_list) {
[email protected]c1bb5af2013-03-13 19:06:27379 // For now, we use damage tracking to compute a global scissor. To do this, we
380 // must compute all damage tracking before drawing anything, so that we know
381 // the root damage rect. The root damage rect is then used to scissor each
382 // surface.
383
384 for (int surface_index = render_surface_layer_list.size() - 1;
[email protected]bf691c22013-03-26 21:15:06385 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27386 --surface_index) {
387 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
388 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
389 DCHECK(render_surface);
390 render_surface->damage_tracker()->UpdateDamageTrackingState(
391 render_surface->layer_list(),
392 render_surface_layer->id(),
393 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
394 render_surface->content_rect(),
395 render_surface_layer->mask_layer(),
396 render_surface_layer->filters(),
397 render_surface_layer->filter().get());
398 }
399}
400
401void LayerTreeHostImpl::FrameData::AppendRenderPass(
402 scoped_ptr<RenderPass> render_pass) {
403 render_passes_by_id[render_pass->id] = render_pass.get();
404 render_passes.push_back(render_pass.Pass());
405}
406
407static void AppendQuadsForLayer(RenderPass* target_render_pass,
408 LayerImpl* layer,
409 const OcclusionTrackerImpl& occlusion_tracker,
410 AppendQuadsData* append_quads_data) {
411 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49412 QuadCuller quad_culler(&target_render_pass->quad_list,
413 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27414 layer,
415 occlusion_tracker,
416 layer->ShowDebugBorders(),
417 for_surface);
418 layer->AppendQuads(&quad_culler, append_quads_data);
419}
420
421static void AppendQuadsForRenderSurfaceLayer(
422 RenderPass* target_render_pass,
423 LayerImpl* layer,
424 const RenderPass* contributing_render_pass,
425 const OcclusionTrackerImpl& occlusion_tracker,
426 AppendQuadsData* append_quads_data) {
427 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49428 QuadCuller quad_culler(&target_render_pass->quad_list,
429 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27430 layer,
431 occlusion_tracker,
432 layer->ShowDebugBorders(),
433 for_surface);
434
435 bool is_replica = false;
436 layer->render_surface()->AppendQuads(&quad_culler,
437 append_quads_data,
438 is_replica,
439 contributing_render_pass->id);
440
441 // Add replica after the surface so that it appears below the surface.
442 if (layer->has_replica()) {
443 is_replica = true;
444 layer->render_surface()->AppendQuads(&quad_culler,
445 append_quads_data,
446 is_replica,
447 contributing_render_pass->id);
448 }
449}
450
451static void AppendQuadsToFillScreen(
452 RenderPass* target_render_pass,
453 LayerImpl* root_layer,
454 SkColor screen_background_color,
455 const OcclusionTrackerImpl& occlusion_tracker) {
456 if (!root_layer || !SkColorGetA(screen_background_color))
457 return;
458
459 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
460 if (fill_region.IsEmpty())
461 return;
462
463 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49464 QuadCuller quad_culler(&target_render_pass->quad_list,
465 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27466 root_layer,
467 occlusion_tracker,
468 root_layer->ShowDebugBorders(),
469 for_surface);
470
471 // Manually create the quad state for the gutter quads, as the root layer
472 // doesn't have any bounds and so can't generate this itself.
473 // TODO(danakj): Make the gutter quads generated by the solid color layer
474 // (make it smarter about generating quads to fill unoccluded areas).
475
476 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
477 float opacity = 1.f;
478 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49479 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27480 shared_quad_state->SetAll(root_layer->draw_transform(),
481 root_target_rect.size(),
482 root_target_rect,
483 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01484 false,
[email protected]f57bbc02012-11-21 07:02:15485 opacity);
486
[email protected]c1bb5af2013-03-13 19:06:27487 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17488
[email protected]c1bb5af2013-03-13 19:06:27489 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
490 bool did_invert = root_layer->screen_space_transform().GetInverse(
491 &transform_to_layer_space);
492 DCHECK(did_invert);
493 for (Region::Iterator fill_rects(fill_region);
494 fill_rects.has_rect();
495 fill_rects.next()) {
496 // The root layer transform is composed of translations and scales only,
497 // no perspective, so mapping is sufficient (as opposed to projecting).
498 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21499 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27500 // Skip the quad culler and just append the quads directly to avoid
501 // occlusion checks.
502 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
[email protected]10a30b12013-05-02 16:42:11503 quad->SetNew(shared_quad_state, layer_rect, screen_background_color, false);
[email protected]c7e95b42013-03-18 01:13:49504 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27505 }
[email protected]467b3612012-08-28 07:41:16506}
507
[email protected]c1bb5af2013-03-13 19:06:27508bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
509 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14510
[email protected]c1bb5af2013-03-13 19:06:27511 if (!CanDraw() || !active_tree_->root_layer())
512 return false;
[email protected]2d692992012-12-19 01:19:32513
[email protected]c1bb5af2013-03-13 19:06:27514 TrackDamageForAllSurfaces(active_tree_->root_layer(),
515 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14516
[email protected]e0341352013-04-06 05:01:20517 // If the root render surface has no visible damage, then don't generate a
518 // frame at all.
519 RenderSurfaceImpl* root_surface =
520 active_tree_->root_layer()->render_surface();
521 bool root_surface_has_no_visible_damage =
522 !root_surface->damage_tracker()->current_damage_rect().Intersects(
523 root_surface->content_rect());
524 bool root_surface_has_contributing_layers =
525 !root_surface->layer_list().empty();
526 if (root_surface_has_contributing_layers &&
527 root_surface_has_no_visible_damage) {
528 TRACE_EVENT0("cc",
529 "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
530 frame->has_no_damage = true;
531 return true;
532 }
533
[email protected]c1bb5af2013-03-13 19:06:27534 TRACE_EVENT1("cc",
535 "LayerTreeHostImpl::CalculateRenderPasses",
536 "render_surface_layer_list.size()",
[email protected]bf691c22013-03-26 21:15:06537 static_cast<uint64>(frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14538
[email protected]c1bb5af2013-03-13 19:06:27539 // Create the render passes in dependency order.
540 for (int surface_index = frame->render_surface_layer_list->size() - 1;
[email protected]bf691c22013-03-26 21:15:06541 surface_index >= 0;
[email protected]c1bb5af2013-03-13 19:06:27542 --surface_index) {
543 LayerImpl* render_surface_layer =
544 (*frame->render_surface_layer_list)[surface_index];
545 render_surface_layer->render_surface()->AppendRenderPasses(frame);
546 }
[email protected]94f206c12012-08-25 00:09:14547
[email protected]c1bb5af2013-03-13 19:06:27548 bool record_metrics_for_frame =
[email protected]8e0176d2013-03-21 03:14:52549 settings_.show_overdraw_in_tracing &&
[email protected]c1bb5af2013-03-13 19:06:27550 base::debug::TraceLog::GetInstance() &&
551 base::debug::TraceLog::GetInstance()->IsEnabled();
552 OcclusionTrackerImpl occlusion_tracker(
553 active_tree_->root_layer()->render_surface()->content_rect(),
554 record_metrics_for_frame);
555 occlusion_tracker.set_minimum_tracking_size(
[email protected]8e0176d2013-03-21 03:14:52556 settings_.minimum_occlusion_tracking_size);
[email protected]94f206c12012-08-25 00:09:14557
[email protected]846f455b2013-03-18 19:07:41558 if (debug_state_.show_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27559 occlusion_tracker.set_occluding_screen_space_rects_container(
560 &frame->occluding_screen_space_rects);
561 }
[email protected]846f455b2013-03-18 19:07:41562 if (debug_state_.show_non_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27563 occlusion_tracker.set_non_occluding_screen_space_rects_container(
564 &frame->non_occluding_screen_space_rects);
565 }
[email protected]94f206c12012-08-25 00:09:14566
[email protected]c1bb5af2013-03-13 19:06:27567 // Add quads to the Render passes in FrontToBack order to allow for testing
568 // occlusion and performing culling during the tree walk.
569 typedef LayerIterator<LayerImpl,
[email protected]50761e92013-03-29 20:51:28570 LayerImplList,
[email protected]c1bb5af2013-03-13 19:06:27571 RenderSurfaceImpl,
572 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14573
[email protected]c1bb5af2013-03-13 19:06:27574 // Typically when we are missing a texture and use a checkerboard quad, we
575 // still draw the frame. However when the layer being checkerboarded is moving
576 // due to an impl-animation, we drop the frame to avoid flashing due to the
577 // texture suddenly appearing in the future.
578 bool draw_frame = true;
[email protected]18a70192013-04-26 16:18:25579 // When we have a copy request for a layer, we need to draw no matter
580 // what, as the layer may disappear after this frame.
581 bool have_copy_request = false;
[email protected]94f206c12012-08-25 00:09:14582
[email protected]372bad5f2013-03-21 16:38:43583 int layers_drawn = 0;
584
[email protected]c1bb5af2013-03-13 19:06:27585 LayerIteratorType end =
[email protected]71dfcc72013-03-20 21:30:09586 LayerIteratorType::End(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27587 for (LayerIteratorType it =
[email protected]71dfcc72013-03-20 21:30:09588 LayerIteratorType::Begin(frame->render_surface_layer_list);
[email protected]c1bb5af2013-03-13 19:06:27589 it != end;
590 ++it) {
591 RenderPass::Id target_render_pass_id =
[email protected]71dfcc72013-03-20 21:30:09592 it.target_render_surface_layer()->render_surface()->RenderPassId();
[email protected]c1bb5af2013-03-13 19:06:27593 RenderPass* target_render_pass =
594 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14595
[email protected]2ea5e6c2013-04-26 21:52:23596 bool prevent_occlusion =
597 it.target_render_surface_layer()->HasRequestCopyCallback();
598 occlusion_tracker.EnterLayer(it, prevent_occlusion);
[email protected]94f206c12012-08-25 00:09:14599
[email protected]c1bb5af2013-03-13 19:06:27600 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]b09c1942013-05-10 00:06:37601 if (output_surface_->ForcedDrawToSoftwareDevice())
602 append_quads_data.allow_tile_draw_quads = false;
[email protected]89228202012-08-29 03:20:30603
[email protected]18a70192013-04-26 16:18:25604 if (it.represents_target_render_surface()) {
605 if (it->HasRequestCopyCallback()) {
606 have_copy_request = true;
607 it->TakeRequestCopyCallbacks(&target_render_pass->copy_callbacks);
608 }
609 } else if (it.represents_contributing_render_surface()) {
[email protected]c1bb5af2013-03-13 19:06:27610 RenderPass::Id contributing_render_pass_id =
611 it->render_surface()->RenderPassId();
612 RenderPass* contributing_render_pass =
613 frame->render_passes_by_id[contributing_render_pass_id];
614 AppendQuadsForRenderSurfaceLayer(target_render_pass,
615 *it,
616 contributing_render_pass,
617 occlusion_tracker,
618 &append_quads_data);
[email protected]e1e768f2013-03-26 08:48:09619 } else if (it.represents_itself() &&
620 !it->visible_content_rect().IsEmpty()) {
[email protected]c1bb5af2013-03-13 19:06:27621 bool has_occlusion_from_outside_target_surface;
622 bool impl_draw_transform_is_unknown = false;
623 if (occlusion_tracker.Occluded(
624 it->render_target(),
625 it->visible_content_rect(),
626 it->draw_transform(),
627 impl_draw_transform_is_unknown,
628 it->is_clipped(),
629 it->clip_rect(),
630 &has_occlusion_from_outside_target_surface)) {
[email protected]e1e768f2013-03-26 08:48:09631 append_quads_data.had_occlusion_from_outside_target_surface |=
[email protected]c1bb5af2013-03-13 19:06:27632 has_occlusion_from_outside_target_surface;
633 } else {
634 DCHECK_EQ(active_tree_, it->layer_tree_impl());
635 it->WillDraw(resource_provider_.get());
636 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57637
[email protected]c1bb5af2013-03-13 19:06:27638 if (it->HasContributingDelegatedRenderPasses()) {
639 RenderPass::Id contributing_render_pass_id =
640 it->FirstContributingRenderPassId();
641 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
642 frame->render_passes_by_id.end()) {
643 RenderPass* render_pass =
644 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14645
[email protected]c1bb5af2013-03-13 19:06:27646 AppendQuadsData append_quads_data(render_pass->id);
647 AppendQuadsForLayer(render_pass,
648 *it,
649 occlusion_tracker,
650 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57651
[email protected]c1bb5af2013-03-13 19:06:27652 contributing_render_pass_id =
653 it->NextContributingRenderPassId(contributing_render_pass_id);
654 }
[email protected]94f206c12012-08-25 00:09:14655 }
656
[email protected]c1bb5af2013-03-13 19:06:27657 AppendQuadsForLayer(target_render_pass,
658 *it,
659 occlusion_tracker,
660 &append_quads_data);
661 }
[email protected]89228202012-08-29 03:20:30662
[email protected]372bad5f2013-03-21 16:38:43663 ++layers_drawn;
[email protected]94f206c12012-08-25 00:09:14664 }
665
[email protected]e1e768f2013-03-26 08:48:09666 if (append_quads_data.had_occlusion_from_outside_target_surface)
[email protected]c1bb5af2013-03-13 19:06:27667 target_render_pass->has_occlusion_from_outside_target_surface = true;
668
[email protected]e1e768f2013-03-26 08:48:09669 if (append_quads_data.num_missing_tiles) {
[email protected]372bad5f2013-03-21 16:38:43670 rendering_stats_instrumentation_->AddMissingTiles(
[email protected]e1e768f2013-03-26 08:48:09671 append_quads_data.num_missing_tiles);
[email protected]c1bb5af2013-03-13 19:06:27672 bool layer_has_animating_transform =
673 it->screen_space_transform_is_animating() ||
674 it->draw_transform_is_animating();
675 if (layer_has_animating_transform)
676 draw_frame = false;
677 }
678
[email protected]e1e768f2013-03-26 08:48:09679 if (append_quads_data.had_incomplete_tile)
[email protected]c1bb5af2013-03-13 19:06:27680 frame->contains_incomplete_tile = true;
681
682 occlusion_tracker.LeaveLayer(it);
683 }
684
[email protected]18a70192013-04-26 16:18:25685 if (have_copy_request)
686 draw_frame = true;
687
[email protected]372bad5f2013-03-21 16:38:43688 rendering_stats_instrumentation_->AddLayersDrawn(layers_drawn);
689
[email protected]1d993172012-10-18 18:15:04690#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27691 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
692 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
693 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
694 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
695 != frame->render_passes_by_id.end());
696 }
[email protected]94f206c12012-08-25 00:09:14697#endif
[email protected]c1bb5af2013-03-13 19:06:27698 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14699
[email protected]c1bb5af2013-03-13 19:06:27700 if (!active_tree_->has_transparent_background()) {
701 frame->render_passes.back()->has_transparent_background = false;
702 AppendQuadsToFillScreen(frame->render_passes.back(),
703 active_tree_->root_layer(),
704 active_tree_->background_color(),
705 occlusion_tracker);
706 }
[email protected]94f206c12012-08-25 00:09:14707
[email protected]c1bb5af2013-03-13 19:06:27708 if (draw_frame)
709 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]18a70192013-04-26 16:18:25710 else
711 DCHECK(!have_copy_request);
[email protected]94f206c12012-08-25 00:09:14712
[email protected]c1bb5af2013-03-13 19:06:27713 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
[email protected]b09c1942013-05-10 00:06:37714 if (!output_surface_->ForcedDrawToSoftwareDevice())
715 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
[email protected]bf691c22013-03-26 21:15:06716 RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()),
717 frame);
[email protected]94f206c12012-08-25 00:09:14718
[email protected]e0341352013-04-06 05:01:20719 // If we're making a frame to draw, it better have at least one render pass.
720 DCHECK(!frame->render_passes.empty());
[email protected]c1bb5af2013-03-13 19:06:27721 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14722}
723
[email protected]3d9f7432013-04-06 00:35:18724void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
725 bool should_background_tick) {
726 bool enabled = should_background_tick &&
727 !animation_registrar_->active_animation_controllers().empty();
728
[email protected]c1bb5af2013-03-13 19:06:27729 // Lazily create the time_source adapter so that we can vary the interval for
730 // testing.
731 if (!time_source_client_adapter_) {
732 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
733 this,
[email protected]6d0e69d2013-03-20 14:53:26734 DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(),
[email protected]c1bb5af2013-03-13 19:06:27735 proxy_->CurrentThread()));
736 }
[email protected]94f206c12012-08-25 00:09:14737
[email protected]c1bb5af2013-03-13 19:06:27738 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14739}
740
[email protected]b9d4a362013-04-23 05:36:27741void LayerTreeHostImpl::SetViewportDamage(gfx::Rect damage_rect) {
[email protected]878705be2013-04-15 22:44:02742 viewport_damage_rect_.Union(damage_rect);
743}
744
[email protected]c1bb5af2013-03-13 19:06:27745static inline RenderPass* FindRenderPassById(
746 RenderPass::Id render_pass_id,
747 const LayerTreeHostImpl::FrameData& frame) {
748 RenderPassIdHashMap::const_iterator it =
749 frame.render_passes_by_id.find(render_pass_id);
750 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14751}
752
[email protected]c1bb5af2013-03-13 19:06:27753static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
754 LayerTreeHostImpl::FrameData* frame) {
755 RenderPass* remove_render_pass =
756 FindRenderPassById(remove_render_pass_id, *frame);
757 // The pass was already removed by another quad - probably the original, and
758 // we are the replica.
759 if (!remove_render_pass)
760 return;
761 RenderPassList& render_passes = frame->render_passes;
762 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
763 render_passes.end(),
764 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14765
[email protected]c1bb5af2013-03-13 19:06:27766 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14767
[email protected]c1bb5af2013-03-13 19:06:27768 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
769 frame->render_passes.erase(to_remove);
770 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14771
[email protected]c1bb5af2013-03-13 19:06:27772 // Now follow up for all RenderPass quads and remove their RenderPasses
773 // recursively.
774 const QuadList& quad_list = removed_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29775 QuadList::ConstBackToFrontIterator quad_list_iterator =
776 quad_list.BackToFrontBegin();
777 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27778 ++quad_list_iterator) {
779 DrawQuad* current_quad = (*quad_list_iterator);
780 if (current_quad->material != DrawQuad::RENDER_PASS)
781 continue;
[email protected]94f206c12012-08-25 00:09:14782
[email protected]c1bb5af2013-03-13 19:06:27783 RenderPass::Id next_remove_render_pass_id =
784 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
785 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
786 }
[email protected]94f206c12012-08-25 00:09:14787}
788
[email protected]c1bb5af2013-03-13 19:06:27789bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
790 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
791 const FrameData& frame) const {
792 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
793 bool quad_has_cached_resource =
[email protected]bf691c22013-03-26 21:15:06794 renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id);
[email protected]c1bb5af2013-03-13 19:06:27795 if (quad_has_damage) {
796 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
797 return false;
798 } else if (!quad_has_cached_resource) {
799 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
800 return false;
801 }
802 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
803 return true;
[email protected]94f206c12012-08-25 00:09:14804}
805
[email protected]c1bb5af2013-03-13 19:06:27806bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
807 const RenderPassDrawQuad& quad, const FrameData& frame) const {
808 const RenderPass* render_pass =
809 FindRenderPassById(quad.render_pass_id, frame);
810 if (!render_pass)
811 return false;
[email protected]94f206c12012-08-25 00:09:14812
[email protected]c1bb5af2013-03-13 19:06:27813 // If any quad or RenderPass draws into this RenderPass, then keep it.
814 const QuadList& quad_list = render_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29815 for (QuadList::ConstBackToFrontIterator quad_list_iterator =
816 quad_list.BackToFrontBegin();
817 quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27818 ++quad_list_iterator) {
819 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14820
[email protected]c1bb5af2013-03-13 19:06:27821 if (current_quad->material != DrawQuad::RENDER_PASS)
822 return false;
[email protected]94f206c12012-08-25 00:09:14823
[email protected]c1bb5af2013-03-13 19:06:27824 const RenderPass* contributing_pass = FindRenderPassById(
825 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
826 if (contributing_pass)
827 return false;
828 }
829 return true;
[email protected]94f206c12012-08-25 00:09:14830}
831
832// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27833template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
834 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
835 CullRenderPassesWithCachedTextures culler, FrameData* frame);
836template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
837 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
838 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14839
840// static
[email protected]c1bb5af2013-03-13 19:06:27841template <typename RenderPassCuller>
842void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
843 FrameData* frame) {
844 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
845 it != culler.RenderPassListEnd(frame->render_passes);
846 it = culler.RenderPassListNext(it)) {
847 const RenderPass* current_pass = frame->render_passes[it];
848 const QuadList& quad_list = current_pass->quad_list;
[email protected]ed511b8d2013-03-25 03:29:29849 QuadList::ConstBackToFrontIterator quad_list_iterator =
850 quad_list.BackToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14851
[email protected]ed511b8d2013-03-25 03:29:29852 for (; quad_list_iterator != quad_list.BackToFrontEnd();
[email protected]c1bb5af2013-03-13 19:06:27853 ++quad_list_iterator) {
854 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14855
[email protected]c1bb5af2013-03-13 19:06:27856 if (current_quad->material != DrawQuad::RENDER_PASS)
857 continue;
[email protected]94f206c12012-08-25 00:09:14858
[email protected]c1bb5af2013-03-13 19:06:27859 const RenderPassDrawQuad* render_pass_quad =
860 RenderPassDrawQuad::MaterialCast(current_quad);
861 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
862 continue;
[email protected]94f206c12012-08-25 00:09:14863
[email protected]c1bb5af2013-03-13 19:06:27864 // We are changing the vector in the middle of iteration. Because we
865 // delete render passes that draw into the current pass, we are
866 // guaranteed that any data from the iterator to the end will not
867 // change. So, capture the iterator position from the end of the
868 // list, and restore it after the change.
869 size_t position_from_end = frame->render_passes.size() - it;
870 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
871 it = frame->render_passes.size() - position_from_end;
872 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14873 }
[email protected]c1bb5af2013-03-13 19:06:27874 }
[email protected]94f206c12012-08-25 00:09:14875}
876
[email protected]e0341352013-04-06 05:01:20877bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
878 gfx::Rect device_viewport_damage_rect) {
[email protected]c1bb5af2013-03-13 19:06:27879 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14880
[email protected]7d19dc342013-05-02 22:02:04881 active_tree_->UpdateDrawProperties();
[email protected]2e7ca422012-12-20 02:57:27882
[email protected]c1bb5af2013-03-13 19:06:27883 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
884 frame->render_passes.clear();
885 frame->render_passes_by_id.clear();
886 frame->will_draw_layers.clear();
[email protected]e0341352013-04-06 05:01:20887 frame->contains_incomplete_tile = false;
888 frame->has_no_damage = false;
889
890 if (active_tree_->root_layer()) {
[email protected]878705be2013-04-15 22:44:02891 device_viewport_damage_rect.Union(viewport_damage_rect_);
892 viewport_damage_rect_ = gfx::Rect();
[email protected]e0341352013-04-06 05:01:20893
894 active_tree_->root_layer()->render_surface()->damage_tracker()->
895 AddDamageNextUpdate(device_viewport_damage_rect);
896 }
[email protected]94f206c12012-08-25 00:09:14897
[email protected]c1bb5af2013-03-13 19:06:27898 if (!CalculateRenderPasses(frame))
899 return false;
[email protected]94f206c12012-08-25 00:09:14900
[email protected]e4c3c87a2013-04-22 02:28:40901 frame->latency_info = active_tree_->GetLatencyInfo();
902
[email protected]c1bb5af2013-03-13 19:06:27903 // If we return true, then we expect DrawLayers() to be called before this
904 // function is called again.
905 return true;
[email protected]94f206c12012-08-25 00:09:14906}
907
[email protected]c1bb5af2013-03-13 19:06:27908void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
909 const ManagedMemoryPolicy& policy) {
910 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
[email protected]46b8acc2013-03-19 22:38:35911 visible_ ? policy.bytes_limit_when_visible
912 : policy.bytes_limit_when_not_visible,
913 ManagedMemoryPolicy::PriorityCutoffToValue(
914 visible_ ? policy.priority_cutoff_when_visible
915 : policy.priority_cutoff_when_not_visible));
[email protected]c1bb5af2013-03-13 19:06:27916 if (evicted_resources) {
917 active_tree_->SetContentsTexturesPurged();
918 if (pending_tree_)
919 pending_tree_->SetContentsTexturesPurged();
920 client_->SetNeedsCommitOnImplThread();
921 client_->OnCanDrawStateChanged(CanDraw());
922 client_->RenewTreePriority();
923 }
924 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43925
[email protected]8be1a9bf2013-05-01 03:45:19926 UpdateTileManagerMemoryPolicy(policy);
927}
928
929void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
930 const ManagedMemoryPolicy& policy) {
931 if (!tile_manager_)
932 return;
933
934 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
935 new_state.memory_limit_in_bytes = visible_ ?
936 policy.bytes_limit_when_visible :
937 policy.bytes_limit_when_not_visible;
938 // TODO(reveman): We should avoid keeping around unused resources if
939 // possible. crbug.com/224475
940 new_state.unused_memory_limit_in_bytes = static_cast<size_t>(
941 (static_cast<int64>(new_state.memory_limit_in_bytes) *
942 settings_.max_unused_resource_memory_percentage) / 100);
943 new_state.memory_limit_policy =
944 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
945 visible_ ?
946 policy.priority_cutoff_when_visible :
947 policy.priority_cutoff_when_not_visible);
948 tile_manager_->SetGlobalState(new_state);
[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]f6742f52013-05-08 23:52:221107 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
1108 "cc.debug", "cc::LayerTreeHostImpl", this,
1109 TracedValue::FromValue(AsValue().release()));
[email protected]c1bb5af2013-03-13 19:06:271110 }
[email protected]131a0c22013-02-12 18:31:081111
[email protected]c1bb5af2013-03-13 19:06:271112 // Because the contents of the HUD depend on everything else in the frame, the
1113 // contents of its texture are updated as the last thing before the frame is
1114 // drawn.
1115 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:541116 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:141117
[email protected]b09c1942013-05-10 00:06:371118 if (output_surface_->ForcedDrawToSoftwareDevice()) {
1119 scoped_ptr<SoftwareRenderer> temp_software_renderer =
1120 SoftwareRenderer::Create(this, output_surface_.get(), NULL);
1121 temp_software_renderer->DrawFrame(&frame->render_passes);
1122 } else {
1123 renderer_->DrawFrame(&frame->render_passes);
1124 }
[email protected]c1bb5af2013-03-13 19:06:271125 // The render passes should be consumed by the renderer.
1126 DCHECK(frame->render_passes.empty());
1127 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:141128
[email protected]c1bb5af2013-03-13 19:06:271129 // The next frame should start by assuming nothing has changed, and changes
1130 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:541131 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:271132 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
1133 DidDrawDamagedArea();
1134 }
1135 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:141136}
1137
[email protected]c1bb5af2013-03-13 19:06:271138void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
1139 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
1140 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:521141
[email protected]c1bb5af2013-03-13 19:06:271142 // Once all layers have been drawn, pending texture uploads should no
1143 // longer block future uploads.
1144 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:141145}
1146
[email protected]c1bb5af2013-03-13 19:06:271147void LayerTreeHostImpl::FinishAllRendering() {
1148 if (renderer_)
1149 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:141150}
1151
[email protected]c1bb5af2013-03-13 19:06:271152bool LayerTreeHostImpl::IsContextLost() {
1153 DCHECK(proxy_->IsImplThread());
1154 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141155}
1156
[email protected]c1bb5af2013-03-13 19:06:271157const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1158 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141159}
1160
[email protected]e0341352013-04-06 05:01:201161bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
1162 if (frame.has_no_damage)
1163 return false;
[email protected]c5c506382013-04-30 04:42:161164 renderer_->SwapBuffers(frame.latency_info);
1165 active_tree_->ClearLatencyInfo();
1166 return true;
[email protected]94f206c12012-08-25 00:09:141167}
1168
[email protected]7ed47512013-03-26 22:28:451169void LayerTreeHostImpl::EnableVSyncNotification(bool enable) {
1170 if (output_surface_)
1171 output_surface_->EnableVSyncNotification(enable);
1172}
1173
[email protected]c1bb5af2013-03-13 19:06:271174gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1175 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101176}
1177
[email protected]ffb2720f2013-03-15 19:18:371178gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1179 gfx::SizeF dip_size =
1180 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1181
1182 // The clip layer should be used if non-overlay scrollbars may exist since
1183 // it adjusts for them.
1184 LayerImpl* clip_layer = active_tree_->RootClipLayer();
[email protected]8e0176d2013-03-21 03:14:521185 if (!Settings().solid_color_scrollbars && clip_layer &&
[email protected]ffb2720f2013-03-15 19:18:371186 clip_layer->masks_to_bounds())
1187 dip_size = clip_layer->bounds();
1188
[email protected]ed511b8d2013-03-25 03:29:291189 float top_offset =
[email protected]ffb2720f2013-03-15 19:18:371190 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
[email protected]d9083762013-03-24 01:36:401191 return gfx::SizeF(dip_size.width(),
[email protected]ed511b8d2013-03-25 03:29:291192 dip_size.height() - top_offset - overdraw_bottom_height_);
[email protected]ffb2720f2013-03-15 19:18:371193}
1194
[email protected]c1bb5af2013-03-13 19:06:271195const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1196 return settings();
[email protected]493067512012-09-19 23:34:101197}
1198
[email protected]c1bb5af2013-03-13 19:06:271199void LayerTreeHostImpl::DidLoseOutputSurface() {
[email protected]bb1e2822013-04-17 22:06:011200 // TODO(jamesr): The renderer_ check is needed to make some of the
1201 // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or
1202 // important) in production. We should adjust the test to not need this.
1203 if (renderer_)
1204 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141205}
1206
[email protected]c1bb5af2013-03-13 19:06:271207void LayerTreeHostImpl::OnSwapBuffersComplete() {
1208 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141209}
1210
[email protected]c1bb5af2013-03-13 19:06:271211void LayerTreeHostImpl::Readback(void* pixels,
1212 gfx::Rect rect_in_device_viewport) {
1213 DCHECK(renderer_);
1214 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141215}
1216
[email protected]59adb112013-04-09 04:48:441217bool LayerTreeHostImpl::HaveRootScrollLayer() const {
[email protected]3209161d2013-03-29 19:17:341218 return !!RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011219}
1220
[email protected]c1bb5af2013-03-13 19:06:271221LayerImpl* LayerTreeHostImpl::RootLayer() const {
1222 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081223}
1224
[email protected]c1bb5af2013-03-13 19:06:271225LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1226 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081227}
1228
[email protected]c1bb5af2013-03-13 19:06:271229LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1230 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081231}
1232
[email protected]94f206c12012-08-25 00:09:141233// Content layers can be either directly scrollable or contained in an outer
1234// scrolling layer which applies the scroll transform. Given a content layer,
1235// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271236static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1237 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141238 return 0;
[email protected]c1bb5af2013-03-13 19:06:271239
1240 if (layer_impl->scrollable())
1241 return layer_impl;
1242
1243 if (layer_impl->DrawsContent() &&
1244 layer_impl->parent() &&
1245 layer_impl->parent()->scrollable())
1246 return layer_impl->parent();
1247
1248 return 0;
[email protected]94f206c12012-08-25 00:09:141249}
1250
[email protected]c1bb5af2013-03-13 19:06:271251void LayerTreeHostImpl::CreatePendingTree() {
1252 CHECK(!pending_tree_);
1253 if (recycle_tree_)
1254 recycle_tree_.swap(pending_tree_);
1255 else
1256 pending_tree_ = LayerTreeImpl::create(this);
1257 client_->OnCanDrawStateChanged(CanDraw());
1258 client_->OnHasPendingTreeStateChanged(pending_tree_);
1259 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1260 TRACE_EVENT_ASYNC_STEP0("cc",
1261 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271262}
1263
[email protected]c1bb5af2013-03-13 19:06:271264void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1265 DCHECK(!client_->IsInsideDraw()) <<
1266 "Checking for completed uploads within a draw may trigger "
1267 "spurious redraws.";
1268 if (tile_manager_)
1269 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481270}
1271
[email protected]c1bb5af2013-03-13 19:06:271272bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1273 if (!pending_tree_)
1274 return false;
[email protected]2e7ca422012-12-20 02:57:271275
[email protected]c1bb5af2013-03-13 19:06:271276 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091277
[email protected]7d19dc342013-05-02 22:02:041278 pending_tree_->UpdateDrawProperties();
[email protected]615c78a2013-01-24 23:44:161279
[email protected]f6742f52013-05-08 23:52:221280 TRACE_EVENT_ASYNC_STEP1(
1281 "cc",
1282 "PendingTree", pending_tree_.get(), "activate",
1283 "state", TracedValue::FromValue(ActivationStateAsValue().release()));
[email protected]4f0a5002013-01-28 13:02:271284
[email protected]8ca1e6c2013-04-02 03:49:261285 // Activate once all visible resources in pending tree are ready.
1286 if (!pending_tree_->AreVisibleResourcesReady())
1287 return false;
[email protected]2e7ca422012-12-20 02:57:271288
[email protected]c1bb5af2013-03-13 19:06:271289 ActivatePendingTree();
1290 return true;
[email protected]2e7ca422012-12-20 02:57:271291}
1292
[email protected]c1bb5af2013-03-13 19:06:271293void LayerTreeHostImpl::ActivatePendingTree() {
1294 CHECK(pending_tree_);
1295 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351296
[email protected]1960a712013-04-30 17:06:471297 active_tree_->SetRootLayerScrollOffsetDelegate(NULL);
[email protected]c1bb5af2013-03-13 19:06:271298 active_tree_->PushPersistedState(pending_tree_.get());
1299 if (pending_tree_->needs_full_tree_sync()) {
1300 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331301 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271302 active_tree_->DetachLayerTree(),
1303 active_tree_.get()));
1304 }
[email protected]b5651c22013-03-14 15:06:331305 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271306 active_tree_->root_layer());
1307 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511308
[email protected]c1bb5af2013-03-13 19:06:271309 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511310
[email protected]c1bb5af2013-03-13 19:06:271311 // Now that we've synced everything from the pending tree to the active
1312 // tree, rename the pending tree the recycle tree so we can reuse it on the
1313 // next sync.
1314 pending_tree_.swap(recycle_tree_);
1315 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511316
[email protected]1960a712013-04-30 17:06:471317 active_tree_->SetRootLayerScrollOffsetDelegate(
1318 root_layer_scroll_offset_delegate_);
[email protected]c1bb5af2013-03-13 19:06:271319 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221320
[email protected]c1bb5af2013-03-13 19:06:271321 // Reduce wasted memory now that unlinked resources are guaranteed not
1322 // to be used.
1323 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411324
[email protected]c1bb5af2013-03-13 19:06:271325 client_->OnCanDrawStateChanged(CanDraw());
1326 client_->OnHasPendingTreeStateChanged(pending_tree_);
1327 client_->SetNeedsRedrawOnImplThread();
1328 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241329
[email protected]a848c102013-03-26 08:59:091330 if (debug_state_.continuous_painting) {
1331 const RenderingStats& stats =
[email protected]372bad5f2013-03-21 16:38:431332 rendering_stats_instrumentation_->GetRenderingStats();
[email protected]a848c102013-03-26 08:59:091333 paint_time_counter_->SavePaintTime(
[email protected]41abb6d92013-04-26 16:38:501334 stats.total_paint_time + stats.total_record_time +
[email protected]a848c102013-03-26 08:59:091335 stats.total_rasterize_time_for_now_bins_on_pending_tree);
[email protected]c1bb5af2013-03-13 19:06:271336 }
[email protected]2e7ca422012-12-20 02:57:271337}
1338
[email protected]c1bb5af2013-03-13 19:06:271339void LayerTreeHostImpl::SetVisible(bool visible) {
1340 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141341
[email protected]c1bb5af2013-03-13 19:06:271342 if (visible_ == visible)
1343 return;
1344 visible_ = visible;
1345 DidVisibilityChange(this, visible_);
1346 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141347
[email protected]c1bb5af2013-03-13 19:06:271348 if (!renderer_)
1349 return;
[email protected]94f206c12012-08-25 00:09:141350
[email protected]c1bb5af2013-03-13 19:06:271351 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141352}
1353
[email protected]c1bb5af2013-03-13 19:06:271354bool LayerTreeHostImpl::InitializeRenderer(
1355 scoped_ptr<OutputSurface> output_surface) {
1356 // Since we will create a new resource provider, we cannot continue to use
1357 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1358 // before we destroy the old resource provider.
1359 if (active_tree_->root_layer())
1360 ClearRenderSurfaces();
1361 if (active_tree_->root_layer())
1362 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1363 if (pending_tree_ && pending_tree_->root_layer())
1364 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1365 if (recycle_tree_ && recycle_tree_->root_layer())
1366 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]7ba3ca72013-04-11 06:37:251367 if (resource_provider_)
1368 resource_provider_->DidLoseOutputSurface();
[email protected]45c4b1e2013-01-16 02:19:401369
[email protected]c1bb5af2013-03-13 19:06:271370 // Note: order is important here.
1371 renderer_.reset();
1372 tile_manager_.reset();
1373 resource_provider_.reset();
1374 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141375
[email protected]c1bb5af2013-03-13 19:06:271376 if (!output_surface->BindToClient(this))
1377 return false;
[email protected]be3181652012-09-25 13:02:131378
[email protected]075d8aa2013-04-01 23:03:111379 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1380 output_surface.get(), settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271381 if (!resource_provider)
1382 return false;
[email protected]be3181652012-09-25 13:02:131383
[email protected]8e0176d2013-03-21 03:14:521384 if (settings_.impl_side_painting) {
[email protected]c1bb5af2013-03-13 19:06:271385 tile_manager_.reset(new TileManager(this,
1386 resource_provider.get(),
[email protected]8e0176d2013-03-21 03:14:521387 settings_.num_raster_threads,
[email protected]8e0176d2013-03-21 03:14:521388 settings_.use_color_estimator,
[email protected]372bad5f2013-03-21 16:38:431389 settings_.prediction_benchmarking,
1390 rendering_stats_instrumentation_));
[email protected]8be1a9bf2013-05-01 03:45:191391 UpdateTileManagerMemoryPolicy(managed_memory_policy_);
[email protected]c1bb5af2013-03-13 19:06:271392 }
[email protected]8947cbe2012-11-28 05:27:431393
[email protected]c1bb5af2013-03-13 19:06:271394 if (output_surface->capabilities().has_parent_compositor) {
1395 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1396 resource_provider.get());
1397 } else if (output_surface->context3d()) {
1398 renderer_ = GLRenderer::Create(this,
1399 output_surface.get(),
[email protected]075d8aa2013-04-01 23:03:111400 resource_provider.get(),
1401 settings_.highp_threshold_min);
[email protected]c1bb5af2013-03-13 19:06:271402 } else if (output_surface->software_device()) {
1403 renderer_ = SoftwareRenderer::Create(this,
1404 output_surface.get(),
1405 resource_provider.get());
1406 }
1407 if (!renderer_)
1408 return false;
[email protected]be3181652012-09-25 13:02:131409
[email protected]c1bb5af2013-03-13 19:06:271410 resource_provider_ = resource_provider.Pass();
1411 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141412
[email protected]c1bb5af2013-03-13 19:06:271413 if (!visible_)
1414 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141415
[email protected]c1bb5af2013-03-13 19:06:271416 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211417
[email protected]c1bb5af2013-03-13 19:06:271418 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1419 // to be initialized to get max texture size.
1420 active_tree_->set_needs_update_draw_properties();
1421 if (pending_tree_)
1422 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161423
[email protected]c1bb5af2013-03-13 19:06:271424 return true;
[email protected]94f206c12012-08-25 00:09:141425}
1426
[email protected]18ce59702013-04-09 04:58:401427void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) {
1428 if (device_viewport_size == device_viewport_size_)
[email protected]c1bb5af2013-03-13 19:06:271429 return;
[email protected]94f206c12012-08-25 00:09:141430
[email protected]c1bb5af2013-03-13 19:06:271431 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1432 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271433
[email protected]c1bb5af2013-03-13 19:06:271434 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141435
[email protected]c1bb5af2013-03-13 19:06:271436 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141437
[email protected]c1bb5af2013-03-13 19:06:271438 if (renderer_)
1439 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211440
[email protected]c1bb5af2013-03-13 19:06:271441 client_->OnCanDrawStateChanged(CanDraw());
[email protected]59adb112013-04-09 04:48:441442 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141443}
1444
[email protected]d9083762013-03-24 01:36:401445void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) {
1446 if (overdraw_bottom_height == overdraw_bottom_height_)
1447 return;
1448 overdraw_bottom_height_ = overdraw_bottom_height;
1449
1450 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441451 SetFullRootLayerDamage();
[email protected]d9083762013-03-24 01:36:401452}
1453
[email protected]c1bb5af2013-03-13 19:06:271454void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1455 if (device_scale_factor == device_scale_factor_)
1456 return;
1457 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271458
[email protected]c1bb5af2013-03-13 19:06:271459 UpdateMaxScrollOffset();
[email protected]59adb112013-04-09 04:48:441460 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141461}
1462
[email protected]c1bb5af2013-03-13 19:06:271463void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1464 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141465}
1466
[email protected]59adb112013-04-09 04:48:441467void LayerTreeHostImpl::DidChangeTopControlsPosition() {
[email protected]c1bb5af2013-03-13 19:06:271468 client_->SetNeedsRedrawOnImplThread();
[email protected]59adb112013-04-09 04:48:441469 active_tree_->set_needs_update_draw_properties();
1470 SetFullRootLayerDamage();
[email protected]94f206c12012-08-25 00:09:141471}
1472
[email protected]c1bb5af2013-03-13 19:06:271473bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
[email protected]7d19dc342013-05-02 22:02:041474 active_tree_->UpdateDrawProperties();
[email protected]3209161d2013-03-29 19:17:341475 return !active_tree_->RenderSurfaceLayerList().empty();
[email protected]94f206c12012-08-25 00:09:141476}
1477
[email protected]5ff3c9782013-04-29 17:35:121478InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1479 gfx::Point viewport_point, InputHandler::ScrollInputType type) {
[email protected]ed511b8d2013-03-25 03:29:291480 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
[email protected]94f206c12012-08-25 00:09:141481
[email protected]c1bb5af2013-03-13 19:06:271482 if (top_controls_manager_)
1483 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381484
[email protected]c1bb5af2013-03-13 19:06:271485 DCHECK(!CurrentlyScrollingLayer());
1486 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141487
[email protected]c1bb5af2013-03-13 19:06:271488 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141489 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141490
[email protected]c1bb5af2013-03-13 19:06:271491 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1492 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141493
[email protected]c1bb5af2013-03-13 19:06:271494 // First find out which layer was hit from the saved list of visible layers
1495 // in the most recent frame.
[email protected]6ba914122013-03-22 16:26:391496 LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
[email protected]c1bb5af2013-03-13 19:06:271497 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521498
[email protected]c1bb5af2013-03-13 19:06:271499 // Walk up the hierarchy and look for a scrollable layer.
1500 LayerImpl* potentially_scrolling_layer_impl = 0;
1501 for (; layer_impl; layer_impl = layer_impl->parent()) {
1502 // The content layer can also block attempts to scroll outside the main
1503 // thread.
1504 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1505 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431506 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271507 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421508 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271509 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141510 }
1511
[email protected]c1bb5af2013-03-13 19:06:271512 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1513 if (!scroll_layer_impl)
1514 continue;
[email protected]94f206c12012-08-25 00:09:141515
[email protected]c1bb5af2013-03-13 19:06:271516 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141517
[email protected]c1bb5af2013-03-13 19:06:271518 // If any layer wants to divert the scroll event to the main thread, abort.
1519 if (status == ScrollOnMainThread) {
[email protected]372bad5f2013-03-21 16:38:431520 rendering_stats_instrumentation_->IncrementMainThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271521 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421522 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271523 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141524 }
1525
[email protected]c1bb5af2013-03-13 19:06:271526 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1527 potentially_scrolling_layer_impl = scroll_layer_impl;
1528 }
1529
1530 // When hiding top controls is enabled and the controls are hidden or
1531 // overlaying the content, force scrolls to be enabled on the root layer to
1532 // allow bringing the top controls back into view.
1533 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1534 top_controls_manager_->content_top_offset() !=
[email protected]8e0176d2013-03-21 03:14:521535 settings_.top_controls_height) {
[email protected]c1bb5af2013-03-13 19:06:271536 potentially_scrolling_layer_impl = RootScrollLayer();
1537 }
1538
1539 if (potentially_scrolling_layer_impl) {
[email protected]0fc818e2013-03-18 06:45:201540 active_tree_->SetCurrentlyScrollingLayer(
[email protected]c1bb5af2013-03-13 19:06:271541 potentially_scrolling_layer_impl);
1542 should_bubble_scrolls_ = (type != NonBubblingGesture);
1543 wheel_scrolling_ = (type == Wheel);
[email protected]372bad5f2013-03-21 16:38:431544 rendering_stats_instrumentation_->IncrementImplThreadScrolls();
[email protected]c1bb5af2013-03-13 19:06:271545 client_->RenewTreePriority();
1546 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421547 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271548 return ScrollStarted;
1549 }
1550 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141551}
1552
[email protected]c1bb5af2013-03-13 19:06:271553gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1554 LayerImpl* layer_impl,
1555 float scale_from_viewport_to_screen_space,
1556 gfx::PointF viewport_point,
1557 gfx::Vector2dF viewport_delta) {
1558 // Layers with non-invertible screen space transforms should not have passed
1559 // the scroll hit test in the first place.
1560 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1561 gfx::Transform inverse_screen_space_transform(
1562 gfx::Transform::kSkipInitialization);
1563 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1564 &inverse_screen_space_transform);
[email protected]ca2902e92013-03-28 01:45:351565 // TODO(shawnsingh): With the advent of impl-side crolling for non-root
1566 // layers, we may need to explicitly handle uninvertible transforms here.
[email protected]c1bb5af2013-03-13 19:06:271567 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141568
[email protected]c1bb5af2013-03-13 19:06:271569 gfx::PointF screen_space_point =
1570 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141571
[email protected]c1bb5af2013-03-13 19:06:271572 gfx::Vector2dF screen_space_delta = viewport_delta;
1573 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1574
1575 // First project the scroll start and end points to local layer space to find
1576 // the scroll delta in layer coordinates.
1577 bool start_clipped, end_clipped;
1578 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1579 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211580 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271581 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211582 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271583 gfx::PointF local_end_point =
[email protected]fa816c62013-03-18 04:24:211584 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271585 screen_space_end_point,
[email protected]fa816c62013-03-18 04:24:211586 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271587
1588 // In general scroll point coordinates should not get clipped.
1589 DCHECK(!start_clipped);
1590 DCHECK(!end_clipped);
1591 if (start_clipped || end_clipped)
1592 return gfx::Vector2dF();
1593
1594 // local_start_point and local_end_point are in content space but we want to
1595 // move them to layer space for scrolling.
1596 float width_scale = 1.f / layer_impl->contents_scale_x();
1597 float height_scale = 1.f / layer_impl->contents_scale_y();
1598 local_start_point.Scale(width_scale, height_scale);
1599 local_end_point.Scale(width_scale, height_scale);
1600
1601 // Apply the scroll delta.
[email protected]1960a712013-04-30 17:06:471602 gfx::Vector2dF previous_delta = layer_impl->ScrollDelta();
[email protected]c1bb5af2013-03-13 19:06:271603 layer_impl->ScrollBy(local_end_point - local_start_point);
1604
1605 // Get the end point in the layer's content space so we can apply its
1606 // ScreenSpaceTransform.
1607 gfx::PointF actual_local_end_point = local_start_point +
[email protected]1960a712013-04-30 17:06:471608 layer_impl->ScrollDelta() -
[email protected]c1bb5af2013-03-13 19:06:271609 previous_delta;
1610 gfx::PointF actual_local_content_end_point =
1611 gfx::ScalePoint(actual_local_end_point,
1612 1.f / width_scale,
1613 1.f / height_scale);
1614
1615 // Calculate the applied scroll delta in viewport space coordinates.
1616 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211617 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271618 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211619 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271620 DCHECK(!end_clipped);
1621 if (end_clipped)
1622 return gfx::Vector2dF();
1623 gfx::PointF actual_viewport_end_point =
1624 gfx::ScalePoint(actual_screen_space_end_point,
1625 1.f / scale_from_viewport_to_screen_space);
1626 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141627}
1628
[email protected]c1bb5af2013-03-13 19:06:271629static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1630 gfx::Vector2dF local_delta) {
[email protected]1960a712013-04-30 17:06:471631 gfx::Vector2dF previous_delta(layer_impl->ScrollDelta());
[email protected]c1bb5af2013-03-13 19:06:271632 layer_impl->ScrollBy(local_delta);
[email protected]1960a712013-04-30 17:06:471633 return layer_impl->ScrollDelta() - previous_delta;
[email protected]c1bb5af2013-03-13 19:06:271634}
1635
1636bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1637 gfx::Vector2dF scroll_delta) {
1638 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1639 if (!CurrentlyScrollingLayer())
1640 return false;
1641
1642 gfx::Vector2dF pending_delta = scroll_delta;
1643 bool did_scroll = false;
[email protected]60b4d252013-03-23 18:49:421644 bool consume_by_top_controls = top_controls_manager_ &&
1645 (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0);
[email protected]a91e4f82013-03-15 06:58:061646
[email protected]c1bb5af2013-03-13 19:06:271647 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1648 layer_impl;
1649 layer_impl = layer_impl->parent()) {
1650 if (!layer_impl->scrollable())
1651 continue;
1652
[email protected]60b4d252013-03-23 18:49:421653 // Only allow bubble scrolling when the scroll is in the direction to make
1654 // the top controls visible.
1655 if (consume_by_top_controls && layer_impl == RootScrollLayer()) {
1656 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
1657 UpdateMaxScrollOffset();
1658 }
1659
[email protected]c1bb5af2013-03-13 19:06:271660 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271661 // Gesture events need to be transformed from viewport coordinates to local
1662 // layer coordinates so that the scrolling contents exactly follow the
1663 // user's finger. In contrast, wheel events represent a fixed amount of
1664 // scrolling so we can just apply them directly.
1665 if (!wheel_scrolling_) {
1666 float scale_from_viewport_to_screen_space = device_scale_factor_;
1667 applied_delta =
1668 ScrollLayerWithViewportSpaceDelta(layer_impl,
1669 scale_from_viewport_to_screen_space,
1670 viewport_point, pending_delta);
1671 } else {
1672 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141673 }
[email protected]94f206c12012-08-25 00:09:141674
[email protected]c1bb5af2013-03-13 19:06:271675 // If the layer wasn't able to move, try the next one in the hierarchy.
1676 float move_threshold_squared = 0.1f * 0.1f;
1677 if (applied_delta.LengthSquared() < move_threshold_squared) {
1678 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1679 continue;
1680 else
1681 break;
[email protected]94f206c12012-08-25 00:09:141682 }
[email protected]c1bb5af2013-03-13 19:06:271683 did_scroll = true;
1684 did_lock_scrolling_layer_ = true;
1685 if (!should_bubble_scrolls_) {
[email protected]0fc818e2013-03-18 06:45:201686 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
[email protected]c1bb5af2013-03-13 19:06:271687 break;
[email protected]94f206c12012-08-25 00:09:141688 }
[email protected]94f206c12012-08-25 00:09:141689
[email protected]c1bb5af2013-03-13 19:06:271690 // If the applied delta is within 45 degrees of the input delta, bail out to
1691 // make it easier to scroll just one layer in one direction without
1692 // affecting any of its parents.
1693 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211694 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271695 applied_delta, pending_delta) < angle_threshold) {
1696 pending_delta = gfx::Vector2d();
1697 break;
[email protected]4a23c374c2012-12-08 08:38:551698 }
[email protected]c1bb5af2013-03-13 19:06:271699
1700 // Allow further movement only on an axis perpendicular to the direction in
1701 // which the layer moved.
1702 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211703 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271704
1705 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1706 break;
1707 }
1708
[email protected]b7c4783f2013-03-15 23:11:421709 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271710 if (did_scroll) {
1711 client_->SetNeedsCommitOnImplThread();
1712 client_->SetNeedsRedrawOnImplThread();
1713 client_->RenewTreePriority();
1714 }
1715 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551716}
1717
[email protected]be782f52013-03-23 21:36:141718// This implements scrolling by page as described here:
1719// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645601(v=vs.85).aspx#_win32_The_Mouse_Wheel
1720// for events with WHEEL_PAGESCROLL set.
1721bool LayerTreeHostImpl::ScrollVerticallyByPage(
1722 gfx::Point viewport_point,
1723 WebKit::WebScrollbar::ScrollDirection direction) {
1724 DCHECK(wheel_scrolling_);
1725
1726 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1727 layer_impl;
1728 layer_impl = layer_impl->parent()) {
1729 if (!layer_impl->scrollable())
1730 continue;
1731
1732 if (!layer_impl->vertical_scrollbar_layer())
1733 continue;
1734
1735 float height = layer_impl->vertical_scrollbar_layer()->bounds().height();
1736
1737 // These magical values match WebKit and are designed to scroll nearly the
1738 // entire visible content height but leave a bit of overlap.
1739 float page = std::max(height * 0.875f, 1.f);
1740 if (direction == WebKit::WebScrollbar::ScrollBackward)
1741 page = -page;
1742
1743 gfx::Vector2dF delta = gfx::Vector2dF(0.f, page);
1744
1745 gfx::Vector2dF applied_delta = ScrollLayerWithLocalDelta(layer_impl, delta);
1746
1747 if (!applied_delta.IsZero()) {
1748 active_tree()->DidUpdateScroll();
1749 client_->SetNeedsCommitOnImplThread();
1750 client_->SetNeedsRedrawOnImplThread();
1751 client_->RenewTreePriority();
1752 return true;
1753 }
1754
1755 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
1756 }
1757
1758 return false;
1759}
1760
[email protected]1960a712013-04-30 17:06:471761void LayerTreeHostImpl::SetRootLayerScrollOffsetDelegate(
1762 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
1763 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
1764 active_tree_->SetRootLayerScrollOffsetDelegate(
1765 root_layer_scroll_offset_delegate_);
1766}
1767
1768void LayerTreeHostImpl::OnRootLayerDelegatedScrollOffsetChanged() {
1769 DCHECK(root_layer_scroll_offset_delegate_ != NULL);
1770 client_->SetNeedsCommitOnImplThread();
1771}
1772
[email protected]c1bb5af2013-03-13 19:06:271773void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1774 active_tree_->ClearCurrentlyScrollingLayer();
1775 did_lock_scrolling_layer_ = false;
[email protected]6e921bd2013-04-29 21:10:201776 current_fling_velocity_ = gfx::Vector2dF();
[email protected]94f206c12012-08-25 00:09:141777}
1778
[email protected]c1bb5af2013-03-13 19:06:271779void LayerTreeHostImpl::ScrollEnd() {
1780 if (top_controls_manager_)
1781 top_controls_manager_->ScrollEnd();
1782 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421783 active_tree()->DidEndScroll();
[email protected]fb7425a2013-04-22 16:28:551784 StartScrollbarAnimation(CurrentFrameTimeTicks());
[email protected]94f206c12012-08-25 00:09:141785}
1786
[email protected]5ff3c9782013-04-29 17:35:121787InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() {
[email protected]7c45d8152013-04-23 18:27:211788 if (active_tree_->CurrentlyScrollingLayer())
1789 return ScrollStarted;
1790
1791 return ScrollIgnored;
1792}
1793
[email protected]6e921bd2013-04-29 21:10:201794void LayerTreeHostImpl::NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) {
1795 current_fling_velocity_ = velocity;
1796}
1797
[email protected]c1bb5af2013-03-13 19:06:271798void LayerTreeHostImpl::PinchGestureBegin() {
1799 pinch_gesture_active_ = true;
1800 previous_pinch_anchor_ = gfx::Point();
1801 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141802}
1803
[email protected]c1bb5af2013-03-13 19:06:271804void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1805 gfx::Point anchor) {
1806 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281807
[email protected]c1bb5af2013-03-13 19:06:271808 if (!RootScrollLayer())
1809 return;
[email protected]d3afa112012-12-08 06:24:281810
[email protected]c1bb5af2013-03-13 19:06:271811 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1812 // position over the course of the magnify.
1813 float page_scale_delta = active_tree_->page_scale_delta();
1814 gfx::PointF previous_scale_anchor =
1815 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1816 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1817 page_scale_delta = active_tree_->page_scale_delta();
1818 gfx::PointF new_scale_anchor =
1819 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1820 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1821
1822 previous_pinch_anchor_ = anchor;
1823
1824 move.Scale(1 / active_tree_->page_scale_factor());
1825
1826 RootScrollLayer()->ScrollBy(move);
1827
[email protected]c1bb5af2013-03-13 19:06:271828 client_->SetNeedsCommitOnImplThread();
1829 client_->SetNeedsRedrawOnImplThread();
1830 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281831}
1832
[email protected]c1bb5af2013-03-13 19:06:271833void LayerTreeHostImpl::PinchGestureEnd() {
1834 pinch_gesture_active_ = false;
[email protected]c1bb5af2013-03-13 19:06:271835 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141836}
1837
[email protected]c1bb5af2013-03-13 19:06:271838static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1839 LayerImpl* layer_impl) {
1840 if (!layer_impl)
1841 return;
[email protected]94f206c12012-08-25 00:09:141842
[email protected]c1bb5af2013-03-13 19:06:271843 gfx::Vector2d scroll_delta =
[email protected]1960a712013-04-30 17:06:471844 gfx::ToFlooredVector2d(layer_impl->ScrollDelta());
[email protected]c1bb5af2013-03-13 19:06:271845 if (!scroll_delta.IsZero()) {
1846 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]6ba914122013-03-22 16:26:391847 scroll.layer_id = layer_impl->id();
1848 scroll.scroll_delta = scroll_delta;
[email protected]c1bb5af2013-03-13 19:06:271849 scroll_info->scrolls.push_back(scroll);
1850 layer_impl->SetSentScrollDelta(scroll_delta);
1851 }
[email protected]94f206c12012-08-25 00:09:141852
[email protected]c1bb5af2013-03-13 19:06:271853 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1854 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141855}
1856
[email protected]c1bb5af2013-03-13 19:06:271857scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1858 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301859
[email protected]c1bb5af2013-03-13 19:06:271860 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
[email protected]6ba914122013-03-22 16:26:391861 scroll_info->page_scale_delta = active_tree_->page_scale_delta();
1862 active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
[email protected]362f1e8b2013-01-21 16:54:301863
[email protected]c1bb5af2013-03-13 19:06:271864 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301865}
1866
[email protected]c1bb5af2013-03-13 19:06:271867void LayerTreeHostImpl::SetFullRootLayerDamage() {
[email protected]878705be2013-04-15 22:44:021868 SetViewportDamage(gfx::Rect(device_viewport_size_));
[email protected]829ad972013-01-28 23:36:101869}
1870
[email protected]c1bb5af2013-03-13 19:06:271871void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1872 if (!page_scale_animation_ || !RootScrollLayer())
1873 return;
1874
1875 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1876 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
[email protected]1960a712013-04-30 17:06:471877 RootScrollLayer()->ScrollDelta();
[email protected]c1bb5af2013-03-13 19:06:271878
1879 active_tree_->SetPageScaleDelta(
1880 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1881 active_tree_->page_scale_factor());
1882 gfx::Vector2dF next_scroll =
1883 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1884
1885 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1886 client_->SetNeedsRedrawOnImplThread();
1887
1888 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1889 page_scale_animation_.reset();
1890 client_->SetNeedsCommitOnImplThread();
1891 client_->RenewTreePriority();
1892 }
[email protected]829ad972013-01-28 23:36:101893}
1894
[email protected]ffb2720f2013-03-15 19:18:371895void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1896 if (!top_controls_manager_ || !RootScrollLayer())
1897 return;
1898 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1899 UpdateMaxScrollOffset();
[email protected]5ef82622013-05-01 16:26:171900 if (RootScrollLayer()->TotalScrollOffset().y() == 0.f)
1901 return;
[email protected]ffb2720f2013-03-15 19:18:371902 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1903 scroll, 1.f / active_tree_->total_page_scale_factor()));
1904}
1905
[email protected]c1bb5af2013-03-13 19:06:271906void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1907 base::Time wall_clock_time) {
[email protected]8e0176d2013-03-21 03:14:521908 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271909 animation_registrar_->active_animation_controllers().empty() ||
1910 !active_tree_->root_layer())
1911 return;
1912
1913 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1914
1915 last_animation_time_ = wall_clock_time;
1916 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1917
1918 AnimationRegistrar::AnimationControllerMap copy =
1919 animation_registrar_->active_animation_controllers();
1920 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1921 iter != copy.end();
1922 ++iter)
1923 (*iter).second->Animate(monotonic_seconds);
1924
1925 client_->SetNeedsRedrawOnImplThread();
[email protected]131a0c22013-02-12 18:31:081926}
1927
[email protected]3d9f7432013-04-06 00:35:181928void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
[email protected]8e0176d2013-03-21 03:14:521929 if (!settings_.accelerated_animation_enabled ||
[email protected]c1bb5af2013-03-13 19:06:271930 animation_registrar_->active_animation_controllers().empty() ||
1931 !active_tree_->root_layer())
1932 return;
1933
1934 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1935 scoped_ptr<AnimationEventsVector> events =
1936 make_scoped_ptr(new AnimationEventsVector);
1937 AnimationRegistrar::AnimationControllerMap copy =
1938 animation_registrar_->active_animation_controllers();
1939 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1940 iter != copy.end();
1941 ++iter)
[email protected]3d9f7432013-04-06 00:35:181942 (*iter).second->UpdateState(start_ready_animations, events.get());
[email protected]c1bb5af2013-03-13 19:06:271943
1944 if (!events->empty()) {
1945 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1946 last_animation_time_);
1947 }
[email protected]131a0c22013-02-12 18:31:081948}
1949
[email protected]c1bb5af2013-03-13 19:06:271950base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1951 return base::TimeDelta::FromSeconds(1);
1952}
1953
1954void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1955 DCHECK(current);
1956 current->DidLoseOutputSurface();
1957 if (current->mask_layer())
1958 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1959 if (current->replica_layer())
1960 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1961 for (size_t i = 0; i < current->children().size(); ++i)
1962 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1963}
1964
1965void LayerTreeHostImpl::ClearRenderSurfaces() {
1966 active_tree_->ClearRenderSurfaces();
1967 if (pending_tree_)
1968 pending_tree_->ClearRenderSurfaces();
1969}
1970
1971std::string LayerTreeHostImpl::LayerTreeAsText() const {
1972 std::string str;
1973 if (active_tree_->root_layer()) {
1974 str = active_tree_->root_layer()->LayerTreeAsText();
1975 str += "RenderSurfaces:\n";
1976 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1977 }
1978 return str;
1979}
1980
1981std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1982 std::string str;
1983 if (active_tree_->root_layer()) {
1984 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1985 base::JSONWriter::WriteWithOptions(
1986 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1987 }
1988 return str;
1989}
1990
1991void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1992 int indent,
1993 const LayerImpl* layer) const {
1994 if (layer->render_surface())
1995 layer->render_surface()->DumpSurface(str, indent);
1996
1997 for (size_t i = 0; i < layer->children().size(); ++i)
1998 DumpRenderSurfaces(str, indent, layer->children()[i]);
1999}
2000
2001int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:362002 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:272003}
2004
[email protected]c1bb5af2013-03-13 19:06:272005void LayerTreeHostImpl::SendManagedMemoryStats(
2006 size_t memory_visible_bytes,
2007 size_t memory_visible_and_nearby_bytes,
2008 size_t memory_use_bytes) {
2009 if (!renderer_)
2010 return;
2011
2012 // Round the numbers being sent up to the next 8MB, to throttle the rate
2013 // at which we spam the GPU process.
2014 static const size_t rounding_step = 8 * 1024 * 1024;
2015 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
2016 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
2017 rounding_step);
2018 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
2019 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
2020 last_sent_memory_visible_and_nearby_bytes_ ==
2021 memory_visible_and_nearby_bytes &&
2022 last_sent_memory_use_bytes_ == memory_use_bytes) {
2023 return;
2024 }
2025 last_sent_memory_visible_bytes_ = memory_visible_bytes;
2026 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
2027 last_sent_memory_use_bytes_ = memory_use_bytes;
2028
2029 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
2030 last_sent_memory_visible_and_nearby_bytes_,
2031 last_sent_memory_use_bytes_);
2032}
2033
2034void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
2035 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
2036}
2037
2038void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
2039 base::TimeTicks time) {
2040 if (!layer)
2041 return;
2042
2043 ScrollbarAnimationController* scrollbar_controller =
2044 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352045 if (scrollbar_controller && scrollbar_controller->Animate(time)) {
[email protected]0fc818e2013-03-18 06:45:202046 TRACE_EVENT_INSTANT0(
[email protected]c76faea2013-03-26 07:42:422047 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
2048 TRACE_EVENT_SCOPE_THREAD);
[email protected]c1bb5af2013-03-13 19:06:272049 client_->SetNeedsRedrawOnImplThread();
[email protected]0fc818e2013-03-18 06:45:202050 }
[email protected]c1bb5af2013-03-13 19:06:272051
2052 for (size_t i = 0; i < layer->children().size(); ++i)
2053 AnimateScrollbarsRecursive(layer->children()[i], time);
2054}
2055
[email protected]0fc818e2013-03-18 06:45:202056void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time) {
2057 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
2058 StartScrollbarAnimationRecursive(RootLayer(), time);
2059}
2060
2061void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
2062 base::TimeTicks time) {
2063 if (!layer)
2064 return;
2065
2066 ScrollbarAnimationController* scrollbar_controller =
2067 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:352068 if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
2069 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
[email protected]0fc818e2013-03-18 06:45:202070 if (delay > base::TimeDelta())
2071 client_->RequestScrollbarAnimationOnImplThread(delay);
[email protected]6bc09e82013-03-19 03:48:352072 else if (scrollbar_controller->Animate(time))
[email protected]0fc818e2013-03-18 06:45:202073 client_->SetNeedsRedrawOnImplThread();
2074 }
2075
2076 for (size_t i = 0; i < layer->children().size(); ++i)
2077 StartScrollbarAnimationRecursive(layer->children()[i], time);
2078}
2079
[email protected]c1bb5af2013-03-13 19:06:272080void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
2081 if (!tile_manager_)
2082 return;
2083
2084 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
2085 if (new_state.tree_priority == priority)
2086 return;
2087
2088 new_state.tree_priority = priority;
2089 tile_manager_->SetGlobalState(new_state);
2090}
2091
2092void LayerTreeHostImpl::BeginNextFrame() {
[email protected]fb7425a2013-04-22 16:28:552093 current_frame_timeticks_ = base::TimeTicks();
2094 current_frame_time_ = base::Time();
[email protected]c1bb5af2013-03-13 19:06:272095}
2096
[email protected]fb7425a2013-04-22 16:28:552097static void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) {
2098 if (ticks->is_null()) {
2099 DCHECK(now->is_null());
2100 *ticks = base::TimeTicks::Now();
2101 *now = base::Time::Now();
2102 }
2103}
2104
2105base::TimeTicks LayerTreeHostImpl::CurrentFrameTimeTicks() {
2106 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
2107 return current_frame_timeticks_;
2108}
2109
2110base::Time LayerTreeHostImpl::CurrentFrameTime() {
2111 UpdateCurrentFrameTime(&current_frame_timeticks_, &current_frame_time_);
[email protected]c1bb5af2013-03-13 19:06:272112 return current_frame_time_;
2113}
2114
2115scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
2116 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]f6742f52013-05-08 23:52:222117 if (this->pending_tree_)
2118 state->Set("activation_state", ActivationStateAsValue().release());
[email protected]c1bb5af2013-03-13 19:06:272119 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:212120 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:272121 if (tile_manager_)
2122 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
2123 state->Set("active_tree", active_tree_->AsValue().release());
[email protected]f6742f52013-05-08 23:52:222124 if (pending_tree_)
2125 state->Set("pending_tree", pending_tree_->AsValue().release());
2126 return state.PassAs<base::Value>();
2127}
2128
2129scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
2130 DCHECK(pending_tree_ && tile_manager_);
2131 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
2132 state->Set("lthi", TracedValue::CreateIDRef(this).release());
2133 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
[email protected]c1bb5af2013-03-13 19:06:272134 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:082135}
2136
[email protected]b9dcf43a2013-01-09 00:15:292137// static
[email protected]c1bb5af2013-03-13 19:06:272138LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
2139 LayerImpl* layer) {
2140 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:292141 return NULL;
[email protected]c1bb5af2013-03-13 19:06:272142
2143 if (layer->DrawsContent())
2144 return layer;
2145
[email protected]50761e92013-03-29 20:51:282146 for (LayerImplList::const_iterator it = layer->children().begin();
[email protected]c1bb5af2013-03-13 19:06:272147 it != layer->children().end(); ++it) {
2148 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
2149 if (nccr)
2150 return nccr;
2151 }
2152
2153 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:292154}
2155
[email protected]c1bb5af2013-03-13 19:06:272156skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
2157 LayerTreeImpl* tree =
2158 pending_tree_ ? pending_tree_.get() : active_tree_.get();
2159 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
2160 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:292161}
2162
[email protected]c1bb5af2013-03-13 19:06:272163void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
[email protected]846f455b2013-03-18 19:07:412164 if (debug_state_.continuous_painting != debug_state.continuous_painting)
[email protected]c1bb5af2013-03-13 19:06:272165 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:242166
[email protected]c1bb5af2013-03-13 19:06:272167 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:022168}
2169
[email protected]d3143c732012-10-05 19:17:592170} // namespace cc