blob: 6d1f6e98078f0f3f5c82a1f88df3aa4901927288 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// Copyright 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]556fd292013-03-18 08:03:045#include "cc/trees/layer_tree_host_impl.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]ac7c7f52012-11-08 06:26:507#include <algorithm>
8
[email protected]ad5d1422012-10-19 13:40:299#include "base/basictypes.h"
[email protected]4456eee22012-10-19 18:16:3810#include "base/debug/trace_event.h"
[email protected]4a23c374c2012-12-08 08:38:5511#include "base/json/json_writer.h"
[email protected]f5864912013-02-01 03:18:1412#include "base/metrics/histogram.h"
[email protected]de4afb5e2012-12-20 00:11:3413#include "base/stl_util.h"
[email protected]131a0c22013-02-12 18:31:0814#include "base/stringprintf.h"
[email protected]95e4e1a02013-03-18 07:09:0915#include "cc/animation/scrollbar_animation_controller.h"
[email protected]681ccff2013-03-18 06:13:5216#include "cc/base/math_util.h"
17#include "cc/base/util.h"
[email protected]6e84de22013-03-18 06:54:2718#include "cc/debug/debug_rect_history.h"
19#include "cc/debug/frame_rate_counter.h"
20#include "cc/debug/overdraw_metrics.h"
21#include "cc/debug/paint_time_counter.h"
22#include "cc/debug/rendering_stats.h"
[email protected]3052b10f2013-03-18 07:41:2123#include "cc/input/page_scale_animation.h"
24#include "cc/input/top_controls_manager.h"
[email protected]cc3cfaa2013-03-18 09:05:5225#include "cc/layers/append_quads_data.h"
26#include "cc/layers/heads_up_display_layer_impl.h"
27#include "cc/layers/layer_iterator.h"
28#include "cc/layers/scrollbar_layer_impl.h"
[email protected]7f0d825f2013-03-18 07:24:3029#include "cc/output/compositor_frame_metadata.h"
30#include "cc/output/delegating_renderer.h"
31#include "cc/output/gl_renderer.h"
32#include "cc/output/software_renderer.h"
[email protected]89e82672013-03-18 07:50:5633#include "cc/quads/render_pass_draw_quad.h"
34#include "cc/quads/shared_quad_state.h"
35#include "cc/quads/solid_color_draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4036#include "cc/resources/memory_history.h"
37#include "cc/resources/picture_layer_tiling.h"
38#include "cc/resources/prioritized_resource_manager.h"
[email protected]be4655a2013-03-18 08:36:3139#include "cc/scheduler/delay_based_time_source.h"
40#include "cc/scheduler/texture_uploader.h"
[email protected]556fd292013-03-18 08:03:0441#include "cc/trees/damage_tracker.h"
42#include "cc/trees/layer_tree_host.h"
43#include "cc/trees/layer_tree_host_common.h"
44#include "cc/trees/layer_tree_impl.h"
45#include "cc/trees/quad_culler.h"
46#include "cc/trees/single_thread_proxy.h"
47#include "cc/trees/tree_synchronizer.h"
[email protected]d455d552012-11-02 00:19:0648#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1349#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1450
[email protected]94f206c12012-08-25 00:09:1451namespace {
52
[email protected]c1bb5af2013-03-13 19:06:2753void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) {
54 if (visible) {
55 TRACE_EVENT_ASYNC_BEGIN1("webkit",
56 "LayerTreeHostImpl::SetVisible",
57 id,
58 "LayerTreeHostImpl",
59 id);
60 return;
61 }
[email protected]94f206c12012-08-25 00:09:1462
[email protected]c1bb5af2013-03-13 19:06:2763 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id);
[email protected]94f206c12012-08-25 00:09:1464}
65
[email protected]c1bb5af2013-03-13 19:06:2766std::string ValueToString(scoped_ptr<base::Value> value) {
67 std::string str;
68 base::JSONWriter::Write(value.get(), &str);
69 return str;
[email protected]131a0c22013-02-12 18:31:0870}
71
[email protected]c1bb5af2013-03-13 19:06:2772} // namespace
[email protected]94f206c12012-08-25 00:09:1473
[email protected]9c88e562012-09-14 22:21:3074namespace cc {
[email protected]94f206c12012-08-25 00:09:1475
[email protected]96baf3e2012-10-22 23:09:5576class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]c1bb5af2013-03-13 19:06:2777 public:
78 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
79 LayerTreeHostImpl* layer_tree_host_impl,
80 scoped_refptr<DelayBasedTimeSource> time_source) {
81 return make_scoped_ptr(
82 new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
83 time_source));
84 }
85 virtual ~LayerTreeHostImplTimeSourceAdapter() {
86 time_source_->setClient(NULL);
87 time_source_->setActive(false);
88 }
89
90 virtual void onTimerTick() OVERRIDE {
91 // In single threaded mode we attempt to simulate changing the current
92 // thread by maintaining a fake thread id. When we switch from one
93 // thread to another, we construct DebugScopedSetXXXThread objects that
94 // update the thread id. This lets DCHECKS that ensure we're on the
95 // right thread to work correctly in single threaded mode. The problem
96 // here is that the timer tasks are run via the message loop, and when
97 // they run, we've had no chance to construct a DebugScopedSetXXXThread
98 // object. The result is that we report that we're running on the main
99 // thread. In multi-threaded mode, this timer is run on the compositor
100 // thread, so to keep this consistent in single-threaded mode, we'll
101 // construct a DebugScopedSetImplThread object. There is no need to do
102 // this in multi-threaded mode since the real thread id's will be
103 // correct. In fact, setting fake thread id's interferes with the real
104 // thread id's and causes breakage.
105 scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
106 if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
107 set_impl_thread.reset(
108 new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
[email protected]94f206c12012-08-25 00:09:14109 }
110
[email protected]c1bb5af2013-03-13 19:06:27111 layer_tree_host_impl_->ActivatePendingTreeIfNeeded();
112 layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now());
113 layer_tree_host_impl_->BeginNextFrame();
114 }
[email protected]373974232013-01-10 22:20:50115
[email protected]c1bb5af2013-03-13 19:06:27116 void SetActive(bool active) {
117 if (active != time_source_->active())
118 time_source_->setActive(active);
119 }
[email protected]94f206c12012-08-25 00:09:14120
[email protected]c1bb5af2013-03-13 19:06:27121 private:
122 LayerTreeHostImplTimeSourceAdapter(
123 LayerTreeHostImpl* layer_tree_host_impl,
124 scoped_refptr<DelayBasedTimeSource> time_source)
125 : layer_tree_host_impl_(layer_tree_host_impl),
126 time_source_(time_source) {
127 time_source_->setClient(this);
128 }
[email protected]94f206c12012-08-25 00:09:14129
[email protected]c1bb5af2013-03-13 19:06:27130 LayerTreeHostImpl* layer_tree_host_impl_;
131 scoped_refptr<DelayBasedTimeSource> time_source_;
[email protected]94f206c12012-08-25 00:09:14132
[email protected]c1bb5af2013-03-13 19:06:27133 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14134};
135
[email protected]96baf3e2012-10-22 23:09:55136LayerTreeHostImpl::FrameData::FrameData()
[email protected]c1bb5af2013-03-13 19:06:27137 : contains_incomplete_tile(false) {}
138
139LayerTreeHostImpl::FrameData::~FrameData() {}
140
141scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
142 const LayerTreeSettings& settings,
143 LayerTreeHostImplClient* client,
144 Proxy* proxy) {
145 return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy));
[email protected]493067512012-09-19 23:34:10146}
147
[email protected]c1bb5af2013-03-13 19:06:27148LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings,
149 LayerTreeHostImplClient* client,
150 Proxy* proxy)
151 : client_(client),
152 proxy_(proxy),
153 did_lock_scrolling_layer_(false),
154 should_bubble_scrolls_(false),
155 wheel_scrolling_(false),
156 settings_(settings),
157 device_scale_factor_(1.f),
158 visible_(true),
159 managed_memory_policy_(
160 PrioritizedResourceManager::defaultMemoryAllocationLimit(),
161 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
162 0,
163 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING),
164 pinch_gesture_active_(false),
[email protected]9e3594522013-03-18 00:57:36165 fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
[email protected]7497316a2013-03-15 12:42:29166 paint_time_counter_(PaintTimeCounter::Create()),
[email protected]c1bb5af2013-03-13 19:06:27167 memory_history_(MemoryHistory::Create()),
[email protected]d35992782013-03-14 14:54:02168 debug_rect_history_(DebugRectHistory::Create()),
[email protected]c1bb5af2013-03-13 19:06:27169 num_impl_thread_scrolls_(0),
170 num_main_thread_scrolls_(0),
171 cumulative_num_layers_drawn_(0),
172 cumulative_num_missing_tiles_(0),
173 last_sent_memory_visible_bytes_(0),
174 last_sent_memory_visible_and_nearby_bytes_(0),
175 last_sent_memory_use_bytes_(0),
176 animation_registrar_(AnimationRegistrar::create()) {
177 DCHECK(proxy_->IsImplThread());
178 DidVisibilityChange(this, visible_);
179
180 SetDebugState(settings.initialDebugState);
181
182 if (settings.calculateTopControlsPosition) {
183 top_controls_manager_ =
184 TopControlsManager::Create(this,
185 settings.topControlsHeight,
186 settings.topControlsShowThreshold,
187 settings.topControlsHideThreshold);
188 }
189
190 SetDebugState(settings.initialDebugState);
191
192 // LTHI always has an active tree.
193 active_tree_ = LayerTreeImpl::create(this);
[email protected]493067512012-09-19 23:34:10194}
195
[email protected]c1bb5af2013-03-13 19:06:27196LayerTreeHostImpl::~LayerTreeHostImpl() {
197 DCHECK(proxy_->IsImplThread());
198 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
199
200 if (active_tree_->root_layer()) {
201 ClearRenderSurfaces();
202 // The layer trees must be destroyed before the layer tree host. We've
203 // made a contract with our animation controllers that the registrar
204 // will outlive them, and we must make good.
205 recycle_tree_.reset();
206 pending_tree_.reset();
207 active_tree_.reset();
208 }
[email protected]94f206c12012-08-25 00:09:14209}
210
[email protected]c1bb5af2013-03-13 19:06:27211void LayerTreeHostImpl::BeginCommit() {}
[email protected]3b31c6ac2012-12-06 21:27:29212
[email protected]c1bb5af2013-03-13 19:06:27213void LayerTreeHostImpl::CommitComplete() {
214 TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
[email protected]131a0c22013-02-12 18:31:08215
[email protected]c1bb5af2013-03-13 19:06:27216 // Impl-side painting needs an update immediately post-commit to have the
217 // opportunity to create tilings. Other paths can call UpdateDrawProperties
218 // more lazily when needed prior to drawing.
219 if (settings_.implSidePainting) {
220 pending_tree_->set_needs_update_draw_properties();
221 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
222 } else {
223 active_tree_->set_needs_update_draw_properties();
224 }
[email protected]3ba4cae2013-01-16 03:58:38225
[email protected]c1bb5af2013-03-13 19:06:27226 client_->SendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14227}
228
[email protected]c1bb5af2013-03-13 19:06:27229bool LayerTreeHostImpl::CanDraw() {
230 // Note: If you are changing this function or any other function that might
231 // affect the result of CanDraw, make sure to call
232 // client_->OnCanDrawStateChanged in the proper places and update the
233 // NotifyIfCanDrawChanged test.
[email protected]94f206c12012-08-25 00:09:14234
[email protected]c1bb5af2013-03-13 19:06:27235 if (!active_tree_->root_layer()) {
236 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer");
[email protected]2f1acc262012-11-16 21:42:22237 return false;
[email protected]c1bb5af2013-03-13 19:06:27238 }
239 if (device_viewport_size_.IsEmpty()) {
240 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport");
241 return false;
242 }
243 if (active_tree_->ViewportSizeInvalid()) {
244 TRACE_EVENT_INSTANT0(
245 "cc", "LayerTreeHostImpl::CanDraw viewport size recently changed");
246 return false;
247 }
248 if (!renderer_) {
249 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no renderer");
250 return false;
251 }
252 if (active_tree_->ContentsTexturesPurged()) {
253 TRACE_EVENT_INSTANT0(
254 "cc", "LayerTreeHostImpl::CanDraw contents textures purged");
255 return false;
256 }
257 return true;
[email protected]2f1acc262012-11-16 21:42:22258}
259
[email protected]c1bb5af2013-03-13 19:06:27260void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time,
261 base::Time wall_clock_time) {
262 AnimatePageScale(monotonic_time);
263 AnimateLayers(monotonic_time, wall_clock_time);
264 AnimateScrollbars(monotonic_time);
[email protected]ffb2720f2013-03-15 19:18:37265 AnimateTopControls(monotonic_time);
[email protected]94f206c12012-08-25 00:09:14266}
267
[email protected]c1bb5af2013-03-13 19:06:27268void LayerTreeHostImpl::ManageTiles() {
269 DCHECK(tile_manager_);
270 tile_manager_->ManageTiles();
271
272 size_t memory_required_bytes;
273 size_t memory_nice_to_have_bytes;
274 size_t memory_used_bytes;
275 tile_manager_->GetMemoryStats(&memory_required_bytes,
276 &memory_nice_to_have_bytes,
277 &memory_used_bytes);
278 SendManagedMemoryStats(memory_required_bytes,
279 memory_nice_to_have_bytes,
280 memory_used_bytes);
[email protected]f57bbc02012-11-21 07:02:15281}
282
[email protected]f8456612013-03-19 20:56:09283void LayerTreeHostImpl::SetAnticipatedDrawTime(base::TimeTicks time)
284{
285 if (tile_manager_)
286 tile_manager_->SetAnticipatedDrawTime(time);
287}
288
[email protected]c1bb5af2013-03-13 19:06:27289void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
290 bool anchor_point,
291 float page_scale,
292 base::TimeTicks start_time,
293 base::TimeDelta duration) {
294 if (!RootScrollLayer())
295 return;
296
297 gfx::Vector2dF scroll_total =
298 RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta();
299 gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
300 gfx::SizeF viewport_size =
301 gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor_);
302
303 double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
304 page_scale_animation_ =
305 PageScaleAnimation::Create(scroll_total,
306 active_tree_->total_page_scale_factor(),
307 viewport_size,
308 scaled_scrollable_size,
309 start_time_seconds);
310
311 if (anchor_point) {
312 gfx::Vector2dF anchor(target_offset);
313 page_scale_animation_->ZoomWithAnchor(anchor,
314 page_scale,
315 duration.InSecondsF());
316 } else {
317 gfx::Vector2dF scaled_target_offset = target_offset;
318 page_scale_animation_->ZoomTo(scaled_target_offset,
319 page_scale,
320 duration.InSecondsF());
321 }
322
323 client_->SetNeedsRedrawOnImplThread();
324 client_->SetNeedsCommitOnImplThread();
325 client_->RenewTreePriority();
[email protected]f57bbc02012-11-21 07:02:15326}
327
[email protected]c1bb5af2013-03-13 19:06:27328void LayerTreeHostImpl::ScheduleAnimation() {
329 client_->SetNeedsRedrawOnImplThread();
[email protected]f57bbc02012-11-21 07:02:15330}
331
[email protected]c1bb5af2013-03-13 19:06:27332bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
333 if (!EnsureRenderSurfaceLayerList())
334 return false;
[email protected]f57bbc02012-11-21 07:02:15335
[email protected]c1bb5af2013-03-13 19:06:27336 gfx::PointF device_viewport_point =
337 gfx::ScalePoint(viewport_point, device_scale_factor_);
[email protected]f57bbc02012-11-21 07:02:15338
[email protected]c1bb5af2013-03-13 19:06:27339 // First find out which layer was hit from the saved list of visible layers
340 // in the most recent frame.
341 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
342 device_viewport_point,
343 active_tree_->RenderSurfaceLayerList());
[email protected]f57bbc02012-11-21 07:02:15344
[email protected]c1bb5af2013-03-13 19:06:27345 // Walk up the hierarchy and look for a layer with a touch event handler
346 // region that the given point hits.
347 for (; layer_impl; layer_impl = layer_impl->parent()) {
348 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(device_viewport_point,
349 layer_impl))
350 return true;
351 }
[email protected]f57bbc02012-11-21 07:02:15352
[email protected]c1bb5af2013-03-13 19:06:27353 return false;
354}
355
356void LayerTreeHostImpl::TrackDamageForAllSurfaces(
357 LayerImpl* root_draw_layer,
358 const LayerList& render_surface_layer_list) {
359 // For now, we use damage tracking to compute a global scissor. To do this, we
360 // must compute all damage tracking before drawing anything, so that we know
361 // the root damage rect. The root damage rect is then used to scissor each
362 // surface.
363
364 for (int surface_index = render_surface_layer_list.size() - 1;
365 surface_index >= 0 ;
366 --surface_index) {
367 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
368 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
369 DCHECK(render_surface);
370 render_surface->damage_tracker()->UpdateDamageTrackingState(
371 render_surface->layer_list(),
372 render_surface_layer->id(),
373 render_surface->SurfacePropertyChangedOnlyFromDescendant(),
374 render_surface->content_rect(),
375 render_surface_layer->mask_layer(),
376 render_surface_layer->filters(),
377 render_surface_layer->filter().get());
378 }
379}
380
381void LayerTreeHostImpl::FrameData::AppendRenderPass(
382 scoped_ptr<RenderPass> render_pass) {
383 render_passes_by_id[render_pass->id] = render_pass.get();
384 render_passes.push_back(render_pass.Pass());
385}
386
387static void AppendQuadsForLayer(RenderPass* target_render_pass,
388 LayerImpl* layer,
389 const OcclusionTrackerImpl& occlusion_tracker,
390 AppendQuadsData* append_quads_data) {
391 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49392 QuadCuller quad_culler(&target_render_pass->quad_list,
393 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27394 layer,
395 occlusion_tracker,
396 layer->ShowDebugBorders(),
397 for_surface);
398 layer->AppendQuads(&quad_culler, append_quads_data);
399}
400
401static void AppendQuadsForRenderSurfaceLayer(
402 RenderPass* target_render_pass,
403 LayerImpl* layer,
404 const RenderPass* contributing_render_pass,
405 const OcclusionTrackerImpl& occlusion_tracker,
406 AppendQuadsData* append_quads_data) {
407 bool for_surface = true;
[email protected]c7e95b42013-03-18 01:13:49408 QuadCuller quad_culler(&target_render_pass->quad_list,
409 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27410 layer,
411 occlusion_tracker,
412 layer->ShowDebugBorders(),
413 for_surface);
414
415 bool is_replica = false;
416 layer->render_surface()->AppendQuads(&quad_culler,
417 append_quads_data,
418 is_replica,
419 contributing_render_pass->id);
420
421 // Add replica after the surface so that it appears below the surface.
422 if (layer->has_replica()) {
423 is_replica = true;
424 layer->render_surface()->AppendQuads(&quad_culler,
425 append_quads_data,
426 is_replica,
427 contributing_render_pass->id);
428 }
429}
430
431static void AppendQuadsToFillScreen(
432 RenderPass* target_render_pass,
433 LayerImpl* root_layer,
434 SkColor screen_background_color,
435 const OcclusionTrackerImpl& occlusion_tracker) {
436 if (!root_layer || !SkColorGetA(screen_background_color))
437 return;
438
439 Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen();
440 if (fill_region.IsEmpty())
441 return;
442
443 bool for_surface = false;
[email protected]c7e95b42013-03-18 01:13:49444 QuadCuller quad_culler(&target_render_pass->quad_list,
445 &target_render_pass->shared_quad_state_list,
[email protected]c1bb5af2013-03-13 19:06:27446 root_layer,
447 occlusion_tracker,
448 root_layer->ShowDebugBorders(),
449 for_surface);
450
451 // Manually create the quad state for the gutter quads, as the root layer
452 // doesn't have any bounds and so can't generate this itself.
453 // TODO(danakj): Make the gutter quads generated by the solid color layer
454 // (make it smarter about generating quads to fill unoccluded areas).
455
456 gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
457 float opacity = 1.f;
458 SharedQuadState* shared_quad_state =
[email protected]c7e95b42013-03-18 01:13:49459 quad_culler.UseSharedQuadState(SharedQuadState::Create());
[email protected]c1bb5af2013-03-13 19:06:27460 shared_quad_state->SetAll(root_layer->draw_transform(),
461 root_target_rect.size(),
462 root_target_rect,
463 root_target_rect,
[email protected]dc462d782012-11-21 21:43:01464 false,
[email protected]f57bbc02012-11-21 07:02:15465 opacity);
466
[email protected]c1bb5af2013-03-13 19:06:27467 AppendQuadsData append_quads_data;
[email protected]bda41962013-01-07 18:46:17468
[email protected]c1bb5af2013-03-13 19:06:27469 gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization);
470 bool did_invert = root_layer->screen_space_transform().GetInverse(
471 &transform_to_layer_space);
472 DCHECK(did_invert);
473 for (Region::Iterator fill_rects(fill_region);
474 fill_rects.has_rect();
475 fill_rects.next()) {
476 // The root layer transform is composed of translations and scales only,
477 // no perspective, so mapping is sufficient (as opposed to projecting).
478 gfx::Rect layer_rect =
[email protected]fa816c62013-03-18 04:24:21479 MathUtil::MapClippedRect(transform_to_layer_space, fill_rects.rect());
[email protected]c1bb5af2013-03-13 19:06:27480 // Skip the quad culler and just append the quads directly to avoid
481 // occlusion checks.
482 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
483 quad->SetNew(shared_quad_state, layer_rect, screen_background_color);
[email protected]c7e95b42013-03-18 01:13:49484 quad_culler.Append(quad.PassAs<DrawQuad>(), &append_quads_data);
[email protected]c1bb5af2013-03-13 19:06:27485 }
[email protected]467b3612012-08-28 07:41:16486}
487
[email protected]c1bb5af2013-03-13 19:06:27488bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
489 DCHECK(frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14490
[email protected]c1bb5af2013-03-13 19:06:27491 if (!CanDraw() || !active_tree_->root_layer())
492 return false;
[email protected]2d692992012-12-19 01:19:32493
[email protected]c1bb5af2013-03-13 19:06:27494 TrackDamageForAllSurfaces(active_tree_->root_layer(),
495 *frame->render_surface_layer_list);
[email protected]94f206c12012-08-25 00:09:14496
[email protected]c1bb5af2013-03-13 19:06:27497 TRACE_EVENT1("cc",
498 "LayerTreeHostImpl::CalculateRenderPasses",
499 "render_surface_layer_list.size()",
500 static_cast<long long unsigned>(
501 frame->render_surface_layer_list->size()));
[email protected]94f206c12012-08-25 00:09:14502
[email protected]c1bb5af2013-03-13 19:06:27503 // Create the render passes in dependency order.
504 for (int surface_index = frame->render_surface_layer_list->size() - 1;
505 surface_index >= 0 ;
506 --surface_index) {
507 LayerImpl* render_surface_layer =
508 (*frame->render_surface_layer_list)[surface_index];
509 render_surface_layer->render_surface()->AppendRenderPasses(frame);
510 }
[email protected]94f206c12012-08-25 00:09:14511
[email protected]c1bb5af2013-03-13 19:06:27512 bool record_metrics_for_frame =
513 settings_.showOverdrawInTracing &&
514 base::debug::TraceLog::GetInstance() &&
515 base::debug::TraceLog::GetInstance()->IsEnabled();
516 OcclusionTrackerImpl occlusion_tracker(
517 active_tree_->root_layer()->render_surface()->content_rect(),
518 record_metrics_for_frame);
519 occlusion_tracker.set_minimum_tracking_size(
520 settings_.minimumOcclusionTrackingSize);
[email protected]94f206c12012-08-25 00:09:14521
[email protected]846f455b2013-03-18 19:07:41522 if (debug_state_.show_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27523 occlusion_tracker.set_occluding_screen_space_rects_container(
524 &frame->occluding_screen_space_rects);
525 }
[email protected]846f455b2013-03-18 19:07:41526 if (debug_state_.show_non_occluding_rects) {
[email protected]c1bb5af2013-03-13 19:06:27527 occlusion_tracker.set_non_occluding_screen_space_rects_container(
528 &frame->non_occluding_screen_space_rects);
529 }
[email protected]94f206c12012-08-25 00:09:14530
[email protected]c1bb5af2013-03-13 19:06:27531 // Add quads to the Render passes in FrontToBack order to allow for testing
532 // occlusion and performing culling during the tree walk.
533 typedef LayerIterator<LayerImpl,
534 std::vector<LayerImpl*>,
535 RenderSurfaceImpl,
536 LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14537
[email protected]c1bb5af2013-03-13 19:06:27538 // Typically when we are missing a texture and use a checkerboard quad, we
539 // still draw the frame. However when the layer being checkerboarded is moving
540 // due to an impl-animation, we drop the frame to avoid flashing due to the
541 // texture suddenly appearing in the future.
542 bool draw_frame = true;
[email protected]94f206c12012-08-25 00:09:14543
[email protected]c1bb5af2013-03-13 19:06:27544 LayerIteratorType end =
545 LayerIteratorType::end(frame->render_surface_layer_list);
546 for (LayerIteratorType it =
547 LayerIteratorType::begin(frame->render_surface_layer_list);
548 it != end;
549 ++it) {
550 RenderPass::Id target_render_pass_id =
551 it.targetRenderSurfaceLayer()->render_surface()->RenderPassId();
552 RenderPass* target_render_pass =
553 frame->render_passes_by_id[target_render_pass_id];
[email protected]94f206c12012-08-25 00:09:14554
[email protected]c1bb5af2013-03-13 19:06:27555 occlusion_tracker.EnterLayer(it);
[email protected]94f206c12012-08-25 00:09:14556
[email protected]c1bb5af2013-03-13 19:06:27557 AppendQuadsData append_quads_data(target_render_pass->id);
[email protected]89228202012-08-29 03:20:30558
[email protected]c1bb5af2013-03-13 19:06:27559 if (it.representsContributingRenderSurface()) {
560 RenderPass::Id contributing_render_pass_id =
561 it->render_surface()->RenderPassId();
562 RenderPass* contributing_render_pass =
563 frame->render_passes_by_id[contributing_render_pass_id];
564 AppendQuadsForRenderSurfaceLayer(target_render_pass,
565 *it,
566 contributing_render_pass,
567 occlusion_tracker,
568 &append_quads_data);
569 } else if (it.representsItself() && !it->visible_content_rect().IsEmpty()) {
570 bool has_occlusion_from_outside_target_surface;
571 bool impl_draw_transform_is_unknown = false;
572 if (occlusion_tracker.Occluded(
573 it->render_target(),
574 it->visible_content_rect(),
575 it->draw_transform(),
576 impl_draw_transform_is_unknown,
577 it->is_clipped(),
578 it->clip_rect(),
579 &has_occlusion_from_outside_target_surface)) {
580 append_quads_data.hadOcclusionFromOutsideTargetSurface |=
581 has_occlusion_from_outside_target_surface;
582 } else {
583 DCHECK_EQ(active_tree_, it->layer_tree_impl());
584 it->WillDraw(resource_provider_.get());
585 frame->will_draw_layers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57586
[email protected]c1bb5af2013-03-13 19:06:27587 if (it->HasContributingDelegatedRenderPasses()) {
588 RenderPass::Id contributing_render_pass_id =
589 it->FirstContributingRenderPassId();
590 while (frame->render_passes_by_id.find(contributing_render_pass_id) !=
591 frame->render_passes_by_id.end()) {
592 RenderPass* render_pass =
593 frame->render_passes_by_id[contributing_render_pass_id];
[email protected]f5864912013-02-01 03:18:14594
[email protected]c1bb5af2013-03-13 19:06:27595 AppendQuadsData append_quads_data(render_pass->id);
596 AppendQuadsForLayer(render_pass,
597 *it,
598 occlusion_tracker,
599 &append_quads_data);
[email protected]7d929c02012-09-20 17:26:57600
[email protected]c1bb5af2013-03-13 19:06:27601 contributing_render_pass_id =
602 it->NextContributingRenderPassId(contributing_render_pass_id);
603 }
[email protected]94f206c12012-08-25 00:09:14604 }
605
[email protected]c1bb5af2013-03-13 19:06:27606 AppendQuadsForLayer(target_render_pass,
607 *it,
608 occlusion_tracker,
609 &append_quads_data);
610 }
[email protected]89228202012-08-29 03:20:30611
[email protected]c1bb5af2013-03-13 19:06:27612 ++cumulative_num_layers_drawn_;
[email protected]94f206c12012-08-25 00:09:14613 }
614
[email protected]c1bb5af2013-03-13 19:06:27615 if (append_quads_data.hadOcclusionFromOutsideTargetSurface)
616 target_render_pass->has_occlusion_from_outside_target_surface = true;
617
618 if (append_quads_data.numMissingTiles) {
619 cumulative_num_missing_tiles_ += append_quads_data.numMissingTiles;
620 bool layer_has_animating_transform =
621 it->screen_space_transform_is_animating() ||
622 it->draw_transform_is_animating();
623 if (layer_has_animating_transform)
624 draw_frame = false;
625 }
626
627 if (append_quads_data.hadIncompleteTile)
628 frame->contains_incomplete_tile = true;
629
630 occlusion_tracker.LeaveLayer(it);
631 }
632
[email protected]1d993172012-10-18 18:15:04633#ifndef NDEBUG
[email protected]c1bb5af2013-03-13 19:06:27634 for (size_t i = 0; i < frame->render_passes.size(); ++i) {
635 for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j)
636 DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state);
637 DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id)
638 != frame->render_passes_by_id.end());
639 }
[email protected]94f206c12012-08-25 00:09:14640#endif
[email protected]c1bb5af2013-03-13 19:06:27641 DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14642
[email protected]c1bb5af2013-03-13 19:06:27643 if (!active_tree_->has_transparent_background()) {
644 frame->render_passes.back()->has_transparent_background = false;
645 AppendQuadsToFillScreen(frame->render_passes.back(),
646 active_tree_->root_layer(),
647 active_tree_->background_color(),
648 occlusion_tracker);
649 }
[email protected]94f206c12012-08-25 00:09:14650
[email protected]c1bb5af2013-03-13 19:06:27651 if (draw_frame)
652 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
[email protected]94f206c12012-08-25 00:09:14653
[email protected]c1bb5af2013-03-13 19:06:27654 RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame);
655 renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes);
656 RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame);
[email protected]94f206c12012-08-25 00:09:14657
[email protected]c1bb5af2013-03-13 19:06:27658 return draw_frame;
[email protected]94f206c12012-08-25 00:09:14659}
660
[email protected]c1bb5af2013-03-13 19:06:27661void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) {
662 // Lazily create the time_source adapter so that we can vary the interval for
663 // testing.
664 if (!time_source_client_adapter_) {
665 time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
666 this,
667 DelayBasedTimeSource::create(LowFrequencyAnimationInterval(),
668 proxy_->CurrentThread()));
669 }
[email protected]94f206c12012-08-25 00:09:14670
[email protected]c1bb5af2013-03-13 19:06:27671 time_source_client_adapter_->SetActive(enabled);
[email protected]94f206c12012-08-25 00:09:14672}
673
[email protected]c1bb5af2013-03-13 19:06:27674static inline RenderPass* FindRenderPassById(
675 RenderPass::Id render_pass_id,
676 const LayerTreeHostImpl::FrameData& frame) {
677 RenderPassIdHashMap::const_iterator it =
678 frame.render_passes_by_id.find(render_pass_id);
679 return it != frame.render_passes_by_id.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14680}
681
[email protected]c1bb5af2013-03-13 19:06:27682static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id,
683 LayerTreeHostImpl::FrameData* frame) {
684 RenderPass* remove_render_pass =
685 FindRenderPassById(remove_render_pass_id, *frame);
686 // The pass was already removed by another quad - probably the original, and
687 // we are the replica.
688 if (!remove_render_pass)
689 return;
690 RenderPassList& render_passes = frame->render_passes;
691 RenderPassList::iterator to_remove = std::find(render_passes.begin(),
692 render_passes.end(),
693 remove_render_pass);
[email protected]94f206c12012-08-25 00:09:14694
[email protected]c1bb5af2013-03-13 19:06:27695 DCHECK(to_remove != render_passes.end());
[email protected]94f206c12012-08-25 00:09:14696
[email protected]c1bb5af2013-03-13 19:06:27697 scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove);
698 frame->render_passes.erase(to_remove);
699 frame->render_passes_by_id.erase(remove_render_pass_id);
[email protected]94f206c12012-08-25 00:09:14700
[email protected]c1bb5af2013-03-13 19:06:27701 // Now follow up for all RenderPass quads and remove their RenderPasses
702 // recursively.
703 const QuadList& quad_list = removed_pass->quad_list;
704 QuadList::constBackToFrontIterator quad_list_iterator =
705 quad_list.backToFrontBegin();
706 for (; quad_list_iterator != quad_list.backToFrontEnd();
707 ++quad_list_iterator) {
708 DrawQuad* current_quad = (*quad_list_iterator);
709 if (current_quad->material != DrawQuad::RENDER_PASS)
710 continue;
[email protected]94f206c12012-08-25 00:09:14711
[email protected]c1bb5af2013-03-13 19:06:27712 RenderPass::Id next_remove_render_pass_id =
713 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id;
714 RemoveRenderPassesRecursive(next_remove_render_pass_id, frame);
715 }
[email protected]94f206c12012-08-25 00:09:14716}
717
[email protected]c1bb5af2013-03-13 19:06:27718bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::
719 ShouldRemoveRenderPass(const RenderPassDrawQuad& quad,
720 const FrameData& frame) const {
721 bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty();
722 bool quad_has_cached_resource =
723 renderer_.HaveCachedResourcesForRenderPassId(quad.render_pass_id);
724 if (quad_has_damage) {
725 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
726 return false;
727 } else if (!quad_has_cached_resource) {
728 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
729 return false;
730 }
731 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
732 return true;
[email protected]94f206c12012-08-25 00:09:14733}
734
[email protected]c1bb5af2013-03-13 19:06:27735bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass(
736 const RenderPassDrawQuad& quad, const FrameData& frame) const {
737 const RenderPass* render_pass =
738 FindRenderPassById(quad.render_pass_id, frame);
739 if (!render_pass)
740 return false;
[email protected]94f206c12012-08-25 00:09:14741
[email protected]c1bb5af2013-03-13 19:06:27742 // If any quad or RenderPass draws into this RenderPass, then keep it.
743 const QuadList& quad_list = render_pass->quad_list;
744 for (QuadList::constBackToFrontIterator quad_list_iterator =
745 quad_list.backToFrontBegin();
746 quad_list_iterator != quad_list.backToFrontEnd();
747 ++quad_list_iterator) {
748 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14749
[email protected]c1bb5af2013-03-13 19:06:27750 if (current_quad->material != DrawQuad::RENDER_PASS)
751 return false;
[email protected]94f206c12012-08-25 00:09:14752
[email protected]c1bb5af2013-03-13 19:06:27753 const RenderPass* contributing_pass = FindRenderPassById(
754 RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame);
755 if (contributing_pass)
756 return false;
757 }
758 return true;
[email protected]94f206c12012-08-25 00:09:14759}
760
761// Defined for linking tests.
[email protected]c1bb5af2013-03-13 19:06:27762template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
763 LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(
764 CullRenderPassesWithCachedTextures culler, FrameData* frame);
765template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses<
766 LayerTreeHostImpl::CullRenderPassesWithNoQuads>(
767 CullRenderPassesWithNoQuads culler, FrameData*);
[email protected]94f206c12012-08-25 00:09:14768
769// static
[email protected]c1bb5af2013-03-13 19:06:27770template <typename RenderPassCuller>
771void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
772 FrameData* frame) {
773 for (size_t it = culler.RenderPassListBegin(frame->render_passes);
774 it != culler.RenderPassListEnd(frame->render_passes);
775 it = culler.RenderPassListNext(it)) {
776 const RenderPass* current_pass = frame->render_passes[it];
777 const QuadList& quad_list = current_pass->quad_list;
778 QuadList::constBackToFrontIterator quad_list_iterator =
779 quad_list.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14780
[email protected]c1bb5af2013-03-13 19:06:27781 for (; quad_list_iterator != quad_list.backToFrontEnd();
782 ++quad_list_iterator) {
783 DrawQuad* current_quad = *quad_list_iterator;
[email protected]94f206c12012-08-25 00:09:14784
[email protected]c1bb5af2013-03-13 19:06:27785 if (current_quad->material != DrawQuad::RENDER_PASS)
786 continue;
[email protected]94f206c12012-08-25 00:09:14787
[email protected]c1bb5af2013-03-13 19:06:27788 const RenderPassDrawQuad* render_pass_quad =
789 RenderPassDrawQuad::MaterialCast(current_quad);
790 if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame))
791 continue;
[email protected]94f206c12012-08-25 00:09:14792
[email protected]c1bb5af2013-03-13 19:06:27793 // We are changing the vector in the middle of iteration. Because we
794 // delete render passes that draw into the current pass, we are
795 // guaranteed that any data from the iterator to the end will not
796 // change. So, capture the iterator position from the end of the
797 // list, and restore it after the change.
798 size_t position_from_end = frame->render_passes.size() - it;
799 RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame);
800 it = frame->render_passes.size() - position_from_end;
801 DCHECK_GE(frame->render_passes.size(), position_from_end);
[email protected]94f206c12012-08-25 00:09:14802 }
[email protected]c1bb5af2013-03-13 19:06:27803 }
[email protected]94f206c12012-08-25 00:09:14804}
805
[email protected]c1bb5af2013-03-13 19:06:27806bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
807 TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
[email protected]94f206c12012-08-25 00:09:14808
[email protected]c1bb5af2013-03-13 19:06:27809 active_tree_->UpdateDrawProperties(
810 LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27811
[email protected]c1bb5af2013-03-13 19:06:27812 frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
813 frame->render_passes.clear();
814 frame->render_passes_by_id.clear();
815 frame->will_draw_layers.clear();
[email protected]94f206c12012-08-25 00:09:14816
[email protected]c1bb5af2013-03-13 19:06:27817 if (!CalculateRenderPasses(frame))
818 return false;
[email protected]94f206c12012-08-25 00:09:14819
[email protected]c1bb5af2013-03-13 19:06:27820 // If we return true, then we expect DrawLayers() to be called before this
821 // function is called again.
822 return true;
[email protected]94f206c12012-08-25 00:09:14823}
824
[email protected]c1bb5af2013-03-13 19:06:27825void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
826 const ManagedMemoryPolicy& policy) {
827 bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
[email protected]46b8acc2013-03-19 22:38:35828 visible_ ? policy.bytes_limit_when_visible
829 : policy.bytes_limit_when_not_visible,
830 ManagedMemoryPolicy::PriorityCutoffToValue(
831 visible_ ? policy.priority_cutoff_when_visible
832 : policy.priority_cutoff_when_not_visible));
[email protected]c1bb5af2013-03-13 19:06:27833 if (evicted_resources) {
834 active_tree_->SetContentsTexturesPurged();
835 if (pending_tree_)
836 pending_tree_->SetContentsTexturesPurged();
837 client_->SetNeedsCommitOnImplThread();
838 client_->OnCanDrawStateChanged(CanDraw());
839 client_->RenewTreePriority();
840 }
841 client_->SendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43842
[email protected]c1bb5af2013-03-13 19:06:27843 if (tile_manager_) {
844 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
845 new_state.memory_limit_in_bytes = visible_ ?
[email protected]46b8acc2013-03-19 22:38:35846 policy.bytes_limit_when_visible :
847 policy.bytes_limit_when_not_visible;
[email protected]c1bb5af2013-03-13 19:06:27848 new_state.memory_limit_policy =
[email protected]46b8acc2013-03-19 22:38:35849 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
[email protected]c1bb5af2013-03-13 19:06:27850 visible_ ?
[email protected]46b8acc2013-03-19 22:38:35851 policy.priority_cutoff_when_visible :
852 policy.priority_cutoff_when_not_visible);
[email protected]c1bb5af2013-03-13 19:06:27853 tile_manager_->SetGlobalState(new_state);
854 }
[email protected]94f206c12012-08-25 00:09:14855}
856
[email protected]c1bb5af2013-03-13 19:06:27857bool LayerTreeHostImpl::HasImplThread() const {
858 return proxy_->HasImplThread();
[email protected]61de5812012-11-08 07:03:44859}
860
[email protected]c1bb5af2013-03-13 19:06:27861void LayerTreeHostImpl::ScheduleManageTiles() {
862 if (client_)
863 client_->SetNeedsManageTilesOnImplThread();
[email protected]8947cbe2012-11-28 05:27:43864}
865
[email protected]86126792013-03-16 20:07:54866void LayerTreeHostImpl::DidInitializeVisibleTile() {
867 // TODO(reveman): Determine tiles that changed and only damage
868 // what's necessary.
869 SetFullRootLayerDamage();
[email protected]c1bb5af2013-03-13 19:06:27870 if (client_)
[email protected]86126792013-03-16 20:07:54871 client_->DidInitializeVisibleTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47872}
873
[email protected]c1bb5af2013-03-13 19:06:27874bool LayerTreeHostImpl::ShouldClearRootRenderPass() const {
875 return settings_.shouldClearRootRenderPass;
[email protected]f35e2322012-12-15 21:45:52876}
877
[email protected]c1bb5af2013-03-13 19:06:27878void LayerTreeHostImpl::SetManagedMemoryPolicy(
879 const ManagedMemoryPolicy& policy) {
880 if (managed_memory_policy_ == policy)
881 return;
[email protected]61de5812012-11-08 07:03:44882
[email protected]c1bb5af2013-03-13 19:06:27883 managed_memory_policy_ = policy;
884 if (!proxy_->HasImplThread()) {
885 // TODO(ccameron): In single-thread mode, this can be called on the main
886 // thread by GLRenderer::OnMemoryAllocationChanged.
887 DebugScopedSetImplThread impl_thread(proxy_);
888 EnforceManagedMemoryPolicy(managed_memory_policy_);
889 } else {
890 DCHECK(proxy_->IsImplThread());
891 EnforceManagedMemoryPolicy(managed_memory_policy_);
892 }
893 // We always need to commit after changing the memory policy because the new
894 // limit can result in more or less content having texture allocated for it.
895 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:14896}
897
[email protected]c1bb5af2013-03-13 19:06:27898void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
899 base::TimeDelta interval) {
900 client_->OnVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14901}
902
[email protected]c1bb5af2013-03-13 19:06:27903void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
904 const CompositorFrameAck& ack) {
905 if (!renderer_)
906 return;
[email protected]b6f3d7e2012-12-08 00:11:21907
[email protected]c1bb5af2013-03-13 19:06:27908 // TODO(piman): We may need to do some validation on this ack before
909 // processing it.
910 renderer_->ReceiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16911}
912
[email protected]c1bb5af2013-03-13 19:06:27913void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
914 client_->OnCanDrawStateChanged(CanDraw());
[email protected]3b31c6ac2012-12-06 21:27:29915}
916
[email protected]c1bb5af2013-03-13 19:06:27917CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
918 CompositorFrameMetadata metadata;
919 metadata.device_scale_factor = device_scale_factor_;
920 metadata.page_scale_factor = active_tree_->total_page_scale_factor();
921 metadata.viewport_size = active_tree_->ScrollableViewportSize();
922 metadata.root_layer_size = active_tree_->ScrollableSize();
923 metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
924 metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
925 if (top_controls_manager_) {
926 metadata.location_bar_offset =
927 gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset());
928 metadata.location_bar_content_translation =
929 gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset());
930 }
[email protected]bf189f62012-12-18 03:42:11931
[email protected]c1bb5af2013-03-13 19:06:27932 if (!RootScrollLayer())
[email protected]bf189f62012-12-18 03:42:11933 return metadata;
[email protected]c1bb5af2013-03-13 19:06:27934
[email protected]ffb2720f2013-03-15 19:18:37935 metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
[email protected]c1bb5af2013-03-13 19:06:27936
937 return metadata;
[email protected]bf189f62012-12-18 03:42:11938}
939
[email protected]f0c2a242013-03-15 19:34:52940void LayerTreeHostImpl::DrawLayers(FrameData* frame,
941 base::TimeTicks frame_begin_time) {
[email protected]c1bb5af2013-03-13 19:06:27942 TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
943 DCHECK(CanDraw());
944 DCHECK(!frame->render_passes.empty());
[email protected]94f206c12012-08-25 00:09:14945
[email protected]9e3594522013-03-18 00:57:36946 fps_counter_->SaveTimeStamp(frame_begin_time);
[email protected]94f206c12012-08-25 00:09:14947
[email protected]c1bb5af2013-03-13 19:06:27948 if (tile_manager_) {
949 memory_history_->SaveEntry(
950 tile_manager_->memory_stats_from_last_assign());
951 }
[email protected]1191d9d2013-02-02 06:00:33952
[email protected]846f455b2013-03-18 19:07:41953 if (debug_state_.ShowHudRects()) {
[email protected]d35992782013-03-14 14:54:02954 debug_rect_history_->SaveDebugRectsForCurrentFrame(
[email protected]c1bb5af2013-03-13 19:06:27955 active_tree_->root_layer(),
956 *frame->render_surface_layer_list,
957 frame->occluding_screen_space_rects,
958 frame->non_occluding_screen_space_rects,
959 debug_state_);
960 }
[email protected]94f206c12012-08-25 00:09:14961
[email protected]846f455b2013-03-18 19:07:41962 if (debug_state_.trace_all_rendered_frames) {
[email protected]c1bb5af2013-03-13 19:06:27963 TRACE_EVENT_INSTANT1("cc.debug", "Frame",
964 "frame", ValueToString(FrameStateAsValue()));
965 }
[email protected]131a0c22013-02-12 18:31:08966
[email protected]c1bb5af2013-03-13 19:06:27967 // Because the contents of the HUD depend on everything else in the frame, the
968 // contents of its texture are updated as the last thing before the frame is
969 // drawn.
970 if (active_tree_->hud_layer())
[email protected]264dc0332013-03-17 21:00:54971 active_tree_->hud_layer()->UpdateHudTexture(resource_provider_.get());
[email protected]94f206c12012-08-25 00:09:14972
[email protected]c1bb5af2013-03-13 19:06:27973 renderer_->DrawFrame(frame->render_passes);
974 // The render passes should be consumed by the renderer.
975 DCHECK(frame->render_passes.empty());
976 frame->render_passes_by_id.clear();
[email protected]94f206c12012-08-25 00:09:14977
[email protected]c1bb5af2013-03-13 19:06:27978 // The next frame should start by assuming nothing has changed, and changes
979 // are noted as they occur.
[email protected]264dc0332013-03-17 21:00:54980 for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) {
[email protected]c1bb5af2013-03-13 19:06:27981 (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()->
982 DidDrawDamagedArea();
983 }
984 active_tree_->root_layer()->ResetAllChangeTrackingForSubtree();
985 UpdateAnimationState();
[email protected]94f206c12012-08-25 00:09:14986}
987
[email protected]c1bb5af2013-03-13 19:06:27988void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
989 for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
990 frame.will_draw_layers[i]->DidDraw(resource_provider_.get());
[email protected]b914e102012-10-02 08:11:52991
[email protected]c1bb5af2013-03-13 19:06:27992 // Once all layers have been drawn, pending texture uploads should no
993 // longer block future uploads.
994 resource_provider_->MarkPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:14995}
996
[email protected]c1bb5af2013-03-13 19:06:27997void LayerTreeHostImpl::FinishAllRendering() {
998 if (renderer_)
999 renderer_->Finish();
[email protected]94f206c12012-08-25 00:09:141000}
1001
[email protected]c1bb5af2013-03-13 19:06:271002bool LayerTreeHostImpl::IsContextLost() {
1003 DCHECK(proxy_->IsImplThread());
1004 return renderer_ && renderer_->IsContextLost();
[email protected]94f206c12012-08-25 00:09:141005}
1006
[email protected]c1bb5af2013-03-13 19:06:271007const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
1008 return renderer_->Capabilities();
[email protected]94f206c12012-08-25 00:09:141009}
1010
[email protected]c1bb5af2013-03-13 19:06:271011bool LayerTreeHostImpl::SwapBuffers() {
[email protected]c1bb5af2013-03-13 19:06:271012 return renderer_->SwapBuffers();
[email protected]94f206c12012-08-25 00:09:141013}
1014
[email protected]c1bb5af2013-03-13 19:06:271015gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
1016 return device_viewport_size();
[email protected]493067512012-09-19 23:34:101017}
1018
[email protected]ffb2720f2013-03-15 19:18:371019gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
1020 gfx::SizeF dip_size =
1021 gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
1022
1023 // The clip layer should be used if non-overlay scrollbars may exist since
1024 // it adjusts for them.
1025 LayerImpl* clip_layer = active_tree_->RootClipLayer();
1026 if (!Settings().solidColorScrollbars && clip_layer &&
1027 clip_layer->masks_to_bounds())
1028 dip_size = clip_layer->bounds();
1029
1030 float topOffset =
1031 top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
1032 return gfx::SizeF(dip_size.width(), dip_size.height() - topOffset);
1033}
1034
[email protected]c1bb5af2013-03-13 19:06:271035const LayerTreeSettings& LayerTreeHostImpl::Settings() const {
1036 return settings();
[email protected]493067512012-09-19 23:34:101037}
1038
[email protected]c1bb5af2013-03-13 19:06:271039void LayerTreeHostImpl::DidLoseOutputSurface() {
1040 client_->DidLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:141041}
1042
[email protected]c1bb5af2013-03-13 19:06:271043void LayerTreeHostImpl::OnSwapBuffersComplete() {
1044 client_->OnSwapBuffersCompleteOnImplThread();
[email protected]94f206c12012-08-25 00:09:141045}
1046
[email protected]c1bb5af2013-03-13 19:06:271047void LayerTreeHostImpl::Readback(void* pixels,
1048 gfx::Rect rect_in_device_viewport) {
1049 DCHECK(renderer_);
1050 renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport);
[email protected]94f206c12012-08-25 00:09:141051}
1052
[email protected]69b50ec2013-01-19 04:58:011053bool LayerTreeHostImpl::haveRootScrollLayer() const {
[email protected]c1bb5af2013-03-13 19:06:271054 return RootScrollLayer();
[email protected]69b50ec2013-01-19 04:58:011055}
1056
[email protected]c1bb5af2013-03-13 19:06:271057LayerImpl* LayerTreeHostImpl::RootLayer() const {
1058 return active_tree_->root_layer();
[email protected]8bef40572012-12-11 21:38:081059}
1060
[email protected]c1bb5af2013-03-13 19:06:271061LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
1062 return active_tree_->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:081063}
1064
[email protected]c1bb5af2013-03-13 19:06:271065LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
1066 return active_tree_->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:081067}
1068
[email protected]94f206c12012-08-25 00:09:141069// Content layers can be either directly scrollable or contained in an outer
1070// scrolling layer which applies the scroll transform. Given a content layer,
1071// this function returns the associated scroll layer if any.
[email protected]c1bb5af2013-03-13 19:06:271072static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
1073 if (!layer_impl)
[email protected]94f206c12012-08-25 00:09:141074 return 0;
[email protected]c1bb5af2013-03-13 19:06:271075
1076 if (layer_impl->scrollable())
1077 return layer_impl;
1078
1079 if (layer_impl->DrawsContent() &&
1080 layer_impl->parent() &&
1081 layer_impl->parent()->scrollable())
1082 return layer_impl->parent();
1083
1084 return 0;
[email protected]94f206c12012-08-25 00:09:141085}
1086
[email protected]c1bb5af2013-03-13 19:06:271087void LayerTreeHostImpl::CreatePendingTree() {
1088 CHECK(!pending_tree_);
1089 if (recycle_tree_)
1090 recycle_tree_.swap(pending_tree_);
1091 else
1092 pending_tree_ = LayerTreeImpl::create(this);
1093 client_->OnCanDrawStateChanged(CanDraw());
1094 client_->OnHasPendingTreeStateChanged(pending_tree_);
1095 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
1096 TRACE_EVENT_ASYNC_STEP0("cc",
1097 "PendingTree", pending_tree_.get(), "waiting");
[email protected]2e7ca422012-12-20 02:57:271098}
1099
[email protected]c1bb5af2013-03-13 19:06:271100void LayerTreeHostImpl::CheckForCompletedTileUploads() {
1101 DCHECK(!client_->IsInsideDraw()) <<
1102 "Checking for completed uploads within a draw may trigger "
1103 "spurious redraws.";
1104 if (tile_manager_)
1105 tile_manager_->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:481106}
1107
[email protected]c1bb5af2013-03-13 19:06:271108bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
1109 if (!pending_tree_)
1110 return false;
[email protected]2e7ca422012-12-20 02:57:271111
[email protected]c1bb5af2013-03-13 19:06:271112 CHECK(tile_manager_);
[email protected]2ae038b2013-01-28 12:52:091113
[email protected]c1bb5af2013-03-13 19:06:271114 pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:161115
[email protected]c1bb5af2013-03-13 19:06:271116 TRACE_EVENT_ASYNC_STEP1("cc",
1117 "PendingTree", pending_tree_.get(), "activate",
1118 "state", ValueToString(ActivationStateAsValue()));
[email protected]4f0a5002013-01-28 13:02:271119
[email protected]c1bb5af2013-03-13 19:06:271120 // It's always fine to activate to an empty tree. Otherwise, only
1121 // activate once all visible resources in pending tree are ready
1122 // or tile manager has no work scheduled for pending tree.
1123 if (active_tree_->root_layer() &&
1124 !pending_tree_->AreVisibleResourcesReady()) {
1125 // In smoothness takes priority mode, the pending tree's priorities are
1126 // ignored, so the tile manager may not have work for it even though it
1127 // is simultaneously not ready to be activated.
1128 if (tile_manager_->GlobalState().tree_priority ==
1129 SMOOTHNESS_TAKES_PRIORITY ||
1130 tile_manager_->HasPendingWorkScheduled(PENDING_TREE)) {
1131 TRACE_EVENT_ASYNC_STEP0("cc",
1132 "PendingTree",
1133 pending_tree_.get(),
1134 "waiting");
1135 return false;
[email protected]131a0c22013-02-12 18:31:081136 }
[email protected]c1bb5af2013-03-13 19:06:271137 }
[email protected]2e7ca422012-12-20 02:57:271138
[email protected]c1bb5af2013-03-13 19:06:271139 ActivatePendingTree();
1140 return true;
[email protected]2e7ca422012-12-20 02:57:271141}
1142
[email protected]c1bb5af2013-03-13 19:06:271143void LayerTreeHostImpl::ActivatePendingTree() {
1144 CHECK(pending_tree_);
1145 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
[email protected]1e0f8d62013-01-09 07:41:351146
[email protected]c1bb5af2013-03-13 19:06:271147 active_tree_->PushPersistedState(pending_tree_.get());
1148 if (pending_tree_->needs_full_tree_sync()) {
1149 active_tree_->SetRootLayer(
[email protected]b5651c22013-03-14 15:06:331150 TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271151 active_tree_->DetachLayerTree(),
1152 active_tree_.get()));
1153 }
[email protected]b5651c22013-03-14 15:06:331154 TreeSynchronizer::PushProperties(pending_tree_->root_layer(),
[email protected]c1bb5af2013-03-13 19:06:271155 active_tree_->root_layer());
1156 DCHECK(!recycle_tree_);
[email protected]48871fc2013-01-23 07:36:511157
[email protected]c1bb5af2013-03-13 19:06:271158 pending_tree_->PushPropertiesTo(active_tree_.get());
[email protected]48871fc2013-01-23 07:36:511159
[email protected]c1bb5af2013-03-13 19:06:271160 // Now that we've synced everything from the pending tree to the active
1161 // tree, rename the pending tree the recycle tree so we can reuse it on the
1162 // next sync.
1163 pending_tree_.swap(recycle_tree_);
1164 recycle_tree_->ClearRenderSurfaces();
[email protected]48871fc2013-01-23 07:36:511165
[email protected]c1bb5af2013-03-13 19:06:271166 active_tree_->DidBecomeActive();
[email protected]37386f052013-01-13 00:42:221167
[email protected]c1bb5af2013-03-13 19:06:271168 // Reduce wasted memory now that unlinked resources are guaranteed not
1169 // to be used.
1170 client_->ReduceWastedContentsTextureMemoryOnImplThread();
[email protected]a0b84172013-02-04 08:13:411171
[email protected]c1bb5af2013-03-13 19:06:271172 client_->OnCanDrawStateChanged(CanDraw());
1173 client_->OnHasPendingTreeStateChanged(pending_tree_);
1174 client_->SetNeedsRedrawOnImplThread();
1175 client_->RenewTreePriority();
[email protected]652cf132013-02-15 21:53:241176
[email protected]846f455b2013-03-18 19:07:411177 if (tile_manager_ && debug_state_.continuous_painting) {
[email protected]c1bb5af2013-03-13 19:06:271178 RenderingStats stats;
1179 tile_manager_->GetRenderingStats(&stats);
1180 paint_time_counter_->SaveRasterizeTime(
1181 stats.totalRasterizeTimeForNowBinsOnPendingTree,
1182 active_tree_->source_frame_number());
1183 }
[email protected]2e7ca422012-12-20 02:57:271184}
1185
[email protected]c1bb5af2013-03-13 19:06:271186void LayerTreeHostImpl::SetVisible(bool visible) {
1187 DCHECK(proxy_->IsImplThread());
[email protected]94f206c12012-08-25 00:09:141188
[email protected]c1bb5af2013-03-13 19:06:271189 if (visible_ == visible)
1190 return;
1191 visible_ = visible;
1192 DidVisibilityChange(this, visible_);
1193 EnforceManagedMemoryPolicy(managed_memory_policy_);
[email protected]94f206c12012-08-25 00:09:141194
[email protected]c1bb5af2013-03-13 19:06:271195 if (!renderer_)
1196 return;
[email protected]94f206c12012-08-25 00:09:141197
[email protected]c1bb5af2013-03-13 19:06:271198 renderer_->SetVisible(visible);
[email protected]94f206c12012-08-25 00:09:141199
[email protected]c1bb5af2013-03-13 19:06:271200 SetBackgroundTickingEnabled(
1201 !visible_ &&
1202 !animation_registrar_->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141203}
1204
[email protected]c1bb5af2013-03-13 19:06:271205bool LayerTreeHostImpl::InitializeRenderer(
1206 scoped_ptr<OutputSurface> output_surface) {
1207 // Since we will create a new resource provider, we cannot continue to use
1208 // the old resources (i.e. render_surfaces and texture IDs). Clear them
1209 // before we destroy the old resource provider.
1210 if (active_tree_->root_layer())
1211 ClearRenderSurfaces();
1212 if (active_tree_->root_layer())
1213 SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer());
1214 if (pending_tree_ && pending_tree_->root_layer())
1215 SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer());
1216 if (recycle_tree_ && recycle_tree_->root_layer())
1217 SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer());
[email protected]45c4b1e2013-01-16 02:19:401218
[email protected]c1bb5af2013-03-13 19:06:271219 // Note: order is important here.
1220 renderer_.reset();
1221 tile_manager_.reset();
1222 resource_provider_.reset();
1223 output_surface_.reset();
[email protected]94f206c12012-08-25 00:09:141224
[email protected]c1bb5af2013-03-13 19:06:271225 if (!output_surface->BindToClient(this))
1226 return false;
[email protected]be3181652012-09-25 13:02:131227
[email protected]c1bb5af2013-03-13 19:06:271228 scoped_ptr<ResourceProvider> resource_provider =
1229 ResourceProvider::Create(output_surface.get());
1230 if (!resource_provider)
1231 return false;
[email protected]be3181652012-09-25 13:02:131232
[email protected]c1bb5af2013-03-13 19:06:271233 if (settings_.implSidePainting) {
1234 tile_manager_.reset(new TileManager(this,
1235 resource_provider.get(),
1236 settings_.numRasterThreads,
1237 settings_.useCheapnessEstimator,
1238 settings_.useColorEstimator,
1239 settings_.predictionBenchmarking));
[email protected]846f455b2013-03-18 19:07:411240 tile_manager_->SetRecordRenderingStats(debug_state_.RecordRenderingStats());
[email protected]c1bb5af2013-03-13 19:06:271241 }
[email protected]8947cbe2012-11-28 05:27:431242
[email protected]c1bb5af2013-03-13 19:06:271243 if (output_surface->capabilities().has_parent_compositor) {
1244 renderer_ = DelegatingRenderer::Create(this, output_surface.get(),
1245 resource_provider.get());
1246 } else if (output_surface->context3d()) {
1247 renderer_ = GLRenderer::Create(this,
1248 output_surface.get(),
1249 resource_provider.get());
1250 } else if (output_surface->software_device()) {
1251 renderer_ = SoftwareRenderer::Create(this,
1252 output_surface.get(),
1253 resource_provider.get());
1254 }
1255 if (!renderer_)
1256 return false;
[email protected]be3181652012-09-25 13:02:131257
[email protected]c1bb5af2013-03-13 19:06:271258 resource_provider_ = resource_provider.Pass();
1259 output_surface_ = output_surface.Pass();
[email protected]94f206c12012-08-25 00:09:141260
[email protected]c1bb5af2013-03-13 19:06:271261 if (!visible_)
1262 renderer_->SetVisible(visible_);
[email protected]94f206c12012-08-25 00:09:141263
[email protected]c1bb5af2013-03-13 19:06:271264 client_->OnCanDrawStateChanged(CanDraw());
[email protected]8db2213c2012-09-05 22:08:211265
[email protected]c1bb5af2013-03-13 19:06:271266 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1267 // to be initialized to get max texture size.
1268 active_tree_->set_needs_update_draw_properties();
1269 if (pending_tree_)
1270 pending_tree_->set_needs_update_draw_properties();
[email protected]615c78a2013-01-24 23:44:161271
[email protected]c1bb5af2013-03-13 19:06:271272 return true;
[email protected]94f206c12012-08-25 00:09:141273}
1274
[email protected]c1bb5af2013-03-13 19:06:271275void LayerTreeHostImpl::SetViewportSize(gfx::Size layout_viewport_size,
1276 gfx::Size device_viewport_size) {
1277 if (layout_viewport_size == layout_viewport_size_ &&
1278 device_viewport_size == device_viewport_size_)
1279 return;
[email protected]94f206c12012-08-25 00:09:141280
[email protected]c1bb5af2013-03-13 19:06:271281 if (pending_tree_ && device_viewport_size_ != device_viewport_size)
1282 active_tree_->SetViewportSizeInvalid();
[email protected]318822852013-02-14 00:54:271283
[email protected]c1bb5af2013-03-13 19:06:271284 layout_viewport_size_ = layout_viewport_size;
1285 device_viewport_size_ = device_viewport_size;
[email protected]94f206c12012-08-25 00:09:141286
[email protected]c1bb5af2013-03-13 19:06:271287 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141288
[email protected]c1bb5af2013-03-13 19:06:271289 if (renderer_)
1290 renderer_->ViewportChanged();
[email protected]8db2213c2012-09-05 22:08:211291
[email protected]c1bb5af2013-03-13 19:06:271292 client_->OnCanDrawStateChanged(CanDraw());
[email protected]94f206c12012-08-25 00:09:141293}
1294
[email protected]c1bb5af2013-03-13 19:06:271295static void AdjustScrollsForPageScaleChange(LayerImpl* layer_impl,
1296 float page_scale_change) {
1297 if (!layer_impl)
1298 return;
[email protected]94f206c12012-08-25 00:09:141299
[email protected]c1bb5af2013-03-13 19:06:271300 if (layer_impl->scrollable()) {
1301 // We need to convert impl-side scroll deltas to page_scale space.
1302 gfx::Vector2dF scroll_delta = layer_impl->scroll_delta();
1303 scroll_delta.Scale(page_scale_change);
1304 layer_impl->SetScrollDelta(scroll_delta);
1305 }
[email protected]94f206c12012-08-25 00:09:141306
[email protected]c1bb5af2013-03-13 19:06:271307 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1308 AdjustScrollsForPageScaleChange(layer_impl->children()[i],
1309 page_scale_change);
[email protected]94f206c12012-08-25 00:09:141310}
1311
[email protected]c1bb5af2013-03-13 19:06:271312void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
1313 if (device_scale_factor == device_scale_factor_)
1314 return;
1315 device_scale_factor_ = device_scale_factor;
[email protected]c0dd24c2012-08-30 23:25:271316
[email protected]c1bb5af2013-03-13 19:06:271317 UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141318}
1319
[email protected]c1bb5af2013-03-13 19:06:271320void LayerTreeHostImpl::UpdateMaxScrollOffset() {
1321 active_tree_->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141322}
1323
[email protected]c1bb5af2013-03-13 19:06:271324void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() {
1325 active_tree_->set_needs_update_draw_properties();
[email protected]3ba4cae2013-01-16 03:58:381326}
1327
[email protected]c1bb5af2013-03-13 19:06:271328void LayerTreeHostImpl::setNeedsRedraw() {
1329 client_->SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:141330}
1331
[email protected]c1bb5af2013-03-13 19:06:271332bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() {
1333 active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
1334 return active_tree_->RenderSurfaceLayerList().size();
[email protected]94f206c12012-08-25 00:09:141335}
1336
[email protected]c1bb5af2013-03-13 19:06:271337InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin(
1338 gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) {
1339 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin");
[email protected]94f206c12012-08-25 00:09:141340
[email protected]c1bb5af2013-03-13 19:06:271341 if (top_controls_manager_)
1342 top_controls_manager_->ScrollBegin();
[email protected]3ba4cae2013-01-16 03:58:381343
[email protected]c1bb5af2013-03-13 19:06:271344 DCHECK(!CurrentlyScrollingLayer());
1345 ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141346
[email protected]c1bb5af2013-03-13 19:06:271347 if (!EnsureRenderSurfaceLayerList())
[email protected]94f206c12012-08-25 00:09:141348 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141349
[email protected]c1bb5af2013-03-13 19:06:271350 gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
1351 device_scale_factor_);
[email protected]94f206c12012-08-25 00:09:141352
[email protected]c1bb5af2013-03-13 19:06:271353 // First find out which layer was hit from the saved list of visible layers
1354 // in the most recent frame.
1355 LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint(
1356 device_viewport_point, active_tree_->RenderSurfaceLayerList());
[email protected]31bfe272012-10-19 18:49:521357
[email protected]c1bb5af2013-03-13 19:06:271358 // Walk up the hierarchy and look for a scrollable layer.
1359 LayerImpl* potentially_scrolling_layer_impl = 0;
1360 for (; layer_impl; layer_impl = layer_impl->parent()) {
1361 // The content layer can also block attempts to scroll outside the main
1362 // thread.
1363 ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
1364 if (status == ScrollOnMainThread) {
1365 num_main_thread_scrolls_++;
1366 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421367 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271368 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141369 }
1370
[email protected]c1bb5af2013-03-13 19:06:271371 LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
1372 if (!scroll_layer_impl)
1373 continue;
[email protected]94f206c12012-08-25 00:09:141374
[email protected]c1bb5af2013-03-13 19:06:271375 status = scroll_layer_impl->TryScroll(device_viewport_point, type);
[email protected]94f206c12012-08-25 00:09:141376
[email protected]c1bb5af2013-03-13 19:06:271377 // If any layer wants to divert the scroll event to the main thread, abort.
1378 if (status == ScrollOnMainThread) {
1379 num_main_thread_scrolls_++;
1380 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
[email protected]b7c4783f2013-03-15 23:11:421381 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271382 return ScrollOnMainThread;
[email protected]94f206c12012-08-25 00:09:141383 }
1384
[email protected]c1bb5af2013-03-13 19:06:271385 if (status == ScrollStarted && !potentially_scrolling_layer_impl)
1386 potentially_scrolling_layer_impl = scroll_layer_impl;
1387 }
1388
1389 // When hiding top controls is enabled and the controls are hidden or
1390 // overlaying the content, force scrolls to be enabled on the root layer to
1391 // allow bringing the top controls back into view.
1392 if (!potentially_scrolling_layer_impl && top_controls_manager_ &&
1393 top_controls_manager_->content_top_offset() !=
1394 settings_.topControlsHeight) {
1395 potentially_scrolling_layer_impl = RootScrollLayer();
1396 }
1397
1398 if (potentially_scrolling_layer_impl) {
[email protected]0fc818e2013-03-18 06:45:201399 active_tree_->SetCurrentlyScrollingLayer(
[email protected]c1bb5af2013-03-13 19:06:271400 potentially_scrolling_layer_impl);
1401 should_bubble_scrolls_ = (type != NonBubblingGesture);
1402 wheel_scrolling_ = (type == Wheel);
1403 num_impl_thread_scrolls_++;
1404 client_->RenewTreePriority();
1405 UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
[email protected]b7c4783f2013-03-15 23:11:421406 active_tree()->DidBeginScroll();
[email protected]c1bb5af2013-03-13 19:06:271407 return ScrollStarted;
1408 }
1409 return ScrollIgnored;
[email protected]94f206c12012-08-25 00:09:141410}
1411
[email protected]c1bb5af2013-03-13 19:06:271412gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
1413 LayerImpl* layer_impl,
1414 float scale_from_viewport_to_screen_space,
1415 gfx::PointF viewport_point,
1416 gfx::Vector2dF viewport_delta) {
1417 // Layers with non-invertible screen space transforms should not have passed
1418 // the scroll hit test in the first place.
1419 DCHECK(layer_impl->screen_space_transform().IsInvertible());
1420 gfx::Transform inverse_screen_space_transform(
1421 gfx::Transform::kSkipInitialization);
1422 bool did_invert = layer_impl->screen_space_transform().GetInverse(
1423 &inverse_screen_space_transform);
1424 // TODO: With the advent of impl-side crolling for non-root layers, we may
1425 // need to explicitly handle uninvertible transforms here.
1426 DCHECK(did_invert);
[email protected]94f206c12012-08-25 00:09:141427
[email protected]c1bb5af2013-03-13 19:06:271428 gfx::PointF screen_space_point =
1429 gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
[email protected]94f206c12012-08-25 00:09:141430
[email protected]c1bb5af2013-03-13 19:06:271431 gfx::Vector2dF screen_space_delta = viewport_delta;
1432 screen_space_delta.Scale(scale_from_viewport_to_screen_space);
1433
1434 // First project the scroll start and end points to local layer space to find
1435 // the scroll delta in layer coordinates.
1436 bool start_clipped, end_clipped;
1437 gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta;
1438 gfx::PointF local_start_point =
[email protected]fa816c62013-03-18 04:24:211439 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271440 screen_space_point,
[email protected]fa816c62013-03-18 04:24:211441 &start_clipped);
[email protected]c1bb5af2013-03-13 19:06:271442 gfx::PointF local_end_point =
[email protected]fa816c62013-03-18 04:24:211443 MathUtil::ProjectPoint(inverse_screen_space_transform,
[email protected]c1bb5af2013-03-13 19:06:271444 screen_space_end_point,
[email protected]fa816c62013-03-18 04:24:211445 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271446
1447 // In general scroll point coordinates should not get clipped.
1448 DCHECK(!start_clipped);
1449 DCHECK(!end_clipped);
1450 if (start_clipped || end_clipped)
1451 return gfx::Vector2dF();
1452
1453 // local_start_point and local_end_point are in content space but we want to
1454 // move them to layer space for scrolling.
1455 float width_scale = 1.f / layer_impl->contents_scale_x();
1456 float height_scale = 1.f / layer_impl->contents_scale_y();
1457 local_start_point.Scale(width_scale, height_scale);
1458 local_end_point.Scale(width_scale, height_scale);
1459
1460 // Apply the scroll delta.
1461 gfx::Vector2dF previous_delta = layer_impl->scroll_delta();
1462 layer_impl->ScrollBy(local_end_point - local_start_point);
1463
1464 // Get the end point in the layer's content space so we can apply its
1465 // ScreenSpaceTransform.
1466 gfx::PointF actual_local_end_point = local_start_point +
1467 layer_impl->scroll_delta() -
1468 previous_delta;
1469 gfx::PointF actual_local_content_end_point =
1470 gfx::ScalePoint(actual_local_end_point,
1471 1.f / width_scale,
1472 1.f / height_scale);
1473
1474 // Calculate the applied scroll delta in viewport space coordinates.
1475 gfx::PointF actual_screen_space_end_point =
[email protected]fa816c62013-03-18 04:24:211476 MathUtil::MapPoint(layer_impl->screen_space_transform(),
[email protected]c1bb5af2013-03-13 19:06:271477 actual_local_content_end_point,
[email protected]fa816c62013-03-18 04:24:211478 &end_clipped);
[email protected]c1bb5af2013-03-13 19:06:271479 DCHECK(!end_clipped);
1480 if (end_clipped)
1481 return gfx::Vector2dF();
1482 gfx::PointF actual_viewport_end_point =
1483 gfx::ScalePoint(actual_screen_space_end_point,
1484 1.f / scale_from_viewport_to_screen_space);
1485 return actual_viewport_end_point - viewport_point;
[email protected]94f206c12012-08-25 00:09:141486}
1487
[email protected]c1bb5af2013-03-13 19:06:271488static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
1489 gfx::Vector2dF local_delta) {
1490 gfx::Vector2dF previous_delta(layer_impl->scroll_delta());
1491 layer_impl->ScrollBy(local_delta);
1492 return layer_impl->scroll_delta() - previous_delta;
1493}
1494
1495bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point,
1496 gfx::Vector2dF scroll_delta) {
1497 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
1498 if (!CurrentlyScrollingLayer())
1499 return false;
1500
1501 gfx::Vector2dF pending_delta = scroll_delta;
1502 bool did_scroll = false;
1503
[email protected]ffb2720f2013-03-15 19:18:371504 if (top_controls_manager_ && CurrentlyScrollingLayer() == RootScrollLayer()) {
[email protected]a91e4f82013-03-15 06:58:061505 pending_delta = top_controls_manager_->ScrollBy(pending_delta);
[email protected]ffb2720f2013-03-15 19:18:371506 UpdateMaxScrollOffset();
1507 }
[email protected]a91e4f82013-03-15 06:58:061508
[email protected]c1bb5af2013-03-13 19:06:271509 for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
1510 layer_impl;
1511 layer_impl = layer_impl->parent()) {
1512 if (!layer_impl->scrollable())
1513 continue;
1514
1515 gfx::Vector2dF applied_delta;
[email protected]c1bb5af2013-03-13 19:06:271516 // Gesture events need to be transformed from viewport coordinates to local
1517 // layer coordinates so that the scrolling contents exactly follow the
1518 // user's finger. In contrast, wheel events represent a fixed amount of
1519 // scrolling so we can just apply them directly.
1520 if (!wheel_scrolling_) {
1521 float scale_from_viewport_to_screen_space = device_scale_factor_;
1522 applied_delta =
1523 ScrollLayerWithViewportSpaceDelta(layer_impl,
1524 scale_from_viewport_to_screen_space,
1525 viewport_point, pending_delta);
1526 } else {
1527 applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta);
[email protected]94f206c12012-08-25 00:09:141528 }
[email protected]94f206c12012-08-25 00:09:141529
[email protected]c1bb5af2013-03-13 19:06:271530 // If the layer wasn't able to move, try the next one in the hierarchy.
1531 float move_threshold_squared = 0.1f * 0.1f;
1532 if (applied_delta.LengthSquared() < move_threshold_squared) {
1533 if (should_bubble_scrolls_ || !did_lock_scrolling_layer_)
1534 continue;
1535 else
1536 break;
[email protected]94f206c12012-08-25 00:09:141537 }
[email protected]c1bb5af2013-03-13 19:06:271538 did_scroll = true;
1539 did_lock_scrolling_layer_ = true;
1540 if (!should_bubble_scrolls_) {
[email protected]0fc818e2013-03-18 06:45:201541 active_tree_->SetCurrentlyScrollingLayer(layer_impl);
[email protected]c1bb5af2013-03-13 19:06:271542 break;
[email protected]94f206c12012-08-25 00:09:141543 }
[email protected]94f206c12012-08-25 00:09:141544
[email protected]c1bb5af2013-03-13 19:06:271545 // If the applied delta is within 45 degrees of the input delta, bail out to
1546 // make it easier to scroll just one layer in one direction without
1547 // affecting any of its parents.
1548 float angle_threshold = 45;
[email protected]fa816c62013-03-18 04:24:211549 if (MathUtil::SmallestAngleBetweenVectors(
[email protected]c1bb5af2013-03-13 19:06:271550 applied_delta, pending_delta) < angle_threshold) {
1551 pending_delta = gfx::Vector2d();
1552 break;
[email protected]4a23c374c2012-12-08 08:38:551553 }
[email protected]c1bb5af2013-03-13 19:06:271554
1555 // Allow further movement only on an axis perpendicular to the direction in
1556 // which the layer moved.
1557 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
[email protected]fa816c62013-03-18 04:24:211558 pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
[email protected]c1bb5af2013-03-13 19:06:271559
1560 if (gfx::ToFlooredVector2d(pending_delta).IsZero())
1561 break;
1562 }
1563
[email protected]b7c4783f2013-03-15 23:11:421564 active_tree()->DidUpdateScroll();
[email protected]c1bb5af2013-03-13 19:06:271565 if (did_scroll) {
1566 client_->SetNeedsCommitOnImplThread();
1567 client_->SetNeedsRedrawOnImplThread();
1568 client_->RenewTreePriority();
1569 }
1570 return did_scroll;
[email protected]4a23c374c2012-12-08 08:38:551571}
1572
[email protected]c1bb5af2013-03-13 19:06:271573void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
1574 active_tree_->ClearCurrentlyScrollingLayer();
1575 did_lock_scrolling_layer_ = false;
[email protected]94f206c12012-08-25 00:09:141576}
1577
[email protected]c1bb5af2013-03-13 19:06:271578void LayerTreeHostImpl::ScrollEnd() {
1579 if (top_controls_manager_)
1580 top_controls_manager_->ScrollEnd();
1581 ClearCurrentlyScrollingLayer();
[email protected]b7c4783f2013-03-15 23:11:421582 active_tree()->DidEndScroll();
[email protected]0fc818e2013-03-18 06:45:201583 StartScrollbarAnimation(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141584}
1585
[email protected]c1bb5af2013-03-13 19:06:271586void LayerTreeHostImpl::PinchGestureBegin() {
1587 pinch_gesture_active_ = true;
1588 previous_pinch_anchor_ = gfx::Point();
1589 client_->RenewTreePriority();
[email protected]94f206c12012-08-25 00:09:141590}
1591
[email protected]c1bb5af2013-03-13 19:06:271592void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
1593 gfx::Point anchor) {
1594 TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
[email protected]d3afa112012-12-08 06:24:281595
[email protected]c1bb5af2013-03-13 19:06:271596 if (!RootScrollLayer())
1597 return;
[email protected]d3afa112012-12-08 06:24:281598
[email protected]c1bb5af2013-03-13 19:06:271599 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1600 // position over the course of the magnify.
1601 float page_scale_delta = active_tree_->page_scale_delta();
1602 gfx::PointF previous_scale_anchor =
1603 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1604 active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
1605 page_scale_delta = active_tree_->page_scale_delta();
1606 gfx::PointF new_scale_anchor =
1607 gfx::ScalePoint(anchor, 1.f / page_scale_delta);
1608 gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
1609
1610 previous_pinch_anchor_ = anchor;
1611
1612 move.Scale(1 / active_tree_->page_scale_factor());
1613
1614 RootScrollLayer()->ScrollBy(move);
1615
[email protected]c1bb5af2013-03-13 19:06:271616 client_->SetNeedsCommitOnImplThread();
1617 client_->SetNeedsRedrawOnImplThread();
1618 client_->RenewTreePriority();
[email protected]d3afa112012-12-08 06:24:281619}
1620
[email protected]c1bb5af2013-03-13 19:06:271621void LayerTreeHostImpl::PinchGestureEnd() {
1622 pinch_gesture_active_ = false;
[email protected]c1bb5af2013-03-13 19:06:271623 client_->SetNeedsCommitOnImplThread();
[email protected]94f206c12012-08-25 00:09:141624}
1625
[email protected]c1bb5af2013-03-13 19:06:271626static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
1627 LayerImpl* layer_impl) {
1628 if (!layer_impl)
1629 return;
[email protected]94f206c12012-08-25 00:09:141630
[email protected]c1bb5af2013-03-13 19:06:271631 gfx::Vector2d scroll_delta =
1632 gfx::ToFlooredVector2d(layer_impl->scroll_delta());
1633 if (!scroll_delta.IsZero()) {
1634 LayerTreeHostCommon::ScrollUpdateInfo scroll;
1635 scroll.layerId = layer_impl->id();
1636 scroll.scrollDelta = scroll_delta;
1637 scroll_info->scrolls.push_back(scroll);
1638 layer_impl->SetSentScrollDelta(scroll_delta);
1639 }
[email protected]94f206c12012-08-25 00:09:141640
[email protected]c1bb5af2013-03-13 19:06:271641 for (size_t i = 0; i < layer_impl->children().size(); ++i)
1642 CollectScrollDeltas(scroll_info, layer_impl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141643}
1644
[email protected]c1bb5af2013-03-13 19:06:271645scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
1646 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
[email protected]362f1e8b2013-01-21 16:54:301647
[email protected]c1bb5af2013-03-13 19:06:271648 CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
1649 scroll_info->pageScaleDelta = active_tree_->page_scale_delta();
1650 active_tree_->set_sent_page_scale_delta(scroll_info->pageScaleDelta);
[email protected]362f1e8b2013-01-21 16:54:301651
[email protected]c1bb5af2013-03-13 19:06:271652 return scroll_info.Pass();
[email protected]362f1e8b2013-01-21 16:54:301653}
1654
[email protected]c1bb5af2013-03-13 19:06:271655void LayerTreeHostImpl::SetFullRootLayerDamage() {
1656 if (active_tree_->root_layer()) {
1657 RenderSurfaceImpl* render_surface =
1658 active_tree_->root_layer()->render_surface();
1659 if (render_surface)
1660 render_surface->damage_tracker()->ForceFullDamageNextUpdate();
1661 }
[email protected]829ad972013-01-28 23:36:101662}
1663
[email protected]c1bb5af2013-03-13 19:06:271664void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
1665 if (!page_scale_animation_ || !RootScrollLayer())
1666 return;
1667
1668 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1669 gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
1670 RootScrollLayer()->scroll_delta();
1671
1672 active_tree_->SetPageScaleDelta(
1673 page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
1674 active_tree_->page_scale_factor());
1675 gfx::Vector2dF next_scroll =
1676 page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
1677
1678 RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
1679 client_->SetNeedsRedrawOnImplThread();
1680
1681 if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
1682 page_scale_animation_.reset();
1683 client_->SetNeedsCommitOnImplThread();
1684 client_->RenewTreePriority();
1685 }
[email protected]829ad972013-01-28 23:36:101686}
1687
[email protected]ffb2720f2013-03-15 19:18:371688void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
1689 if (!top_controls_manager_ || !RootScrollLayer())
1690 return;
1691 gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
1692 UpdateMaxScrollOffset();
1693 RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
1694 scroll, 1.f / active_tree_->total_page_scale_factor()));
1695}
1696
[email protected]c1bb5af2013-03-13 19:06:271697void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
1698 base::Time wall_clock_time) {
1699 if (!settings_.acceleratedAnimationEnabled ||
1700 animation_registrar_->active_animation_controllers().empty() ||
1701 !active_tree_->root_layer())
1702 return;
1703
1704 TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
1705
1706 last_animation_time_ = wall_clock_time;
1707 double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF();
1708
1709 AnimationRegistrar::AnimationControllerMap copy =
1710 animation_registrar_->active_animation_controllers();
1711 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1712 iter != copy.end();
1713 ++iter)
1714 (*iter).second->Animate(monotonic_seconds);
1715
1716 client_->SetNeedsRedrawOnImplThread();
1717 SetBackgroundTickingEnabled(
1718 !visible_ &&
1719 !animation_registrar_->active_animation_controllers().empty());
[email protected]131a0c22013-02-12 18:31:081720}
1721
[email protected]c1bb5af2013-03-13 19:06:271722void LayerTreeHostImpl::UpdateAnimationState() {
1723 if (!settings_.acceleratedAnimationEnabled ||
1724 animation_registrar_->active_animation_controllers().empty() ||
1725 !active_tree_->root_layer())
1726 return;
1727
1728 TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
1729 scoped_ptr<AnimationEventsVector> events =
1730 make_scoped_ptr(new AnimationEventsVector);
1731 AnimationRegistrar::AnimationControllerMap copy =
1732 animation_registrar_->active_animation_controllers();
1733 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1734 iter != copy.end();
1735 ++iter)
1736 (*iter).second->UpdateState(events.get());
1737
1738 if (!events->empty()) {
1739 client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(),
1740 last_animation_time_);
1741 }
[email protected]131a0c22013-02-12 18:31:081742}
1743
[email protected]c1bb5af2013-03-13 19:06:271744base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
1745 return base::TimeDelta::FromSeconds(1);
1746}
1747
1748void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) {
1749 DCHECK(current);
1750 current->DidLoseOutputSurface();
1751 if (current->mask_layer())
1752 SendDidLoseOutputSurfaceRecursive(current->mask_layer());
1753 if (current->replica_layer())
1754 SendDidLoseOutputSurfaceRecursive(current->replica_layer());
1755 for (size_t i = 0; i < current->children().size(); ++i)
1756 SendDidLoseOutputSurfaceRecursive(current->children()[i]);
1757}
1758
1759void LayerTreeHostImpl::ClearRenderSurfaces() {
1760 active_tree_->ClearRenderSurfaces();
1761 if (pending_tree_)
1762 pending_tree_->ClearRenderSurfaces();
1763}
1764
1765std::string LayerTreeHostImpl::LayerTreeAsText() const {
1766 std::string str;
1767 if (active_tree_->root_layer()) {
1768 str = active_tree_->root_layer()->LayerTreeAsText();
1769 str += "RenderSurfaces:\n";
1770 DumpRenderSurfaces(&str, 1, active_tree_->root_layer());
1771 }
1772 return str;
1773}
1774
1775std::string LayerTreeHostImpl::LayerTreeAsJson() const {
1776 std::string str;
1777 if (active_tree_->root_layer()) {
1778 scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
1779 base::JSONWriter::WriteWithOptions(
1780 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1781 }
1782 return str;
1783}
1784
1785void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str,
1786 int indent,
1787 const LayerImpl* layer) const {
1788 if (layer->render_surface())
1789 layer->render_surface()->DumpSurface(str, indent);
1790
1791 for (size_t i = 0; i < layer->children().size(); ++i)
1792 DumpRenderSurfaces(str, indent, layer->children()[i]);
1793}
1794
1795int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
[email protected]9e3594522013-03-18 00:57:361796 return fps_counter_->current_frame_number();
[email protected]c1bb5af2013-03-13 19:06:271797}
1798
1799void LayerTreeHostImpl::CollectRenderingStats(RenderingStats* stats) const {
[email protected]9e3594522013-03-18 00:57:361800 stats->numFramesSentToScreen = fps_counter_->current_frame_number();
1801 stats->droppedFrameCount = fps_counter_->dropped_frame_count();
[email protected]c1bb5af2013-03-13 19:06:271802 stats->numImplThreadScrolls = num_impl_thread_scrolls_;
1803 stats->numMainThreadScrolls = num_main_thread_scrolls_;
1804 stats->numLayersDrawn = cumulative_num_layers_drawn_;
1805 stats->numMissingTiles = cumulative_num_missing_tiles_;
1806
1807 if (tile_manager_)
1808 tile_manager_->GetRenderingStats(stats);
1809}
1810
1811void LayerTreeHostImpl::SendManagedMemoryStats(
1812 size_t memory_visible_bytes,
1813 size_t memory_visible_and_nearby_bytes,
1814 size_t memory_use_bytes) {
1815 if (!renderer_)
1816 return;
1817
1818 // Round the numbers being sent up to the next 8MB, to throttle the rate
1819 // at which we spam the GPU process.
1820 static const size_t rounding_step = 8 * 1024 * 1024;
1821 memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step);
1822 memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes,
1823 rounding_step);
1824 memory_use_bytes = RoundUp(memory_use_bytes, rounding_step);
1825 if (last_sent_memory_visible_bytes_ == memory_visible_bytes &&
1826 last_sent_memory_visible_and_nearby_bytes_ ==
1827 memory_visible_and_nearby_bytes &&
1828 last_sent_memory_use_bytes_ == memory_use_bytes) {
1829 return;
1830 }
1831 last_sent_memory_visible_bytes_ = memory_visible_bytes;
1832 last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes;
1833 last_sent_memory_use_bytes_ = memory_use_bytes;
1834
1835 renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_,
1836 last_sent_memory_visible_and_nearby_bytes_,
1837 last_sent_memory_use_bytes_);
1838}
1839
1840void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
1841 AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
1842}
1843
1844void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
1845 base::TimeTicks time) {
1846 if (!layer)
1847 return;
1848
1849 ScrollbarAnimationController* scrollbar_controller =
1850 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:351851 if (scrollbar_controller && scrollbar_controller->Animate(time)) {
[email protected]0fc818e2013-03-18 06:45:201852 TRACE_EVENT_INSTANT0(
1853 "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars");
[email protected]c1bb5af2013-03-13 19:06:271854 client_->SetNeedsRedrawOnImplThread();
[email protected]0fc818e2013-03-18 06:45:201855 }
[email protected]c1bb5af2013-03-13 19:06:271856
1857 for (size_t i = 0; i < layer->children().size(); ++i)
1858 AnimateScrollbarsRecursive(layer->children()[i], time);
1859}
1860
[email protected]0fc818e2013-03-18 06:45:201861void LayerTreeHostImpl::StartScrollbarAnimation(base::TimeTicks time) {
1862 TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
1863 StartScrollbarAnimationRecursive(RootLayer(), time);
1864}
1865
1866void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
1867 base::TimeTicks time) {
1868 if (!layer)
1869 return;
1870
1871 ScrollbarAnimationController* scrollbar_controller =
1872 layer->scrollbar_animation_controller();
[email protected]6bc09e82013-03-19 03:48:351873 if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
1874 base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
[email protected]0fc818e2013-03-18 06:45:201875 if (delay > base::TimeDelta())
1876 client_->RequestScrollbarAnimationOnImplThread(delay);
[email protected]6bc09e82013-03-19 03:48:351877 else if (scrollbar_controller->Animate(time))
[email protected]0fc818e2013-03-18 06:45:201878 client_->SetNeedsRedrawOnImplThread();
1879 }
1880
1881 for (size_t i = 0; i < layer->children().size(); ++i)
1882 StartScrollbarAnimationRecursive(layer->children()[i], time);
1883}
1884
[email protected]c1bb5af2013-03-13 19:06:271885void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
1886 if (!tile_manager_)
1887 return;
1888
1889 GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState());
1890 if (new_state.tree_priority == priority)
1891 return;
1892
1893 new_state.tree_priority = priority;
1894 tile_manager_->SetGlobalState(new_state);
1895}
1896
1897void LayerTreeHostImpl::BeginNextFrame() {
1898 current_frame_time_ = base::TimeTicks();
1899}
1900
1901base::TimeTicks LayerTreeHostImpl::CurrentFrameTime() {
1902 if (current_frame_time_.is_null())
1903 current_frame_time_ = base::TimeTicks::Now();
1904 return current_frame_time_;
1905}
1906
1907scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const {
1908 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1909 state->Set("activation_state", ActivationStateAsValue().release());
1910 state->Set("frame_state", FrameStateAsValue().release());
1911 return state.PassAs<base::Value>();
1912}
1913
1914scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const {
1915 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:041916 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:271917 state->SetBoolean("visible_resources_ready",
1918 pending_tree_->AreVisibleResourcesReady());
1919 state->Set("tile_manager", tile_manager_->BasicStateAsValue().release());
1920 return state.PassAs<base::Value>();
1921}
1922
1923scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const {
1924 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
[email protected]7d3cbc92013-03-18 22:33:041925 state->SetString("lthi_id", base::StringPrintf("%p", this));
[email protected]c1bb5af2013-03-13 19:06:271926 state->Set("device_viewport_size",
[email protected]fa816c62013-03-18 04:24:211927 MathUtil::AsValue(device_viewport_size_).release());
[email protected]c1bb5af2013-03-13 19:06:271928 if (tile_manager_)
1929 state->Set("tiles", tile_manager_->AllTilesAsValue().release());
1930 state->Set("active_tree", active_tree_->AsValue().release());
1931 return state.PassAs<base::Value>();
[email protected]131a0c22013-02-12 18:31:081932}
1933
[email protected]b9dcf43a2013-01-09 00:15:291934// static
[email protected]c1bb5af2013-03-13 19:06:271935LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive(
1936 LayerImpl* layer) {
1937 if (!layer)
[email protected]b9dcf43a2013-01-09 00:15:291938 return NULL;
[email protected]c1bb5af2013-03-13 19:06:271939
1940 if (layer->DrawsContent())
1941 return layer;
1942
1943 for (LayerImpl::LayerList::const_iterator it = layer->children().begin();
1944 it != layer->children().end(); ++it) {
1945 LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it);
1946 if (nccr)
1947 return nccr;
1948 }
1949
1950 return NULL;
[email protected]b9dcf43a2013-01-09 00:15:291951}
1952
[email protected]c1bb5af2013-03-13 19:06:271953skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() {
1954 LayerTreeImpl* tree =
1955 pending_tree_ ? pending_tree_.get() : active_tree_.get();
1956 LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer());
1957 return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:291958}
1959
[email protected]c1bb5af2013-03-13 19:06:271960void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) {
[email protected]846f455b2013-03-18 19:07:411961 if (debug_state_.continuous_painting != debug_state.continuous_painting)
[email protected]c1bb5af2013-03-13 19:06:271962 paint_time_counter_->ClearHistory();
[email protected]652cf132013-02-15 21:53:241963
[email protected]c1bb5af2013-03-13 19:06:271964 debug_state_ = debug_state;
[email protected]d0d12192013-02-08 19:02:021965
[email protected]c1bb5af2013-03-13 19:06:271966 if (tile_manager_)
[email protected]846f455b2013-03-18 19:07:411967 tile_manager_->SetRecordRenderingStats(debug_state_.RecordRenderingStats());
[email protected]d0d12192013-02-08 19:02:021968}
1969
[email protected]c1bb5af2013-03-13 19:06:271970void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time,
1971 int commit_number) {
[email protected]846f455b2013-03-18 19:07:411972 DCHECK(debug_state_.continuous_painting);
[email protected]c1bb5af2013-03-13 19:06:271973 paint_time_counter_->SavePaintTime(total_paint_time, commit_number);
[email protected]0edbfbe9f2013-01-17 03:33:031974}
1975
[email protected]d3143c732012-10-05 19:17:591976} // namespace cc