blob: 42aa9533c928df6b108bf063cb76bb91c546d130 [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]55a124d02012-10-22 03:07:135#include "cc/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]de4afb5e2012-12-20 00:11:3412#include "base/stl_util.h"
[email protected]aa0a9d32012-10-24 01:58:1013#include "cc/append_quads_data.h"
[email protected]bf189f62012-12-18 03:42:1114#include "cc/compositor_frame_metadata.h"
[email protected]aa0a9d32012-10-24 01:58:1015#include "cc/damage_tracker.h"
16#include "cc/debug_rect_history.h"
17#include "cc/delay_based_time_source.h"
[email protected]ea9d8f22012-12-08 03:39:2918#include "cc/delegating_renderer.h"
[email protected]aa0a9d32012-10-24 01:58:1019#include "cc/frame_rate_counter.h"
[email protected]c4040a522012-10-21 15:01:4020#include "cc/gl_renderer.h"
[email protected]d50c6862012-10-23 02:08:3121#include "cc/heads_up_display_layer_impl.h"
22#include "cc/layer_iterator.h"
23#include "cc/layer_tree_host.h"
24#include "cc/layer_tree_host_common.h"
[email protected]8bef40572012-12-11 21:38:0825#include "cc/layer_tree_impl.h"
[email protected]55a124d02012-10-22 03:07:1326#include "cc/math_util.h"
27#include "cc/overdraw_metrics.h"
28#include "cc/page_scale_animation.h"
[email protected]0edbfbe9f2013-01-17 03:33:0329#include "cc/paint_time_counter.h"
[email protected]3b10a302012-11-07 21:16:4030#include "cc/prioritized_resource_manager.h"
[email protected]f57bbc02012-11-21 07:02:1531#include "cc/quad_culler.h"
[email protected]55a124d02012-10-22 03:07:1332#include "cc/render_pass_draw_quad.h"
[email protected]c4040a522012-10-21 15:01:4033#include "cc/rendering_stats.h"
34#include "cc/scrollbar_animation_controller.h"
35#include "cc/scrollbar_layer_impl.h"
[email protected]f57bbc02012-11-21 07:02:1536#include "cc/shared_quad_state.h"
[email protected]4456eee22012-10-19 18:16:3837#include "cc/single_thread_proxy.h"
[email protected]c4040a522012-10-21 15:01:4038#include "cc/software_renderer.h"
[email protected]f57bbc02012-11-21 07:02:1539#include "cc/solid_color_draw_quad.h"
[email protected]a8461d82012-10-16 21:11:1440#include "cc/texture_uploader.h"
[email protected]3ba4cae2013-01-16 03:58:3841#include "cc/top_controls_manager.h"
[email protected]48871fc2013-01-23 07:36:5142#include "cc/tree_synchronizer.h"
[email protected]d3afa112012-12-08 06:24:2843#include "cc/util.h"
[email protected]d455d552012-11-02 00:19:0644#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1345#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1446
[email protected]94f206c12012-08-25 00:09:1447namespace {
48
[email protected]96baf3e2012-10-22 23:09:5549void didVisibilityChange(cc::LayerTreeHostImpl* id, bool visible)
[email protected]94f206c12012-08-25 00:09:1450{
51 if (visible) {
[email protected]96baf3e2012-10-22 23:09:5552 TRACE_EVENT_ASYNC_BEGIN1("webkit", "LayerTreeHostImpl::setVisible", id, "LayerTreeHostImpl", id);
[email protected]94f206c12012-08-25 00:09:1453 return;
54 }
55
[email protected]96baf3e2012-10-22 23:09:5556 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::setVisible", id);
[email protected]94f206c12012-08-25 00:09:1457}
58
59} // namespace
60
[email protected]9c88e562012-09-14 22:21:3061namespace cc {
[email protected]94f206c12012-08-25 00:09:1462
[email protected]96baf3e2012-10-22 23:09:5563class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]94f206c12012-08-25 00:09:1464public:
[email protected]96baf3e2012-10-22 23:09:5565 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> create(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource)
[email protected]94f206c12012-08-25 00:09:1466 {
[email protected]96baf3e2012-10-22 23:09:5567 return make_scoped_ptr(new LayerTreeHostImplTimeSourceAdapter(layerTreeHostImpl, timeSource));
[email protected]94f206c12012-08-25 00:09:1468 }
[email protected]96baf3e2012-10-22 23:09:5569 virtual ~LayerTreeHostImplTimeSourceAdapter()
[email protected]94f206c12012-08-25 00:09:1470 {
71 m_timeSource->setClient(0);
72 m_timeSource->setActive(false);
73 }
74
75 virtual void onTimerTick() OVERRIDE
76 {
[email protected]373974232013-01-10 22:20:5077 // In single threaded mode we attempt to simulate changing the current
78 // thread by maintaining a fake thread id. When we switch from one
79 // thread to another, we construct DebugScopedSetXXXThread objects that
80 // update the thread id. This lets DCHECKS that ensure we're on the
81 // right thread to work correctly in single threaded mode. The problem
82 // here is that the timer tasks are run via the message loop, and when
83 // they run, we've had no chance to construct a DebugScopedSetXXXThread
84 // object. The result is that we report that we're running on the main
85 // thread. In multi-threaded mode, this timer is run on the compositor
86 // thread, so to keep this consistent in single-threaded mode, we'll
87 // construct a DebugScopedSetImplThread object. There is no need to do
88 // this in multi-threaded mode since the real thread id's will be
89 // correct. In fact, setting fake thread id's interferes with the real
90 // thread id's and causes breakage.
91 scoped_ptr<DebugScopedSetImplThread> setImplThread;
92 if (!m_layerTreeHostImpl->proxy()->hasImplThread())
93 setImplThread.reset(new DebugScopedSetImplThread(m_layerTreeHostImpl->proxy()));
94
[email protected]eabe5002013-01-12 22:07:4895 m_layerTreeHostImpl->activatePendingTreeIfNeeded();
[email protected]30faac92012-10-29 00:06:2996 m_layerTreeHostImpl->animate(base::TimeTicks::Now(), base::Time::Now());
[email protected]94f206c12012-08-25 00:09:1497 }
98
99 void setActive(bool active)
100 {
101 if (active != m_timeSource->active())
102 m_timeSource->setActive(active);
103 }
104
105private:
[email protected]96baf3e2012-10-22 23:09:55106 LayerTreeHostImplTimeSourceAdapter(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource)
[email protected]94f206c12012-08-25 00:09:14107 : m_layerTreeHostImpl(layerTreeHostImpl)
108 , m_timeSource(timeSource)
109 {
110 m_timeSource->setClient(this);
111 }
112
[email protected]96baf3e2012-10-22 23:09:55113 LayerTreeHostImpl* m_layerTreeHostImpl;
114 scoped_refptr<DelayBasedTimeSource> m_timeSource;
[email protected]fd2d4f22012-09-28 22:57:20115
[email protected]96baf3e2012-10-22 23:09:55116 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14117};
118
[email protected]96baf3e2012-10-22 23:09:55119LayerTreeHostImpl::FrameData::FrameData()
[email protected]493067512012-09-19 23:34:10120{
121}
122
[email protected]96baf3e2012-10-22 23:09:55123LayerTreeHostImpl::FrameData::~FrameData()
[email protected]493067512012-09-19 23:34:10124{
125}
126
[email protected]61de5812012-11-08 07:03:44127scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::create(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy)
[email protected]94f206c12012-08-25 00:09:14128{
[email protected]61de5812012-11-08 07:03:44129 return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy));
[email protected]94f206c12012-08-25 00:09:14130}
131
[email protected]61de5812012-11-08 07:03:44132LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy)
[email protected]94f206c12012-08-25 00:09:14133 : m_client(client)
[email protected]61de5812012-11-08 07:03:44134 , m_proxy(proxy)
[email protected]31bfe272012-10-19 18:49:52135 , m_scrollDeltaIsInViewportSpace(false)
[email protected]94f206c12012-08-25 00:09:14136 , m_settings(settings)
[email protected]f511afb2012-11-30 01:55:20137 , m_debugState(settings.initialDebugState)
[email protected]94f206c12012-08-25 00:09:14138 , m_deviceScaleFactor(1)
139 , m_visible(true)
[email protected]3b10a302012-11-07 21:16:40140 , m_managedMemoryPolicy(PrioritizedResourceManager::defaultMemoryAllocationLimit(),
[email protected]9b0b79a02013-01-02 22:47:27141 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
[email protected]a0a00842012-10-22 22:50:28142 0,
[email protected]9b0b79a02013-01-02 22:47:27143 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING)
[email protected]94f206c12012-08-25 00:09:14144 , m_pinchGestureActive(false)
[email protected]61de5812012-11-08 07:03:44145 , m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread()))
[email protected]0edbfbe9f2013-01-17 03:33:03146 , m_paintTimeCounter(PaintTimeCounter::create())
[email protected]96baf3e2012-10-22 23:09:55147 , m_debugRectHistory(DebugRectHistory::create())
[email protected]5c6fe1f82012-10-03 18:00:27148 , m_numImplThreadScrolls(0)
149 , m_numMainThreadScrolls(0)
[email protected]b2136f12012-11-30 02:45:53150 , m_cumulativeNumLayersDrawn(0)
[email protected]f2bbb4e2012-12-07 21:40:49151 , m_cumulativeNumMissingTiles(0)
[email protected]d3afa112012-12-08 06:24:28152 , m_lastSentMemoryVisibleBytes(0)
153 , m_lastSentMemoryVisibleAndNearbyBytes(0)
154 , m_lastSentMemoryUseBytes(0)
[email protected]de4afb5e2012-12-20 00:11:34155 , m_animationRegistrar(AnimationRegistrar::create())
[email protected]94f206c12012-08-25 00:09:14156{
[email protected]61de5812012-11-08 07:03:44157 DCHECK(m_proxy->isImplThread());
[email protected]94f206c12012-08-25 00:09:14158 didVisibilityChange(this, m_visible);
[email protected]3b31c6ac2012-12-06 21:27:29159
[email protected]3ba4cae2013-01-16 03:58:38160 if (settings.calculateTopControlsPosition)
161 m_topControlsManager = TopControlsManager::Create(this, settings.topControlsHeightPx);
162
[email protected]2e7ca422012-12-20 02:57:27163 // LTHI always has an active tree.
[email protected]3b31c6ac2012-12-06 21:27:29164 m_activeTree = LayerTreeImpl::create(this);
[email protected]94f206c12012-08-25 00:09:14165}
166
[email protected]96baf3e2012-10-22 23:09:55167LayerTreeHostImpl::~LayerTreeHostImpl()
[email protected]94f206c12012-08-25 00:09:14168{
[email protected]61de5812012-11-08 07:03:44169 DCHECK(m_proxy->isImplThread());
[email protected]96baf3e2012-10-22 23:09:55170 TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
[email protected]94f206c12012-08-25 00:09:14171
[email protected]de4afb5e2012-12-20 00:11:34172 if (rootLayer()) {
[email protected]94f206c12012-08-25 00:09:14173 clearRenderSurfaces();
[email protected]de4afb5e2012-12-20 00:11:34174 // The layer trees must be destroyed before the layer tree host. We've
175 // made a contract with our animation controllers that the registrar
176 // will outlive them, and we must make good.
[email protected]48871fc2013-01-23 07:36:51177 m_recycleTree.reset();
[email protected]de4afb5e2012-12-20 00:11:34178 m_pendingTree.reset();
[email protected]48871fc2013-01-23 07:36:51179 m_activeTree.reset();
[email protected]de4afb5e2012-12-20 00:11:34180 }
[email protected]94f206c12012-08-25 00:09:14181}
182
[email protected]96baf3e2012-10-22 23:09:55183void LayerTreeHostImpl::beginCommit()
[email protected]94f206c12012-08-25 00:09:14184{
185}
186
[email protected]96baf3e2012-10-22 23:09:55187void LayerTreeHostImpl::commitComplete()
[email protected]94f206c12012-08-25 00:09:14188{
[email protected]96baf3e2012-10-22 23:09:55189 TRACE_EVENT0("cc", "LayerTreeHostImpl::commitComplete");
[email protected]0ede3bb2012-12-09 09:14:39190
191 // Impl-side painting needs an update immediately post-commit to have the
192 // opportunity to create tilings. Other paths can call updateDrawProperties
193 // more lazily when needed prior to drawing.
[email protected]615c78a2013-01-24 23:44:16194 if (m_settings.implSidePainting) {
195 pendingTree()->set_needs_update_draw_properties();
[email protected]4c9bb952013-01-27 05:41:18196 pendingTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:16197 } else {
198 activeTree()->set_needs_update_draw_properties();
199 }
[email protected]0ede3bb2012-12-09 09:14:39200
[email protected]3d21e022012-10-25 20:03:08201 m_client->sendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14202}
203
[email protected]96baf3e2012-10-22 23:09:55204bool LayerTreeHostImpl::canDraw()
[email protected]94f206c12012-08-25 00:09:14205{
[email protected]8db2213c2012-09-05 22:08:21206 // Note: If you are changing this function or any other function that might
207 // affect the result of canDraw, make sure to call m_client->onCanDrawStateChanged
208 // in the proper places and update the notifyIfCanDrawChanged test.
209
[email protected]3b31c6ac2012-12-06 21:27:29210 if (!rootLayer()) {
[email protected]96baf3e2012-10-22 23:09:55211 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no root layer");
[email protected]94f206c12012-08-25 00:09:14212 return false;
213 }
[email protected]aad0a0072012-11-01 18:15:58214 if (deviceViewportSize().IsEmpty()) {
[email protected]96baf3e2012-10-22 23:09:55215 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw empty viewport");
[email protected]94f206c12012-08-25 00:09:14216 return false;
217 }
218 if (!m_renderer) {
[email protected]96baf3e2012-10-22 23:09:55219 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no renderer");
[email protected]94f206c12012-08-25 00:09:14220 return false;
221 }
[email protected]6f90b9e2013-01-17 23:42:00222 if (m_activeTree->ContentsTexturesPurged()) {
[email protected]96baf3e2012-10-22 23:09:55223 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw contents textures purged");
[email protected]94f206c12012-08-25 00:09:14224 return false;
225 }
226 return true;
227}
228
[email protected]3be2171d2012-12-06 06:13:20229OutputSurface* LayerTreeHostImpl::outputSurface() const
[email protected]94f206c12012-08-25 00:09:14230{
[email protected]3be2171d2012-12-06 06:13:20231 return m_outputSurface.get();
[email protected]94f206c12012-08-25 00:09:14232}
233
[email protected]30faac92012-10-29 00:06:29234void LayerTreeHostImpl::animate(base::TimeTicks monotonicTime, base::Time wallClockTime)
[email protected]94f206c12012-08-25 00:09:14235{
236 animatePageScale(monotonicTime);
237 animateLayers(monotonicTime, wallClockTime);
[email protected]94f206c12012-08-25 00:09:14238 animateScrollbars(monotonicTime);
[email protected]3ba4cae2013-01-16 03:58:38239 if (m_topControlsManager)
240 m_topControlsManager->Animate(monotonicTime);
[email protected]94f206c12012-08-25 00:09:14241}
242
[email protected]8947cbe2012-11-28 05:27:43243void LayerTreeHostImpl::manageTiles()
244{
245 DCHECK(m_tileManager);
246 m_tileManager->ManageTiles();
[email protected]9b0b79a02013-01-02 22:47:27247
248 size_t memoryRequiredBytes;
249 size_t memoryNiceToHaveBytes;
250 size_t memoryUsedBytes;
251 m_tileManager->GetMemoryStats(&memoryRequiredBytes,
252 &memoryNiceToHaveBytes,
253 &memoryUsedBytes);
254 sendManagedMemoryStats(memoryRequiredBytes,
255 memoryNiceToHaveBytes,
256 memoryUsedBytes);
[email protected]8947cbe2012-11-28 05:27:43257}
258
[email protected]69a2a5be2012-11-14 06:51:44259void LayerTreeHostImpl::startPageScaleAnimation(gfx::Vector2d targetOffset, bool anchorPoint, float pageScale, base::TimeTicks startTime, base::TimeDelta duration)
[email protected]94f206c12012-08-25 00:09:14260{
[email protected]3b31c6ac2012-12-06 21:27:29261 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:14262 return;
263
[email protected]3b31c6ac2012-12-06 21:27:29264 gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]42ccdbef2013-01-21 07:54:54265 gfx::SizeF scaledScrollableSize = activeTree()->ScrollableSize();
[email protected]9bdcfd642012-11-14 21:24:26266 if (!m_settings.pageScalePinchZoomEnabled) {
[email protected]a823df82013-01-10 02:38:17267 scrollTotal.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]42ccdbef2013-01-21 07:54:54268 scaledScrollableSize.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]f6250742012-11-09 04:46:56269 }
[email protected]01a15a72012-11-10 09:34:28270 gfx::SizeF viewportSize = gfx::ScaleSize(m_deviceViewportSize, 1 / m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:14271
[email protected]30faac92012-10-29 00:06:29272 double startTimeSeconds = (startTime - base::TimeTicks()).InSecondsF();
[email protected]42ccdbef2013-01-21 07:54:54273 m_pageScaleAnimation = PageScaleAnimation::create(scrollTotal, m_pinchZoomViewport.total_page_scale_factor(), viewportSize, scaledScrollableSize, startTimeSeconds);
[email protected]94f206c12012-08-25 00:09:14274
275 if (anchorPoint) {
[email protected]69a2a5be2012-11-14 06:51:44276 gfx::Vector2dF anchor(targetOffset);
[email protected]9bdcfd642012-11-14 21:24:26277 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]f6250742012-11-09 04:46:56278 anchor.Scale(1 / pageScale);
279 m_pageScaleAnimation->zoomWithAnchor(anchor, pageScale, duration.InSecondsF());
280 } else {
[email protected]69a2a5be2012-11-14 06:51:44281 gfx::Vector2dF scaledTargetOffset = targetOffset;
[email protected]9bdcfd642012-11-14 21:24:26282 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]69a2a5be2012-11-14 06:51:44283 scaledTargetOffset.Scale(1 / pageScale);
284 m_pageScaleAnimation->zoomTo(scaledTargetOffset, pageScale, duration.InSecondsF());
[email protected]f6250742012-11-09 04:46:56285 }
[email protected]94f206c12012-08-25 00:09:14286
287 m_client->setNeedsRedrawOnImplThread();
288 m_client->setNeedsCommitOnImplThread();
289}
290
[email protected]96baf3e2012-10-22 23:09:55291void LayerTreeHostImpl::scheduleAnimation()
[email protected]94f206c12012-08-25 00:09:14292{
293 m_client->setNeedsRedrawOnImplThread();
294}
295
[email protected]2f1acc262012-11-16 21:42:22296bool LayerTreeHostImpl::haveTouchEventHandlersAt(const gfx::Point& viewportPoint)
297{
[email protected]df8f44f2013-01-08 08:00:31298 if (!ensureRenderSurfaceLayerList())
299 return false;
[email protected]2f1acc262012-11-16 21:42:22300
301 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceScaleFactor);
302
303 // First find out which layer was hit from the saved list of visible layers
304 // in the most recent frame.
[email protected]76ffd9e2012-12-20 19:12:47305 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(deviceViewportPoint, activeTree()->RenderSurfaceLayerList());
[email protected]2f1acc262012-11-16 21:42:22306
[email protected]35d2edd22012-12-13 02:19:05307 // Walk up the hierarchy and look for a layer with a touch event handler region that the given point hits.
308 for (; layerImpl; layerImpl = layerImpl->parent()) {
309 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(deviceViewportPoint,layerImpl))
310 return true;
311 }
[email protected]2f1acc262012-11-16 21:42:22312
313 return false;
314}
315
[email protected]96baf3e2012-10-22 23:09:55316void LayerTreeHostImpl::trackDamageForAllSurfaces(LayerImpl* rootDrawLayer, const LayerList& renderSurfaceLayerList)
[email protected]94f206c12012-08-25 00:09:14317{
318 // For now, we use damage tracking to compute a global scissor. To do this, we must
319 // compute all damage tracking before drawing anything, so that we know the root
320 // damage rect. The root damage rect is then used to scissor each surface.
321
322 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
[email protected]96baf3e2012-10-22 23:09:55323 LayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
324 RenderSurfaceImpl* renderSurface = renderSurfaceLayer->renderSurface();
[email protected]1d993172012-10-18 18:15:04325 DCHECK(renderSurface);
[email protected]1940c4e2012-12-04 05:08:15326 renderSurface->damageTracker()->updateDamageTrackingState(renderSurface->layerList(), renderSurfaceLayer->id(), renderSurface->surfacePropertyChangedOnlyFromDescendant(), renderSurface->contentRect(), renderSurfaceLayer->maskLayer(), renderSurfaceLayer->filters(), renderSurfaceLayer->filter().get());
[email protected]94f206c12012-08-25 00:09:14327 }
328}
329
[email protected]96baf3e2012-10-22 23:09:55330void LayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<RenderPass> renderPass)
[email protected]467b3612012-08-28 07:41:16331{
[email protected]20062042012-12-21 22:16:36332 renderPassesById[renderPass->id] = renderPass.get();
[email protected]ead39c52013-01-09 07:22:45333 renderPasses.push_back(renderPass.Pass());
[email protected]f57bbc02012-11-21 07:02:15334}
335
336static void appendQuadsForLayer(RenderPass* targetRenderPass, LayerImpl* layer, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData)
337{
338 bool forSurface = false;
339 QuadCuller quadCuller(targetRenderPass->quad_list,
340 targetRenderPass->shared_quad_state_list,
341 layer,
342 occlusionTracker,
343 layer->showDebugBorders(),
344 forSurface);
345 layer->appendQuads(quadCuller, appendQuadsData);
346}
347
348static void appendQuadsForRenderSurfaceLayer(RenderPass* targetRenderPass, LayerImpl* layer, const RenderPass* contributingRenderPass, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData)
349{
350 bool forSurface = true;
351 QuadCuller quadCuller(targetRenderPass->quad_list,
352 targetRenderPass->shared_quad_state_list,
353 layer,
354 occlusionTracker,
355 layer->showDebugBorders(),
356 forSurface);
357
358 bool isReplica = false;
359 layer->renderSurface()->appendQuads(quadCuller,
360 appendQuadsData,
361 isReplica,
362 contributingRenderPass->id);
363
364 // Add replica after the surface so that it appears below the surface.
365 if (layer->hasReplica()) {
366 isReplica = true;
367 layer->renderSurface()->appendQuads(quadCuller,
368 appendQuadsData,
369 isReplica,
370 contributingRenderPass->id);
371 }
372}
373
374static void appendQuadsToFillScreen(RenderPass* targetRenderPass, LayerImpl* rootLayer, SkColor screenBackgroundColor, const OcclusionTrackerImpl& occlusionTracker)
375{
376 if (!rootLayer || !SkColorGetA(screenBackgroundColor))
377 return;
378
379 Region fillRegion = occlusionTracker.computeVisibleRegionInScreen();
380 if (fillRegion.IsEmpty())
381 return;
382
383 bool forSurface = false;
384 QuadCuller quadCuller(targetRenderPass->quad_list,
385 targetRenderPass->shared_quad_state_list,
386 rootLayer,
387 occlusionTracker,
388 rootLayer->showDebugBorders(),
389 forSurface);
390
391 // Manually create the quad state for the gutter quads, as the root layer
392 // doesn't have any bounds and so can't generate this itself.
393 // FIXME: Make the gutter quads generated by the solid color layer (make it smarter about generating quads to fill unoccluded areas).
394
[email protected]f57bbc02012-11-21 07:02:15395 gfx::Rect rootTargetRect = rootLayer->renderSurface()->contentRect();
396 float opacity = 1;
397 SharedQuadState* sharedQuadState = quadCuller.useSharedQuadState(SharedQuadState::Create());
398 sharedQuadState->SetAll(rootLayer->drawTransform(),
399 rootTargetRect,
400 rootTargetRect,
[email protected]dc462d782012-11-21 21:43:01401 false,
[email protected]f57bbc02012-11-21 07:02:15402 opacity);
403
404 AppendQuadsData appendQuadsData;
[email protected]bda41962013-01-07 18:46:17405
406 gfx::Transform transformToLayerSpace(gfx::Transform::kSkipInitialization);
407 bool didInvert = rootLayer->screenSpaceTransform().GetInverse(&transformToLayerSpace);
408 DCHECK(didInvert);
[email protected]f57bbc02012-11-21 07:02:15409 for (Region::Iterator fillRects(fillRegion); fillRects.has_rect(); fillRects.next()) {
410 // The root layer transform is composed of translations and scales only,
[email protected]bda41962013-01-07 18:46:17411 // no perspective, so mapping is sufficient (as opposed to projecting).
[email protected]f57bbc02012-11-21 07:02:15412 gfx::Rect layerRect = MathUtil::mapClippedRect(transformToLayerSpace, fillRects.rect());
413 // Skip the quad culler and just append the quads directly to avoid
414 // occlusion checks.
415 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
416 quad->SetNew(sharedQuadState, layerRect, screenBackgroundColor);
417 quadCuller.append(quad.PassAs<DrawQuad>(), appendQuadsData);
418 }
[email protected]467b3612012-08-28 07:41:16419}
420
[email protected]96baf3e2012-10-22 23:09:55421bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14422{
[email protected]ead39c52013-01-09 07:22:45423 DCHECK(frame.renderPasses.empty());
[email protected]94f206c12012-08-25 00:09:14424
[email protected]2e7ca422012-12-20 02:57:27425 if (!canDraw() || !rootLayer())
[email protected]2d692992012-12-19 01:19:32426 return false;
427
[email protected]0ede3bb2012-12-09 09:14:39428 trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList);
[email protected]94f206c12012-08-25 00:09:14429
[email protected]96baf3e2012-10-22 23:09:55430 TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList->size()));
[email protected]94f206c12012-08-25 00:09:14431
432 // Create the render passes in dependency order.
[email protected]94f206c12012-08-25 00:09:14433 for (int surfaceIndex = frame.renderSurfaceLayerList->size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
[email protected]96baf3e2012-10-22 23:09:55434 LayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceIndex];
[email protected]467b3612012-08-28 07:41:16435 renderSurfaceLayer->renderSurface()->appendRenderPasses(frame);
[email protected]94f206c12012-08-25 00:09:14436 }
437
[email protected]9bdcfd642012-11-14 21:24:26438 bool recordMetricsForFrame = m_settings.showOverdrawInTracing && base::debug::TraceLog::GetInstance() && base::debug::TraceLog::GetInstance()->IsEnabled();
[email protected]3b31c6ac2012-12-06 21:27:29439 OcclusionTrackerImpl occlusionTracker(rootLayer()->renderSurface()->contentRect(), recordMetricsForFrame);
[email protected]94f206c12012-08-25 00:09:14440 occlusionTracker.setMinimumTrackingSize(m_settings.minimumOcclusionTrackingSize);
441
[email protected]f511afb2012-11-30 01:55:20442 if (m_debugState.showOccludingRects)
[email protected]94f206c12012-08-25 00:09:14443 occlusionTracker.setOccludingScreenSpaceRectsContainer(&frame.occludingScreenSpaceRects);
[email protected]f511afb2012-11-30 01:55:20444 if (m_debugState.showNonOccludingRects)
[email protected]4d8804e2012-11-15 01:51:10445 occlusionTracker.setNonOccludingScreenSpaceRectsContainer(&frame.nonOccludingScreenSpaceRects);
[email protected]94f206c12012-08-25 00:09:14446
447 // Add quads to the Render passes in FrontToBack order to allow for testing occlusion and performing culling during the tree walk.
[email protected]96baf3e2012-10-22 23:09:55448 typedef LayerIterator<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14449
450 // Typically when we are missing a texture and use a checkerboard quad, we still draw the frame. However when the layer being
451 // checkerboarded is moving due to an impl-animation, we drop the frame to avoid flashing due to the texture suddenly appearing
452 // in the future.
453 bool drawFrame = true;
454
[email protected]96baf3e2012-10-22 23:09:55455 LayerIteratorType end = LayerIteratorType::end(frame.renderSurfaceLayerList);
456 for (LayerIteratorType it = LayerIteratorType::begin(frame.renderSurfaceLayerList); it != end; ++it) {
457 RenderPass::Id targetRenderPassId = it.targetRenderSurfaceLayer()->renderSurface()->renderPassId();
[email protected]20062042012-12-21 22:16:36458 RenderPass* targetRenderPass = frame.renderPassesById[targetRenderPassId];
[email protected]94f206c12012-08-25 00:09:14459
460 occlusionTracker.enterLayer(it);
461
[email protected]f57bbc02012-11-21 07:02:15462 AppendQuadsData appendQuadsData(targetRenderPass->id);
[email protected]89228202012-08-29 03:20:30463
[email protected]94f206c12012-08-25 00:09:14464 if (it.representsContributingRenderSurface()) {
[email protected]96baf3e2012-10-22 23:09:55465 RenderPass::Id contributingRenderPassId = it->renderSurface()->renderPassId();
[email protected]20062042012-12-21 22:16:36466 RenderPass* contributingRenderPass = frame.renderPassesById[contributingRenderPassId];
[email protected]f57bbc02012-11-21 07:02:15467 appendQuadsForRenderSurfaceLayer(targetRenderPass, *it, contributingRenderPass, occlusionTracker, appendQuadsData);
[email protected]aad0a0072012-11-01 18:15:58468 } else if (it.representsItself() && !it->visibleContentRect().IsEmpty()) {
[email protected]94f206c12012-08-25 00:09:14469 bool hasOcclusionFromOutsideTargetSurface;
[email protected]710ffc02012-10-30 21:42:02470 bool implDrawTransformIsUnknown = false;
[email protected]c8d71552013-01-22 03:43:02471 if (occlusionTracker.occluded(it->renderTarget(), it->visibleContentRect(), it->drawTransform(), implDrawTransformIsUnknown, it->isClipped(), it->clipRect(), &hasOcclusionFromOutsideTargetSurface))
[email protected]89228202012-08-29 03:20:30472 appendQuadsData.hadOcclusionFromOutsideTargetSurface |= hasOcclusionFromOutsideTargetSurface;
473 else {
[email protected]2e7ca422012-12-20 02:57:27474 DCHECK_EQ(activeTree(), it->layerTreeImpl());
[email protected]94f206c12012-08-25 00:09:14475 it->willDraw(m_resourceProvider.get());
[email protected]d58499a2012-10-09 22:27:47476 frame.willDrawLayers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57477
478 if (it->hasContributingDelegatedRenderPasses()) {
[email protected]96baf3e2012-10-22 23:09:55479 RenderPass::Id contributingRenderPassId = it->firstContributingRenderPassId();
[email protected]20062042012-12-21 22:16:36480 while (frame.renderPassesById.find(contributingRenderPassId) != frame.renderPassesById.end()) {
481 RenderPass* renderPass = frame.renderPassesById[contributingRenderPassId];
[email protected]7d929c02012-09-20 17:26:57482
[email protected]f57bbc02012-11-21 07:02:15483 AppendQuadsData appendQuadsData(renderPass->id);
484 appendQuadsForLayer(renderPass, *it, occlusionTracker, appendQuadsData);
[email protected]7d929c02012-09-20 17:26:57485
486 contributingRenderPassId = it->nextContributingRenderPassId(contributingRenderPassId);
487 }
488 }
489
[email protected]f57bbc02012-11-21 07:02:15490 appendQuadsForLayer(targetRenderPass, *it, occlusionTracker, appendQuadsData);
[email protected]94f206c12012-08-25 00:09:14491 }
[email protected]9c2be6a2012-11-27 19:16:10492
[email protected]b2136f12012-11-30 02:45:53493 ++m_cumulativeNumLayersDrawn;
[email protected]94f206c12012-08-25 00:09:14494 }
495
[email protected]89228202012-08-29 03:20:30496 if (appendQuadsData.hadOcclusionFromOutsideTargetSurface)
[email protected]f57bbc02012-11-21 07:02:15497 targetRenderPass->has_occlusion_from_outside_target_surface = true;
[email protected]89228202012-08-29 03:20:30498
[email protected]f2bbb4e2012-12-07 21:40:49499 if (appendQuadsData.numMissingTiles) {
500 m_cumulativeNumMissingTiles += appendQuadsData.numMissingTiles;
[email protected]94f206c12012-08-25 00:09:14501 bool layerHasAnimatingTransform = it->screenSpaceTransformIsAnimating() || it->drawTransformIsAnimating();
[email protected]22619922012-11-14 17:58:10502 if (layerHasAnimatingTransform)
[email protected]94f206c12012-08-25 00:09:14503 drawFrame = false;
504 }
505
506 occlusionTracker.leaveLayer(it);
507 }
508
[email protected]1d993172012-10-18 18:15:04509#ifndef NDEBUG
[email protected]94f206c12012-08-25 00:09:14510 for (size_t i = 0; i < frame.renderPasses.size(); ++i) {
[email protected]f57bbc02012-11-21 07:02:15511 for (size_t j = 0; j < frame.renderPasses[i]->quad_list.size(); ++j)
512 DCHECK(frame.renderPasses[i]->quad_list[j]->shared_quad_state);
[email protected]20062042012-12-21 22:16:36513 DCHECK(frame.renderPassesById.find(frame.renderPasses[i]->id)
514 != frame.renderPassesById.end());
[email protected]94f206c12012-08-25 00:09:14515 }
516#endif
[email protected]217a89a2013-01-20 19:55:39517 DCHECK(frame.renderPasses.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14518
[email protected]a30290142013-01-05 01:27:00519 if (!activeTree()->has_transparent_background()) {
[email protected]ead39c52013-01-09 07:22:45520 frame.renderPasses.back()->has_transparent_background = false;
521 appendQuadsToFillScreen(frame.renderPasses.back(), rootLayer(), activeTree()->background_color(), occlusionTracker);
[email protected]94f206c12012-08-25 00:09:14522 }
523
524 if (drawFrame)
525 occlusionTracker.overdrawMetrics().recordMetrics(this);
526
527 removeRenderPasses(CullRenderPassesWithNoQuads(), frame);
528 m_renderer->decideRenderPassAllocationsForFrame(frame.renderPasses);
529 removeRenderPasses(CullRenderPassesWithCachedTextures(*m_renderer), frame);
530
531 return drawFrame;
532}
533
[email protected]96baf3e2012-10-22 23:09:55534void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled)
[email protected]94f206c12012-08-25 00:09:14535{
536 // Lazily create the timeSource adapter so that we can vary the interval for testing.
537 if (!m_timeSourceClientAdapter)
[email protected]61de5812012-11-08 07:03:44538 m_timeSourceClientAdapter = LayerTreeHostImplTimeSourceAdapter::create(this, DelayBasedTimeSource::create(lowFrequencyAnimationInterval(), m_proxy->currentThread()));
[email protected]94f206c12012-08-25 00:09:14539
540 m_timeSourceClientAdapter->setActive(enabled);
541}
542
[email protected]96baf3e2012-10-22 23:09:55543static inline RenderPass* findRenderPassById(RenderPass::Id renderPassId, const LayerTreeHostImpl::FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14544{
[email protected]96baf3e2012-10-22 23:09:55545 RenderPassIdHashMap::const_iterator it = frame.renderPassesById.find(renderPassId);
[email protected]20062042012-12-21 22:16:36546 return it != frame.renderPassesById.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14547}
548
[email protected]96baf3e2012-10-22 23:09:55549static void removeRenderPassesRecursive(RenderPass::Id removeRenderPassId, LayerTreeHostImpl::FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14550{
[email protected]96baf3e2012-10-22 23:09:55551 RenderPass* removeRenderPass = findRenderPassById(removeRenderPassId, frame);
[email protected]20062042012-12-21 22:16:36552 // The pass was already removed by another quad - probably the original, and we are the replica.
553 if (!removeRenderPass)
554 return;
[email protected]96baf3e2012-10-22 23:09:55555 RenderPassList& renderPasses = frame.renderPasses;
556 RenderPassList::iterator toRemove = std::find(renderPasses.begin(), renderPasses.end(), removeRenderPass);
[email protected]94f206c12012-08-25 00:09:14557
[email protected]20062042012-12-21 22:16:36558 DCHECK(toRemove != renderPasses.end());
[email protected]94f206c12012-08-25 00:09:14559
[email protected]ead39c52013-01-09 07:22:45560 scoped_ptr<RenderPass> removedPass = renderPasses.take(toRemove);
561 frame.renderPasses.erase(toRemove);
[email protected]20062042012-12-21 22:16:36562 frame.renderPassesById.erase(removeRenderPassId);
[email protected]94f206c12012-08-25 00:09:14563
564 // Now follow up for all RenderPass quads and remove their RenderPasses recursively.
[email protected]f57bbc02012-11-21 07:02:15565 const QuadList& quadList = removedPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55566 QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14567 for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
[email protected]96baf3e2012-10-22 23:09:55568 DrawQuad* currentQuad = (*quadListIterator);
[email protected]1bc93f62012-11-17 19:29:50569 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14570 continue;
571
[email protected]c22418b2012-11-20 23:06:26572 RenderPass::Id nextRemoveRenderPassId = RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id;
[email protected]94f206c12012-08-25 00:09:14573 removeRenderPassesRecursive(nextRemoveRenderPassId, frame);
574 }
575}
576
[email protected]96baf3e2012-10-22 23:09:55577bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData&) const
[email protected]94f206c12012-08-25 00:09:14578{
[email protected]ec2eb5f2012-12-16 04:42:27579 if (!quad.contents_changed_since_last_frame.IsEmpty()) {
580 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
581 return false;
582 } else if (!m_renderer.haveCachedResourcesForRenderPassId(quad.render_pass_id)) {
583 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
584 return false;
585 }
586 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
587 return true;
[email protected]94f206c12012-08-25 00:09:14588}
589
[email protected]96baf3e2012-10-22 23:09:55590bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData& frame) const
[email protected]94f206c12012-08-25 00:09:14591{
[email protected]c22418b2012-11-20 23:06:26592 const RenderPass* renderPass = findRenderPassById(quad.render_pass_id, frame);
[email protected]20062042012-12-21 22:16:36593 if (!renderPass)
[email protected]94f206c12012-08-25 00:09:14594 return false;
595
596 // If any quad or RenderPass draws into this RenderPass, then keep it.
[email protected]20062042012-12-21 22:16:36597 const QuadList& quadList = renderPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55598 for (QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
599 DrawQuad* currentQuad = *quadListIterator;
[email protected]94f206c12012-08-25 00:09:14600
[email protected]1bc93f62012-11-17 19:29:50601 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14602 return false;
603
[email protected]c22418b2012-11-20 23:06:26604 const RenderPass* contributingPass = findRenderPassById(RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id, frame);
[email protected]20062042012-12-21 22:16:36605 if (contributingPass)
[email protected]94f206c12012-08-25 00:09:14606 return false;
607 }
608 return true;
609}
610
611// Defined for linking tests.
[email protected]52347c842012-11-02 21:06:20612template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(CullRenderPassesWithCachedTextures, FrameData&);
613template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithNoQuads>(CullRenderPassesWithNoQuads, FrameData&);
[email protected]94f206c12012-08-25 00:09:14614
615// static
616template<typename RenderPassCuller>
[email protected]96baf3e2012-10-22 23:09:55617void LayerTreeHostImpl::removeRenderPasses(RenderPassCuller culler, FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14618{
619 for (size_t it = culler.renderPassListBegin(frame.renderPasses); it != culler.renderPassListEnd(frame.renderPasses); it = culler.renderPassListNext(it)) {
[email protected]96baf3e2012-10-22 23:09:55620 const RenderPass* currentPass = frame.renderPasses[it];
[email protected]f57bbc02012-11-21 07:02:15621 const QuadList& quadList = currentPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55622 QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14623
624 for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
[email protected]96baf3e2012-10-22 23:09:55625 DrawQuad* currentQuad = *quadListIterator;
[email protected]94f206c12012-08-25 00:09:14626
[email protected]1bc93f62012-11-17 19:29:50627 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14628 continue;
629
[email protected]96baf3e2012-10-22 23:09:55630 RenderPassDrawQuad* renderPassQuad = static_cast<RenderPassDrawQuad*>(currentQuad);
[email protected]94f206c12012-08-25 00:09:14631 if (!culler.shouldRemoveRenderPass(*renderPassQuad, frame))
632 continue;
633
634 // We are changing the vector in the middle of iteration. Because we
635 // delete render passes that draw into the current pass, we are
636 // guaranteed that any data from the iterator to the end will not
637 // change. So, capture the iterator position from the end of the
638 // list, and restore it after the change.
639 int positionFromEnd = frame.renderPasses.size() - it;
[email protected]c22418b2012-11-20 23:06:26640 removeRenderPassesRecursive(renderPassQuad->render_pass_id, frame);
[email protected]94f206c12012-08-25 00:09:14641 it = frame.renderPasses.size() - positionFromEnd;
[email protected]1d993172012-10-18 18:15:04642 DCHECK(it >= 0);
[email protected]94f206c12012-08-25 00:09:14643 }
644 }
645}
646
[email protected]96baf3e2012-10-22 23:09:55647bool LayerTreeHostImpl::prepareToDraw(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14648{
[email protected]96baf3e2012-10-22 23:09:55649 TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw");
[email protected]94f206c12012-08-25 00:09:14650
[email protected]615c78a2013-01-24 23:44:16651 if (m_topControlsManager)
652 m_topControlsManager->UpdateDrawPositions();
[email protected]4c9bb952013-01-27 05:41:18653 activeTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW);
[email protected]2e7ca422012-12-20 02:57:27654
[email protected]76ffd9e2012-12-20 19:12:47655 frame.renderSurfaceLayerList = &activeTree()->RenderSurfaceLayerList();
[email protected]94f206c12012-08-25 00:09:14656 frame.renderPasses.clear();
657 frame.renderPassesById.clear();
[email protected]94f206c12012-08-25 00:09:14658 frame.willDrawLayers.clear();
659
660 if (!calculateRenderPasses(frame))
661 return false;
662
663 // If we return true, then we expect drawLayers() to be called before this function is called again.
664 return true;
665}
666
[email protected]96baf3e2012-10-22 23:09:55667void LayerTreeHostImpl::enforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy)
[email protected]94f206c12012-08-25 00:09:14668{
[email protected]a0a00842012-10-22 22:50:28669 bool evictedResources = m_client->reduceContentsTextureMemoryOnImplThread(
670 m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible,
[email protected]9b0b79a02013-01-02 22:47:27671 ManagedMemoryPolicy::priorityCutoffToValue(
672 m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible));
[email protected]b1969fa2012-10-17 20:16:29673 if (evictedResources) {
[email protected]6f90b9e2013-01-17 23:42:00674 activeTree()->SetContentsTexturesPurged();
675 if (pendingTree())
676 pendingTree()->SetContentsTexturesPurged();
[email protected]b1969fa2012-10-17 20:16:29677 m_client->setNeedsCommitOnImplThread();
678 m_client->onCanDrawStateChanged(canDraw());
[email protected]362f1e8b2013-01-21 16:54:30679 m_client->renewTreePriority();
[email protected]b1969fa2012-10-17 20:16:29680 }
[email protected]3d21e022012-10-25 20:03:08681 m_client->sendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43682
683 if (m_tileManager) {
[email protected]8947cbe2012-11-28 05:27:43684 GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState());
[email protected]9b0b79a02013-01-02 22:47:27685 new_state.memory_limit_in_bytes = m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible;
686 new_state.memory_limit_policy = ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy(
687 m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible);
[email protected]8947cbe2012-11-28 05:27:43688 m_tileManager->SetGlobalState(new_state);
689 }
[email protected]94f206c12012-08-25 00:09:14690}
691
[email protected]61de5812012-11-08 07:03:44692bool LayerTreeHostImpl::hasImplThread() const
693{
694 return m_proxy->hasImplThread();
695}
696
[email protected]8947cbe2012-11-28 05:27:43697void LayerTreeHostImpl::ScheduleManageTiles()
698{
699 if (m_client)
700 m_client->setNeedsManageTilesOnImplThread();
701}
702
[email protected]74d9063c2013-01-18 03:14:47703void LayerTreeHostImpl::DidUploadVisibleHighResolutionTile()
704{
705 if (m_client)
[email protected]6367cda2013-01-23 00:21:13706 m_client->didUploadVisibleHighResolutionTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47707}
708
[email protected]f35e2322012-12-15 21:45:52709bool LayerTreeHostImpl::shouldClearRootRenderPass() const
710{
711 return m_settings.shouldClearRootRenderPass;
712}
713
[email protected]96baf3e2012-10-22 23:09:55714void LayerTreeHostImpl::setManagedMemoryPolicy(const ManagedMemoryPolicy& policy)
[email protected]94f206c12012-08-25 00:09:14715{
[email protected]a0a00842012-10-22 22:50:28716 if (m_managedMemoryPolicy == policy)
[email protected]94f206c12012-08-25 00:09:14717 return;
[email protected]61de5812012-11-08 07:03:44718
[email protected]a0a00842012-10-22 22:50:28719 m_managedMemoryPolicy = policy;
[email protected]61de5812012-11-08 07:03:44720 if (!m_proxy->hasImplThread()) {
721 // FIXME: In single-thread mode, this can be called on the main thread
722 // by GLRenderer::onMemoryAllocationChanged.
723 DebugScopedSetImplThread implThread(m_proxy);
724 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
725 } else {
726 DCHECK(m_proxy->isImplThread());
727 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
728 }
[email protected]a0a00842012-10-22 22:50:28729 // We always need to commit after changing the memory policy because the new
730 // limit can result in more or less content having texture allocated for it.
[email protected]94f206c12012-08-25 00:09:14731 m_client->setNeedsCommitOnImplThread();
732}
733
[email protected]a46f32932012-12-07 21:43:16734void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval)
[email protected]94f206c12012-08-25 00:09:14735{
[email protected]30faac92012-10-29 00:06:29736 m_client->onVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14737}
738
[email protected]b6f3d7e2012-12-08 00:11:21739void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack)
[email protected]a46f32932012-12-07 21:43:16740{
[email protected]b6f3d7e2012-12-08 00:11:21741 if (!m_renderer)
742 return;
743
744 // TODO(piman): We may need to do some validation on this ack before processing it.
745 m_renderer->receiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16746}
747
[email protected]3b31c6ac2012-12-06 21:27:29748void LayerTreeHostImpl::OnCanDrawStateChangedForTree(LayerTreeImpl*)
749{
[email protected]a46f32932012-12-07 21:43:16750 m_client->onCanDrawStateChanged(canDraw());
[email protected]3b31c6ac2012-12-06 21:27:29751}
752
[email protected]bf189f62012-12-18 03:42:11753CompositorFrameMetadata LayerTreeHostImpl::makeCompositorFrameMetadata() const
754{
[email protected]bf189f62012-12-18 03:42:11755 CompositorFrameMetadata metadata;
[email protected]a823df82013-01-10 02:38:17756 metadata.page_scale_factor = m_pinchZoomViewport.total_page_scale_factor();
[email protected]42ccdbef2013-01-21 07:54:54757 metadata.viewport_size = m_pinchZoomViewport.ZoomedViewport().size();
758 metadata.root_layer_size = activeTree()->ScrollableSize();
[email protected]a823df82013-01-10 02:38:17759 metadata.min_page_scale_factor = m_pinchZoomViewport.min_page_scale_factor();
760 metadata.max_page_scale_factor = m_pinchZoomViewport.max_page_scale_factor();
[email protected]3ba4cae2013-01-16 03:58:38761 if (m_topControlsManager) {
762 metadata.location_bar_offset = gfx::Vector2dF(0.f, m_topControlsManager->controls_top_offset());
763 metadata.location_bar_content_translation = gfx::Vector2dF(0.f, m_topControlsManager->content_top_offset());
764 }
[email protected]bf189f62012-12-18 03:42:11765
[email protected]05469632013-01-16 03:41:00766 if (!rootScrollLayer())
767 return metadata;
768
769 metadata.root_scroll_offset = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
770 if (!m_settings.pageScalePinchZoomEnabled)
771 metadata.root_scroll_offset.Scale(1 / m_pinchZoomViewport.page_scale_factor());
772
[email protected]bf189f62012-12-18 03:42:11773 return metadata;
774}
775
[email protected]85167c72012-12-04 03:56:07776void LayerTreeHostImpl::drawLayers(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14777{
[email protected]96baf3e2012-10-22 23:09:55778 TRACE_EVENT0("cc", "LayerTreeHostImpl::drawLayers");
[email protected]1d993172012-10-18 18:15:04779 DCHECK(canDraw());
[email protected]ead39c52013-01-09 07:22:45780 DCHECK(!frame.renderPasses.empty());
[email protected]94f206c12012-08-25 00:09:14781
782 // FIXME: use the frame begin time from the overall compositor scheduler.
783 // This value is currently inaccessible because it is up in Chromium's
784 // RenderWidget.
[email protected]d03b5c262013-01-16 04:06:18785 m_fpsCounter->saveTimeStamp(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:14786
[email protected]f511afb2012-11-30 01:55:20787 if (m_debugState.showHudRects())
[email protected]3b31c6ac2012-12-06 21:27:29788 m_debugRectHistory->saveDebugRectsForCurrentFrame(rootLayer(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, frame.nonOccludingScreenSpaceRects, m_debugState);
[email protected]94f206c12012-08-25 00:09:14789
790 // Because the contents of the HUD depend on everything else in the frame, the contents
791 // of its texture are updated as the last thing before the frame is drawn.
[email protected]3b31c6ac2012-12-06 21:27:29792 if (m_activeTree->hud_layer())
793 m_activeTree->hud_layer()->updateHudTexture(m_resourceProvider.get());
[email protected]94f206c12012-08-25 00:09:14794
[email protected]20062042012-12-21 22:16:36795 m_renderer->drawFrame(frame.renderPasses);
[email protected]85167c72012-12-04 03:56:07796 // The render passes should be consumed by the renderer.
[email protected]ead39c52013-01-09 07:22:45797 DCHECK(frame.renderPasses.empty());
[email protected]20062042012-12-21 22:16:36798 frame.renderPassesById.clear();
[email protected]94f206c12012-08-25 00:09:14799
800 // The next frame should start by assuming nothing has changed, and changes are noted as they occur.
801 for (unsigned int i = 0; i < frame.renderSurfaceLayerList->size(); i++)
802 (*frame.renderSurfaceLayerList)[i]->renderSurface()->damageTracker()->didDrawDamagedArea();
[email protected]3b31c6ac2012-12-06 21:27:29803 rootLayer()->resetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:14804}
805
[email protected]96baf3e2012-10-22 23:09:55806void LayerTreeHostImpl::didDrawAllLayers(const FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14807{
808 for (size_t i = 0; i < frame.willDrawLayers.size(); ++i)
809 frame.willDrawLayers[i]->didDraw(m_resourceProvider.get());
[email protected]b914e102012-10-02 08:11:52810
811 // Once all layers have been drawn, pending texture uploads should no
812 // longer block future uploads.
[email protected]e2249592012-10-19 06:59:09813 m_resourceProvider->markPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:14814}
815
[email protected]96baf3e2012-10-22 23:09:55816void LayerTreeHostImpl::finishAllRendering()
[email protected]94f206c12012-08-25 00:09:14817{
818 if (m_renderer)
819 m_renderer->finish();
820}
821
[email protected]96baf3e2012-10-22 23:09:55822bool LayerTreeHostImpl::isContextLost()
[email protected]94f206c12012-08-25 00:09:14823{
[email protected]e01dddb12013-01-23 03:57:08824 DCHECK(m_proxy->isImplThread());
[email protected]94f206c12012-08-25 00:09:14825 return m_renderer && m_renderer->isContextLost();
826}
827
[email protected]96baf3e2012-10-22 23:09:55828const RendererCapabilities& LayerTreeHostImpl::rendererCapabilities() const
[email protected]94f206c12012-08-25 00:09:14829{
830 return m_renderer->capabilities();
831}
832
[email protected]96baf3e2012-10-22 23:09:55833bool LayerTreeHostImpl::swapBuffers()
[email protected]94f206c12012-08-25 00:09:14834{
[email protected]1d993172012-10-18 18:15:04835 DCHECK(m_renderer);
[email protected]74d9063c2013-01-18 03:14:47836 bool result = m_renderer->swapBuffers();
837
838 if (m_settings.implSidePainting &&
839 !activeTree()->AreVisibleResourcesReady()) {
[email protected]6367cda2013-01-23 00:21:13840 m_client->didSwapUseIncompleteTileOnImplThread();
[email protected]74d9063c2013-01-18 03:14:47841 }
842
843 return result;
[email protected]94f206c12012-08-25 00:09:14844}
845
[email protected]aad0a0072012-11-01 18:15:58846const gfx::Size& LayerTreeHostImpl::deviceViewportSize() const
[email protected]493067512012-09-19 23:34:10847{
848 return m_deviceViewportSize;
849}
850
[email protected]96baf3e2012-10-22 23:09:55851const LayerTreeSettings& LayerTreeHostImpl::settings() const
[email protected]493067512012-09-19 23:34:10852{
853 return m_settings;
854}
855
[email protected]3be2171d2012-12-06 06:13:20856void LayerTreeHostImpl::didLoseOutputSurface()
[email protected]94f206c12012-08-25 00:09:14857{
[email protected]3be2171d2012-12-06 06:13:20858 m_client->didLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:14859}
860
[email protected]96baf3e2012-10-22 23:09:55861void LayerTreeHostImpl::onSwapBuffersComplete()
[email protected]94f206c12012-08-25 00:09:14862{
863 m_client->onSwapBuffersCompleteOnImplThread();
864}
865
[email protected]aad0a0072012-11-01 18:15:58866void LayerTreeHostImpl::readback(void* pixels, const gfx::Rect& rect)
[email protected]94f206c12012-08-25 00:09:14867{
[email protected]1d993172012-10-18 18:15:04868 DCHECK(m_renderer);
[email protected]94f206c12012-08-25 00:09:14869 m_renderer->getFramebufferPixels(pixels, rect);
870}
871
[email protected]69b50ec2013-01-19 04:58:01872bool LayerTreeHostImpl::haveRootScrollLayer() const {
873 return rootScrollLayer();
874}
875
876float LayerTreeHostImpl::rootScrollLayerTotalScrollY() const {
877 if (LayerImpl* layer = rootScrollLayer())
878 return layer->scrollOffset().y() + layer->scrollDelta().y();
879 return 0.0f;
880}
881
[email protected]8bef40572012-12-11 21:38:08882LayerImpl* LayerTreeHostImpl::rootLayer() const
883{
884 return m_activeTree->RootLayer();
885}
886
887LayerImpl* LayerTreeHostImpl::rootScrollLayer() const
888{
[email protected]69b50ec2013-01-19 04:58:01889 return m_activeTree->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:08890}
891
892LayerImpl* LayerTreeHostImpl::currentlyScrollingLayer() const
893{
[email protected]69b50ec2013-01-19 04:58:01894 return m_activeTree->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:08895}
896
[email protected]94f206c12012-08-25 00:09:14897// Content layers can be either directly scrollable or contained in an outer
898// scrolling layer which applies the scroll transform. Given a content layer,
899// this function returns the associated scroll layer if any.
[email protected]96baf3e2012-10-22 23:09:55900static LayerImpl* findScrollLayerForContentLayer(LayerImpl* layerImpl)
[email protected]94f206c12012-08-25 00:09:14901{
902 if (!layerImpl)
903 return 0;
904
905 if (layerImpl->scrollable())
906 return layerImpl;
907
908 if (layerImpl->drawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable())
909 return layerImpl->parent();
910
911 return 0;
912}
913
[email protected]2e7ca422012-12-20 02:57:27914void LayerTreeHostImpl::createPendingTree()
915{
916 CHECK(!m_pendingTree);
[email protected]48871fc2013-01-23 07:36:51917 if (m_recycleTree)
918 m_recycleTree.swap(m_pendingTree);
919 else
920 m_pendingTree = LayerTreeImpl::create(this);
[email protected]2e7ca422012-12-20 02:57:27921 m_client->onCanDrawStateChanged(canDraw());
922 m_client->onHasPendingTreeStateChanged(pendingTree());
[email protected]4f0a5002013-01-28 13:02:27923 TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", m_pendingTree.get());
[email protected]2e7ca422012-12-20 02:57:27924}
925
[email protected]6367cda2013-01-23 00:21:13926void LayerTreeHostImpl::checkForCompletedTileUploads()
[email protected]eabe5002013-01-12 22:07:48927{
[email protected]6367cda2013-01-23 00:21:13928 DCHECK(!m_client->isInsideDraw()) << "Checking for completed uploads within a draw may trigger spurious redraws.";
[email protected]eabe5002013-01-12 22:07:48929 if (m_tileManager)
[email protected]6367cda2013-01-23 00:21:13930 m_tileManager->CheckForCompletedTileUploads();
[email protected]eabe5002013-01-12 22:07:48931}
932
[email protected]4f0a5002013-01-28 13:02:27933scoped_ptr<base::Value> LayerTreeHostImpl::activationStateAsValue() const
934{
935 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
936 state->SetBoolean("visible_resources_ready", pendingTree()->AreVisibleResourcesReady());
937 state->Set("tile_manager", m_tileManager->AsValue().release());
938 return state.PassAs<base::Value>();
939}
940
941namespace {
942
943std::string ValueToString(scoped_ptr<base::Value> value)
944{
945 std::string str;
946 base::JSONWriter::Write(value.get(), &str);
947 return str;
948}
949
950}
951
[email protected]2e7ca422012-12-20 02:57:27952void LayerTreeHostImpl::activatePendingTreeIfNeeded()
953{
954 if (!pendingTree())
955 return;
956
[email protected]2ae038b2013-01-28 12:52:09957 CHECK(m_tileManager);
958
[email protected]4c9bb952013-01-27 05:41:18959 pendingTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE);
[email protected]615c78a2013-01-24 23:44:16960
[email protected]4f0a5002013-01-28 13:02:27961 TRACE_EVENT_ASYNC_STEP1("cc",
962 "PendingTree", m_pendingTree.get(), "activate",
963 "state", ValueToString(activationStateAsValue()));
964
[email protected]b0a917c8d2013-01-12 17:42:25965 // It's always fine to activate to an empty tree. Otherwise, only
[email protected]2ae038b2013-01-28 12:52:09966 // activate once all visible resources in pending tree are ready
967 // or tile manager has no work scheduled for pending tree.
[email protected]b0a917c8d2013-01-12 17:42:25968 if (activeTree()->RootLayer() &&
[email protected]2ae038b2013-01-28 12:52:09969 !pendingTree()->AreVisibleResourcesReady() &&
970 m_tileManager->HasPendingWorkScheduled(PENDING_TREE))
[email protected]b0a917c8d2013-01-12 17:42:25971 return;
[email protected]2e7ca422012-12-20 02:57:27972
[email protected]2e7ca422012-12-20 02:57:27973 activatePendingTree();
974}
975
976void LayerTreeHostImpl::activatePendingTree()
977{
978 CHECK(m_pendingTree);
[email protected]4f0a5002013-01-28 13:02:27979 TRACE_EVENT_ASYNC_END0("cc", "PendingTree", m_pendingTree.get());
[email protected]1e0f8d62013-01-09 07:41:35980
981 m_activeTree->PushPersistedState(m_pendingTree.get());
[email protected]48871fc2013-01-23 07:36:51982 m_activeTree->SetRootLayer(TreeSynchronizer::synchronizeTrees(m_pendingTree->RootLayer(), m_activeTree->DetachLayerTree(), m_activeTree.get()));
983 TreeSynchronizer::pushProperties(m_pendingTree->RootLayer(), m_activeTree->RootLayer());
984 DCHECK(!m_recycleTree);
985
986 // This should match the property synchronization in
987 // LayerTreeHost::finishCommitOnImplThread().
988 m_activeTree->set_source_frame_number(m_pendingTree->source_frame_number());
989 m_activeTree->set_background_color(m_pendingTree->background_color());
990 m_activeTree->set_has_transparent_background(m_pendingTree->has_transparent_background());
991 if (m_pendingTree->ContentsTexturesPurged())
992 m_activeTree->SetContentsTexturesPurged();
993 else
994 m_activeTree->ResetContentsTexturesPurged();
[email protected]bf190832013-01-26 00:24:44995 if (m_pendingTree->hud_layer())
996 m_activeTree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(LayerTreeHostCommon::findLayerInSubtree(m_activeTree->RootLayer(), m_pendingTree->hud_layer()->id())));
997 else
998 m_activeTree->set_hud_layer(NULL);
[email protected]48871fc2013-01-23 07:36:51999
1000 // Now that we've synced everything from the pending tree to the active
1001 // tree, rename the pending tree the recycle tree so we can reuse it on the
1002 // next sync.
1003 m_pendingTree.swap(m_recycleTree);
1004 m_recycleTree->ClearRenderSurfaces();
1005
[email protected]37386f052013-01-13 00:42:221006 m_activeTree->DidBecomeActive();
1007
[email protected]2e7ca422012-12-20 02:57:271008 m_client->onCanDrawStateChanged(canDraw());
1009 m_client->onHasPendingTreeStateChanged(pendingTree());
[email protected]eabe5002013-01-12 22:07:481010 m_client->setNeedsRedrawOnImplThread();
[email protected]362f1e8b2013-01-21 16:54:301011 m_client->renewTreePriority();
[email protected]2e7ca422012-12-20 02:57:271012}
1013
[email protected]96baf3e2012-10-22 23:09:551014void LayerTreeHostImpl::setVisible(bool visible)
[email protected]94f206c12012-08-25 00:09:141015{
[email protected]61de5812012-11-08 07:03:441016 DCHECK(m_proxy->isImplThread());
[email protected]94f206c12012-08-25 00:09:141017
1018 if (m_visible == visible)
1019 return;
1020 m_visible = visible;
1021 didVisibilityChange(this, m_visible);
[email protected]a0a00842012-10-22 22:50:281022 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
[email protected]94f206c12012-08-25 00:09:141023
1024 if (!m_renderer)
1025 return;
1026
1027 m_renderer->setVisible(visible);
1028
[email protected]de4afb5e2012-12-20 00:11:341029 setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141030}
1031
[email protected]3be2171d2012-12-06 06:13:201032bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface)
[email protected]94f206c12012-08-25 00:09:141033{
[email protected]be3181652012-09-25 13:02:131034 // Since we will create a new resource provider, we cannot continue to use
1035 // the old resources (i.e. renderSurfaces and texture IDs). Clear them
1036 // before we destroy the old resource provider.
[email protected]45c4b1e2013-01-16 02:19:401037 if (rootLayer())
[email protected]94f206c12012-08-25 00:09:141038 clearRenderSurfaces();
[email protected]45c4b1e2013-01-16 02:19:401039 if (activeTree()->RootLayer())
1040 sendDidLoseOutputSurfaceRecursive(activeTree()->RootLayer());
1041 if (pendingTree() && pendingTree()->RootLayer())
1042 sendDidLoseOutputSurfaceRecursive(pendingTree()->RootLayer());
[email protected]48871fc2013-01-23 07:36:511043 if (m_recycleTree && m_recycleTree->RootLayer())
1044 sendDidLoseOutputSurfaceRecursive(m_recycleTree->RootLayer());
[email protected]45c4b1e2013-01-16 02:19:401045
[email protected]be3181652012-09-25 13:02:131046 // Note: order is important here.
[email protected]0704caf2012-10-16 03:39:471047 m_renderer.reset();
[email protected]8947cbe2012-11-28 05:27:431048 m_tileManager.reset();
[email protected]a7aa5562012-10-17 14:12:441049 m_resourceProvider.reset();
[email protected]3be2171d2012-12-06 06:13:201050 m_outputSurface.reset();
[email protected]94f206c12012-08-25 00:09:141051
[email protected]a46f32932012-12-07 21:43:161052 if (!outputSurface->BindToClient(this))
[email protected]be3181652012-09-25 13:02:131053 return false;
1054
[email protected]3be2171d2012-12-06 06:13:201055 scoped_ptr<ResourceProvider> resourceProvider = ResourceProvider::create(outputSurface.get());
[email protected]be3181652012-09-25 13:02:131056 if (!resourceProvider)
1057 return false;
1058
[email protected]8947cbe2012-11-28 05:27:431059 if (m_settings.implSidePainting)
[email protected]876e9e82012-12-04 20:12:141060 m_tileManager.reset(new TileManager(this, resourceProvider.get(), m_settings.numRasterThreads));
[email protected]8947cbe2012-11-28 05:27:431061
[email protected]ea9d8f22012-12-08 03:39:291062 if (outputSurface->Capabilities().has_parent_compositor)
[email protected]05469632013-01-16 03:41:001063 m_renderer = DelegatingRenderer::Create(this, outputSurface.get(), resourceProvider.get());
[email protected]ea9d8f22012-12-08 03:39:291064 else if (outputSurface->Context3D())
[email protected]bf189f62012-12-18 03:42:111065 m_renderer = GLRenderer::create(this, outputSurface.get(), resourceProvider.get());
[email protected]a46f32932012-12-07 21:43:161066 else if (outputSurface->SoftwareDevice())
1067 m_renderer = SoftwareRenderer::create(this, resourceProvider.get(), outputSurface->SoftwareDevice());
[email protected]be3181652012-09-25 13:02:131068 if (!m_renderer)
1069 return false;
1070
[email protected]a7aa5562012-10-17 14:12:441071 m_resourceProvider = resourceProvider.Pass();
[email protected]3be2171d2012-12-06 06:13:201072 m_outputSurface = outputSurface.Pass();
[email protected]94f206c12012-08-25 00:09:141073
[email protected]be3181652012-09-25 13:02:131074 if (!m_visible)
1075 m_renderer->setVisible(m_visible);
[email protected]94f206c12012-08-25 00:09:141076
[email protected]8db2213c2012-09-05 22:08:211077 m_client->onCanDrawStateChanged(canDraw());
1078
[email protected]615c78a2013-01-24 23:44:161079 // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs
1080 // to be initialized to get max texture size.
1081 activeTree()->set_needs_update_draw_properties();
1082 if (pendingTree())
1083 pendingTree()->set_needs_update_draw_properties();
1084
[email protected]be3181652012-09-25 13:02:131085 return true;
[email protected]94f206c12012-08-25 00:09:141086}
1087
[email protected]aad0a0072012-11-01 18:15:581088void LayerTreeHostImpl::setViewportSize(const gfx::Size& layoutViewportSize, const gfx::Size& deviceViewportSize)
[email protected]94f206c12012-08-25 00:09:141089{
1090 if (layoutViewportSize == m_layoutViewportSize && deviceViewportSize == m_deviceViewportSize)
1091 return;
1092
1093 m_layoutViewportSize = layoutViewportSize;
1094 m_deviceViewportSize = deviceViewportSize;
1095
[email protected]a823df82013-01-10 02:38:171096 m_pinchZoomViewport.set_layout_viewport_size(layoutViewportSize);
[email protected]42ccdbef2013-01-21 07:54:541097 m_pinchZoomViewport.set_device_viewport_size(deviceViewportSize);
[email protected]1c0c9bc2012-10-08 22:41:481098
[email protected]c9c1ebe2012-11-05 20:46:131099 updateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141100
1101 if (m_renderer)
1102 m_renderer->viewportChanged();
[email protected]8db2213c2012-09-05 22:08:211103
1104 m_client->onCanDrawStateChanged(canDraw());
[email protected]94f206c12012-08-25 00:09:141105}
1106
[email protected]96baf3e2012-10-22 23:09:551107static void adjustScrollsForPageScaleChange(LayerImpl* layerImpl, float pageScaleChange)
[email protected]94f206c12012-08-25 00:09:141108{
1109 if (!layerImpl)
1110 return;
1111
1112 if (layerImpl->scrollable()) {
1113 // We need to convert impl-side scroll deltas to pageScale space.
[email protected]c9c1ebe2012-11-05 20:46:131114 gfx::Vector2dF scrollDelta = layerImpl->scrollDelta();
1115 scrollDelta.Scale(pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141116 layerImpl->setScrollDelta(scrollDelta);
1117 }
1118
1119 for (size_t i = 0; i < layerImpl->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031120 adjustScrollsForPageScaleChange(layerImpl->children()[i], pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141121}
1122
[email protected]96baf3e2012-10-22 23:09:551123void LayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor)
[email protected]94f206c12012-08-25 00:09:141124{
1125 if (deviceScaleFactor == m_deviceScaleFactor)
1126 return;
1127 m_deviceScaleFactor = deviceScaleFactor;
[email protected]a823df82013-01-10 02:38:171128 m_pinchZoomViewport.set_device_scale_factor(m_deviceScaleFactor);
[email protected]c0dd24c2012-08-30 23:25:271129
[email protected]c9c1ebe2012-11-05 20:46:131130 updateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141131}
1132
[email protected]96baf3e2012-10-22 23:09:551133float LayerTreeHostImpl::pageScaleFactor() const
[email protected]94f206c12012-08-25 00:09:141134{
[email protected]a823df82013-01-10 02:38:171135 return m_pinchZoomViewport.page_scale_factor();
[email protected]1c0c9bc2012-10-08 22:41:481136}
[email protected]94f206c12012-08-25 00:09:141137
[email protected]96baf3e2012-10-22 23:09:551138void LayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
[email protected]1c0c9bc2012-10-08 22:41:481139{
1140 if (!pageScaleFactor)
1141 return;
[email protected]94f206c12012-08-25 00:09:141142
[email protected]a823df82013-01-10 02:38:171143 float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.page_scale_factor();
1144 m_pinchZoomViewport.SetPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor);
[email protected]94f206c12012-08-25 00:09:141145
[email protected]0ede3bb2012-12-09 09:14:391146 if (!m_settings.pageScalePinchZoomEnabled && pageScaleChange != 1)
1147 adjustScrollsForPageScaleChange(rootScrollLayer(), pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141148
1149 // Clamp delta to limits and refresh display matrix.
[email protected]a823df82013-01-10 02:38:171150 setPageScaleDelta(m_pinchZoomViewport.page_scale_delta() / m_pinchZoomViewport.sent_page_scale_delta());
1151 m_pinchZoomViewport.set_sent_page_scale_delta(1);
[email protected]94f206c12012-08-25 00:09:141152}
1153
[email protected]96baf3e2012-10-22 23:09:551154void LayerTreeHostImpl::setPageScaleDelta(float delta)
[email protected]94f206c12012-08-25 00:09:141155{
[email protected]615c78a2013-01-24 23:44:161156 if (m_pinchZoomViewport.page_scale_delta() == delta)
1157 return;
1158
[email protected]a823df82013-01-10 02:38:171159 m_pinchZoomViewport.set_page_scale_delta(delta);
[email protected]94f206c12012-08-25 00:09:141160
[email protected]c9c1ebe2012-11-05 20:46:131161 updateMaxScrollOffset();
[email protected]615c78a2013-01-24 23:44:161162 activeTree()->set_needs_update_draw_properties();
1163 if (pendingTree())
1164 pendingTree()->set_needs_update_draw_properties();
1165}
1166
1167gfx::Vector2dF LayerTreeHostImpl::scrollPinchZoomViewport(gfx::Vector2dF delta)
1168{
1169 gfx::Vector2dF overflow = m_pinchZoomViewport.ApplyScroll(delta);
1170 activeTree()->set_needs_update_draw_properties();
1171 if (pendingTree())
1172 pendingTree()->set_needs_update_draw_properties();
1173 return overflow;
[email protected]94f206c12012-08-25 00:09:141174}
1175
[email protected]c9c1ebe2012-11-05 20:46:131176void LayerTreeHostImpl::updateMaxScrollOffset()
[email protected]94f206c12012-08-25 00:09:141177{
[email protected]caa567d2012-12-20 07:56:161178 activeTree()->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141179}
1180
[email protected]615c78a2013-01-24 23:44:161181void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties()
[email protected]3ba4cae2013-01-16 03:58:381182{
[email protected]615c78a2013-01-24 23:44:161183 activeTree()->set_needs_update_draw_properties();
[email protected]3ba4cae2013-01-16 03:58:381184}
1185
[email protected]96baf3e2012-10-22 23:09:551186void LayerTreeHostImpl::setNeedsRedraw()
[email protected]94f206c12012-08-25 00:09:141187{
1188 m_client->setNeedsRedrawOnImplThread();
1189}
1190
[email protected]96baf3e2012-10-22 23:09:551191bool LayerTreeHostImpl::ensureRenderSurfaceLayerList()
[email protected]94f206c12012-08-25 00:09:141192{
[email protected]4c9bb952013-01-27 05:41:181193 activeTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE);
[email protected]76ffd9e2012-12-20 19:12:471194 return activeTree()->RenderSurfaceLayerList().size();
[email protected]94f206c12012-08-25 00:09:141195}
1196
[email protected]c9c1ebe2012-11-05 20:46:131197InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewportPoint, InputHandlerClient::ScrollInputType type)
[email protected]94f206c12012-08-25 00:09:141198{
[email protected]96baf3e2012-10-22 23:09:551199 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin");
[email protected]94f206c12012-08-25 00:09:141200
[email protected]3ba4cae2013-01-16 03:58:381201 if (m_topControlsManager)
1202 m_topControlsManager->ScrollBegin();
1203
[email protected]3b31c6ac2012-12-06 21:27:291204 DCHECK(!currentlyScrollingLayer());
[email protected]94f206c12012-08-25 00:09:141205 clearCurrentlyScrollingLayer();
1206
1207 if (!ensureRenderSurfaceLayerList())
1208 return ScrollIgnored;
1209
[email protected]faf56352012-11-09 21:44:131210 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:141211
1212 // First find out which layer was hit from the saved list of visible layers
1213 // in the most recent frame.
[email protected]76ffd9e2012-12-20 19:12:471214 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(deviceViewportPoint, activeTree()->RenderSurfaceLayerList());
[email protected]94f206c12012-08-25 00:09:141215
1216 // Walk up the hierarchy and look for a scrollable layer.
[email protected]96baf3e2012-10-22 23:09:551217 LayerImpl* potentiallyScrollingLayerImpl = 0;
[email protected]94f206c12012-08-25 00:09:141218 for (; layerImpl; layerImpl = layerImpl->parent()) {
1219 // The content layer can also block attempts to scroll outside the main thread.
[email protected]5c6fe1f82012-10-03 18:00:271220 if (layerImpl->tryScroll(deviceViewportPoint, type) == ScrollOnMainThread) {
1221 m_numMainThreadScrolls++;
[email protected]94f206c12012-08-25 00:09:141222 return ScrollOnMainThread;
[email protected]5c6fe1f82012-10-03 18:00:271223 }
[email protected]94f206c12012-08-25 00:09:141224
[email protected]96baf3e2012-10-22 23:09:551225 LayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl);
[email protected]94f206c12012-08-25 00:09:141226 if (!scrollLayerImpl)
1227 continue;
1228
[email protected]31bfe272012-10-19 18:49:521229 ScrollStatus status = scrollLayerImpl->tryScroll(deviceViewportPoint, type);
[email protected]94f206c12012-08-25 00:09:141230
1231 // If any layer wants to divert the scroll event to the main thread, abort.
[email protected]5c6fe1f82012-10-03 18:00:271232 if (status == ScrollOnMainThread) {
1233 m_numMainThreadScrolls++;
[email protected]94f206c12012-08-25 00:09:141234 return ScrollOnMainThread;
[email protected]5c6fe1f82012-10-03 18:00:271235 }
[email protected]94f206c12012-08-25 00:09:141236
1237 if (status == ScrollStarted && !potentiallyScrollingLayerImpl)
1238 potentiallyScrollingLayerImpl = scrollLayerImpl;
1239 }
1240
1241 if (potentiallyScrollingLayerImpl) {
[email protected]3b31c6ac2012-12-06 21:27:291242 m_activeTree->set_currently_scrolling_layer(potentiallyScrollingLayerImpl);
[email protected]31bfe272012-10-19 18:49:521243 // Gesture events need to be transformed from viewport coordinates to local layer coordinates
[email protected]94f206c12012-08-25 00:09:141244 // so that the scrolling contents exactly follow the user's finger. In contrast, wheel
1245 // events are already in local layer coordinates so we can just apply them directly.
[email protected]31bfe272012-10-19 18:49:521246 m_scrollDeltaIsInViewportSpace = (type == Gesture);
[email protected]5c6fe1f82012-10-03 18:00:271247 m_numImplThreadScrolls++;
[email protected]4c0e1bb2013-01-22 03:43:171248 m_client->renewTreePriority();
[email protected]94f206c12012-08-25 00:09:141249 return ScrollStarted;
1250 }
1251 return ScrollIgnored;
1252}
1253
[email protected]615c78a2013-01-24 23:44:161254gfx::Vector2dF LayerTreeHostImpl::scrollLayerWithViewportSpaceDelta(LayerImpl* layerImpl, float scaleFromViewportToScreenSpace, gfx::PointF viewportPoint, gfx::Vector2dF viewportDelta)
[email protected]94f206c12012-08-25 00:09:141255{
1256 // Layers with non-invertible screen space transforms should not have passed the scroll hit
1257 // test in the first place.
[email protected]615c78a2013-01-24 23:44:161258 DCHECK(layerImpl->screenSpaceTransform().IsInvertible());
[email protected]bda41962013-01-07 18:46:171259 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitialization);
[email protected]615c78a2013-01-24 23:44:161260 bool didInvert = layerImpl->screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform);
[email protected]bda41962013-01-07 18:46:171261 // TODO: With the advent of impl-side crolling for non-root layers, we may
1262 // need to explicitly handle uninvertible transforms here.
1263 DCHECK(didInvert);
[email protected]94f206c12012-08-25 00:09:141264
[email protected]faf56352012-11-09 21:44:131265 gfx::PointF screenSpacePoint = gfx::ScalePoint(viewportPoint, scaleFromViewportToScreenSpace);
[email protected]31bfe272012-10-19 18:49:521266
[email protected]c9c1ebe2012-11-05 20:46:131267 gfx::Vector2dF screenSpaceDelta = viewportDelta;
1268 screenSpaceDelta.Scale(scaleFromViewportToScreenSpace);
[email protected]31bfe272012-10-19 18:49:521269
[email protected]94f206c12012-08-25 00:09:141270 // First project the scroll start and end points to local layer space to find the scroll delta
1271 // in layer coordinates.
1272 bool startClipped, endClipped;
[email protected]d455d552012-11-02 00:19:061273 gfx::PointF screenSpaceEndPoint = screenSpacePoint + screenSpaceDelta;
1274 gfx::PointF localStartPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpacePoint, startClipped);
1275 gfx::PointF localEndPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpaceEndPoint, endClipped);
[email protected]94f206c12012-08-25 00:09:141276
1277 // In general scroll point coordinates should not get clipped.
[email protected]1d993172012-10-18 18:15:041278 DCHECK(!startClipped);
1279 DCHECK(!endClipped);
[email protected]94f206c12012-08-25 00:09:141280 if (startClipped || endClipped)
[email protected]c9c1ebe2012-11-05 20:46:131281 return gfx::Vector2dF();
[email protected]94f206c12012-08-25 00:09:141282
[email protected]31bfe272012-10-19 18:49:521283 // localStartPoint and localEndPoint are in content space but we want to move them to layer space for scrolling.
[email protected]615c78a2013-01-24 23:44:161284 float widthScale = 1 / layerImpl->contentsScaleX();
1285 float heightScale = 1 / layerImpl->contentsScaleY();
[email protected]faf56352012-11-09 21:44:131286 localStartPoint.Scale(widthScale, heightScale);
1287 localEndPoint.Scale(widthScale, heightScale);
[email protected]31bfe272012-10-19 18:49:521288
[email protected]94f206c12012-08-25 00:09:141289 // Apply the scroll delta.
[email protected]615c78a2013-01-24 23:44:161290 gfx::Vector2dF previousDelta = layerImpl->scrollDelta();
1291 gfx::Vector2dF unscrolled = layerImpl->scrollBy(localEndPoint - localStartPoint);
[email protected]caa567d2012-12-20 07:56:161292 gfx::Vector2dF scrollAmount = localEndPoint - localStartPoint;
[email protected]1c0c9bc2012-10-08 22:41:481293
[email protected]aeaa50a2012-11-21 20:12:371294 gfx::Vector2dF viewportAppliedPan;
[email protected]615c78a2013-01-24 23:44:161295 if (m_settings.pageScalePinchZoomEnabled && layerImpl == rootScrollLayer())
1296 viewportAppliedPan = unscrolled - scrollPinchZoomViewport(unscrolled);
[email protected]94f206c12012-08-25 00:09:141297
[email protected]31bfe272012-10-19 18:49:521298 // Get the end point in the layer's content space so we can apply its screenSpaceTransform.
[email protected]615c78a2013-01-24 23:44:161299 gfx::PointF actualLocalEndPoint = localStartPoint + layerImpl->scrollDelta() + viewportAppliedPan - previousDelta;
[email protected]faf56352012-11-09 21:44:131300 gfx::PointF actualLocalContentEndPoint = gfx::ScalePoint(actualLocalEndPoint, 1 / widthScale, 1 / heightScale);
[email protected]31bfe272012-10-19 18:49:521301
1302 // Calculate the applied scroll delta in viewport space coordinates.
[email protected]615c78a2013-01-24 23:44:161303 gfx::PointF actualScreenSpaceEndPoint = MathUtil::mapPoint(layerImpl->screenSpaceTransform(), actualLocalContentEndPoint, endClipped);
[email protected]1d993172012-10-18 18:15:041304 DCHECK(!endClipped);
[email protected]94f206c12012-08-25 00:09:141305 if (endClipped)
[email protected]c9c1ebe2012-11-05 20:46:131306 return gfx::Vector2dF();
[email protected]faf56352012-11-09 21:44:131307 gfx::PointF actualViewportEndPoint = gfx::ScalePoint(actualScreenSpaceEndPoint, 1 / scaleFromViewportToScreenSpace);
[email protected]c9c1ebe2012-11-05 20:46:131308 return actualViewportEndPoint - viewportPoint;
[email protected]94f206c12012-08-25 00:09:141309}
1310
[email protected]c9c1ebe2012-11-05 20:46:131311static gfx::Vector2dF scrollLayerWithLocalDelta(LayerImpl& layerImpl, gfx::Vector2dF localDelta)
[email protected]94f206c12012-08-25 00:09:141312{
[email protected]c9c1ebe2012-11-05 20:46:131313 gfx::Vector2dF previousDelta(layerImpl.scrollDelta());
[email protected]94f206c12012-08-25 00:09:141314 layerImpl.scrollBy(localDelta);
1315 return layerImpl.scrollDelta() - previousDelta;
1316}
1317
[email protected]a9710962012-11-14 20:11:021318bool LayerTreeHostImpl::scrollBy(const gfx::Point& viewportPoint,
1319 const gfx::Vector2d& scrollDelta)
[email protected]94f206c12012-08-25 00:09:141320{
[email protected]96baf3e2012-10-22 23:09:551321 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBy");
[email protected]3b31c6ac2012-12-06 21:27:291322 if (!currentlyScrollingLayer())
[email protected]a9710962012-11-14 20:11:021323 return false;
[email protected]94f206c12012-08-25 00:09:141324
[email protected]c9c1ebe2012-11-05 20:46:131325 gfx::Vector2dF pendingDelta = scrollDelta;
[email protected]1ca52a3a2012-12-04 22:47:101326 bool didScroll = false;
[email protected]94f206c12012-08-25 00:09:141327
[email protected]3b31c6ac2012-12-06 21:27:291328 for (LayerImpl* layerImpl = currentlyScrollingLayer(); layerImpl; layerImpl = layerImpl->parent()) {
[email protected]94f206c12012-08-25 00:09:141329 if (!layerImpl->scrollable())
1330 continue;
1331
[email protected]c9c1ebe2012-11-05 20:46:131332 gfx::Vector2dF appliedDelta;
[email protected]3ba4cae2013-01-16 03:58:381333 if (m_topControlsManager && layerImpl == rootScrollLayer())
1334 pendingDelta = m_topControlsManager->ScrollBy(pendingDelta);
1335
[email protected]31bfe272012-10-19 18:49:521336 if (m_scrollDeltaIsInViewportSpace) {
1337 float scaleFromViewportToScreenSpace = m_deviceScaleFactor;
[email protected]615c78a2013-01-24 23:44:161338 appliedDelta = scrollLayerWithViewportSpaceDelta(layerImpl, scaleFromViewportToScreenSpace, viewportPoint, pendingDelta);
[email protected]31bfe272012-10-19 18:49:521339 } else
[email protected]94f206c12012-08-25 00:09:141340 appliedDelta = scrollLayerWithLocalDelta(*layerImpl, pendingDelta);
1341
1342 // If the layer wasn't able to move, try the next one in the hierarchy.
[email protected]23bbb412012-08-30 20:03:381343 float moveThresholdSquared = 0.1f * 0.1f;
[email protected]c9c1ebe2012-11-05 20:46:131344 if (appliedDelta.LengthSquared() < moveThresholdSquared)
[email protected]94f206c12012-08-25 00:09:141345 continue;
[email protected]1ca52a3a2012-12-04 22:47:101346 didScroll = true;
[email protected]94f206c12012-08-25 00:09:141347
1348 // If the applied delta is within 45 degrees of the input delta, bail out to make it easier
1349 // to scroll just one layer in one direction without affecting any of its parents.
1350 float angleThreshold = 45;
[email protected]96baf3e2012-10-22 23:09:551351 if (MathUtil::smallestAngleBetweenVectors(appliedDelta, pendingDelta) < angleThreshold) {
[email protected]c9c1ebe2012-11-05 20:46:131352 pendingDelta = gfx::Vector2d();
[email protected]94f206c12012-08-25 00:09:141353 break;
1354 }
1355
1356 // Allow further movement only on an axis perpendicular to the direction in which the layer
1357 // moved.
[email protected]c9c1ebe2012-11-05 20:46:131358 gfx::Vector2dF perpendicularAxis(-appliedDelta.y(), appliedDelta.x());
[email protected]96baf3e2012-10-22 23:09:551359 pendingDelta = MathUtil::projectVector(pendingDelta, perpendicularAxis);
[email protected]94f206c12012-08-25 00:09:141360
[email protected]c9c1ebe2012-11-05 20:46:131361 if (gfx::ToFlooredVector2d(pendingDelta).IsZero())
[email protected]94f206c12012-08-25 00:09:141362 break;
1363 }
1364
[email protected]1ca52a3a2012-12-04 22:47:101365 if (didScroll) {
[email protected]94f206c12012-08-25 00:09:141366 m_client->setNeedsCommitOnImplThread();
1367 m_client->setNeedsRedrawOnImplThread();
[email protected]4c0e1bb2013-01-22 03:43:171368 m_client->renewTreePriority();
[email protected]94f206c12012-08-25 00:09:141369 }
[email protected]1ca52a3a2012-12-04 22:47:101370 return didScroll;
[email protected]94f206c12012-08-25 00:09:141371}
1372
[email protected]96baf3e2012-10-22 23:09:551373void LayerTreeHostImpl::clearCurrentlyScrollingLayer()
[email protected]94f206c12012-08-25 00:09:141374{
[email protected]3b31c6ac2012-12-06 21:27:291375 m_activeTree->ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141376}
1377
[email protected]96baf3e2012-10-22 23:09:551378void LayerTreeHostImpl::scrollEnd()
[email protected]94f206c12012-08-25 00:09:141379{
[email protected]3ba4cae2013-01-16 03:58:381380 if (m_topControlsManager)
1381 m_topControlsManager->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141382 clearCurrentlyScrollingLayer();
1383}
1384
[email protected]96baf3e2012-10-22 23:09:551385void LayerTreeHostImpl::pinchGestureBegin()
[email protected]94f206c12012-08-25 00:09:141386{
1387 m_pinchGestureActive = true;
[email protected]c9c1ebe2012-11-05 20:46:131388 m_previousPinchAnchor = gfx::Point();
[email protected]4c0e1bb2013-01-22 03:43:171389 m_client->renewTreePriority();
[email protected]94f206c12012-08-25 00:09:141390}
1391
[email protected]c9c1ebe2012-11-05 20:46:131392void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor)
[email protected]94f206c12012-08-25 00:09:141393{
[email protected]96baf3e2012-10-22 23:09:551394 TRACE_EVENT0("cc", "LayerTreeHostImpl::pinchGestureUpdate");
[email protected]94f206c12012-08-25 00:09:141395
[email protected]3b31c6ac2012-12-06 21:27:291396 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141397 return;
1398
[email protected]94f206c12012-08-25 00:09:141399 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1400 // position over the course of the magnify.
[email protected]a823df82013-01-10 02:38:171401 float pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
[email protected]c77745d2012-11-20 04:11:571402 gfx::PointF previousScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta);
[email protected]1c0c9bc2012-10-08 22:41:481403 setPageScaleDelta(pageScaleDelta * magnifyDelta);
[email protected]a823df82013-01-10 02:38:171404 pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
[email protected]faf56352012-11-09 21:44:131405 gfx::PointF newScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta);
[email protected]c9c1ebe2012-11-05 20:46:131406 gfx::Vector2dF move = previousScaleAnchor - newScaleAnchor;
[email protected]94f206c12012-08-25 00:09:141407
1408 m_previousPinchAnchor = anchor;
1409
[email protected]9bdcfd642012-11-14 21:24:261410 if (m_settings.pageScalePinchZoomEnabled) {
[email protected]1c0c9bc2012-10-08 22:41:481411 // Compute the application of the delta with respect to the current page zoom of the page.
[email protected]a823df82013-01-10 02:38:171412 move.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]1c0c9bc2012-10-08 22:41:481413 }
1414
[email protected]615c78a2013-01-24 23:44:161415 gfx::Vector2dF scrollOverflow = m_settings.pageScalePinchZoomEnabled ? scrollPinchZoomViewport(move) : move;
[email protected]3b31c6ac2012-12-06 21:27:291416 rootScrollLayer()->scrollBy(scrollOverflow);
[email protected]94f206c12012-08-25 00:09:141417
[email protected]3b31c6ac2012-12-06 21:27:291418 if (rootScrollLayer()->scrollbarAnimationController())
[email protected]e45638c2013-01-17 22:01:401419 rootScrollLayer()->scrollbarAnimationController()->didPinchGestureUpdate(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141420
1421 m_client->setNeedsCommitOnImplThread();
1422 m_client->setNeedsRedrawOnImplThread();
[email protected]4c0e1bb2013-01-22 03:43:171423 m_client->renewTreePriority();
[email protected]94f206c12012-08-25 00:09:141424}
1425
[email protected]96baf3e2012-10-22 23:09:551426void LayerTreeHostImpl::pinchGestureEnd()
[email protected]94f206c12012-08-25 00:09:141427{
1428 m_pinchGestureActive = false;
1429
[email protected]3b31c6ac2012-12-06 21:27:291430 if (rootScrollLayer() && rootScrollLayer()->scrollbarAnimationController())
[email protected]e45638c2013-01-17 22:01:401431 rootScrollLayer()->scrollbarAnimationController()->didPinchGestureEnd(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141432
1433 m_client->setNeedsCommitOnImplThread();
1434}
1435
[email protected]96baf3e2012-10-22 23:09:551436void LayerTreeHostImpl::computeDoubleTapZoomDeltas(ScrollAndScaleSet* scrollInfo)
[email protected]94f206c12012-08-25 00:09:141437{
[email protected]f6250742012-11-09 04:46:561438 gfx::Vector2dF scaledScrollOffset = m_pageScaleAnimation->targetScrollOffset();
[email protected]9bdcfd642012-11-14 21:24:261439 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]a823df82013-01-10 02:38:171440 scaledScrollOffset.Scale(m_pinchZoomViewport.page_scale_factor());
[email protected]f6250742012-11-09 04:46:561441 makeScrollAndScaleSet(scrollInfo, ToFlooredVector2d(scaledScrollOffset), m_pageScaleAnimation->targetPageScaleFactor());
[email protected]94f206c12012-08-25 00:09:141442}
1443
[email protected]96baf3e2012-10-22 23:09:551444void LayerTreeHostImpl::computePinchZoomDeltas(ScrollAndScaleSet* scrollInfo)
[email protected]94f206c12012-08-25 00:09:141445{
[email protected]3b31c6ac2012-12-06 21:27:291446 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141447 return;
1448
1449 // Only send fake scroll/zoom deltas if we're pinch zooming out by a
1450 // significant amount. This also ensures only one fake delta set will be
1451 // sent.
[email protected]23bbb412012-08-30 20:03:381452 const float pinchZoomOutSensitivity = 0.95f;
[email protected]a823df82013-01-10 02:38:171453 if (m_pinchZoomViewport.page_scale_delta() > pinchZoomOutSensitivity)
[email protected]94f206c12012-08-25 00:09:141454 return;
1455
1456 // Compute where the scroll offset/page scale would be if fully pinch-zoomed
1457 // out from the anchor point.
[email protected]3b31c6ac2012-12-06 21:27:291458 gfx::Vector2dF scrollBegin = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]a823df82013-01-10 02:38:171459 scrollBegin.Scale(m_pinchZoomViewport.page_scale_delta());
1460 float scaleBegin = m_pinchZoomViewport.total_page_scale_factor();
1461 float pageScaleDeltaToSend = m_pinchZoomViewport.min_page_scale_factor() / m_pinchZoomViewport.page_scale_factor();
[email protected]42ccdbef2013-01-21 07:54:541462 gfx::SizeF scaledScrollableSize = gfx::ScaleSize(activeTree()->ScrollableSize(), pageScaleDeltaToSend);
[email protected]94f206c12012-08-25 00:09:141463
[email protected]c9c1ebe2012-11-05 20:46:131464 gfx::Vector2d anchorOffset = m_previousPinchAnchor.OffsetFromOrigin();
1465 gfx::Vector2dF scrollEnd = scrollBegin + anchorOffset;
[email protected]a823df82013-01-10 02:38:171466 scrollEnd.Scale(m_pinchZoomViewport.min_page_scale_factor() / scaleBegin);
[email protected]c9c1ebe2012-11-05 20:46:131467 scrollEnd -= anchorOffset;
[email protected]42ccdbef2013-01-21 07:54:541468 scrollEnd.ClampToMax(gfx::RectF(scaledScrollableSize).bottom_right() - gfx::Rect(m_deviceViewportSize).bottom_right());
[email protected]fe07b642012-11-10 00:07:591469 scrollEnd.ClampToMin(gfx::Vector2d());
[email protected]c9c1ebe2012-11-05 20:46:131470 scrollEnd.Scale(1 / pageScaleDeltaToSend);
1471 scrollEnd.Scale(m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:141472
[email protected]a823df82013-01-10 02:38:171473 makeScrollAndScaleSet(scrollInfo, gfx::ToRoundedVector2d(scrollEnd), m_pinchZoomViewport.min_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:141474}
1475
[email protected]c9c1ebe2012-11-05 20:46:131476void LayerTreeHostImpl::makeScrollAndScaleSet(ScrollAndScaleSet* scrollInfo, gfx::Vector2d scrollOffset, float pageScale)
[email protected]94f206c12012-08-25 00:09:141477{
[email protected]3b31c6ac2012-12-06 21:27:291478 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141479 return;
1480
[email protected]96baf3e2012-10-22 23:09:551481 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]3b31c6ac2012-12-06 21:27:291482 scroll.layerId = rootScrollLayer()->id();
1483 scroll.scrollDelta = scrollOffset - rootScrollLayer()->scrollOffset();
[email protected]787465c2012-10-29 01:12:271484 scrollInfo->scrolls.push_back(scroll);
[email protected]69b50ec2013-01-19 04:58:011485 activeTree()->RootScrollLayer()->setSentScrollDelta(scroll.scrollDelta);
[email protected]a823df82013-01-10 02:38:171486 scrollInfo->pageScaleDelta = pageScale / m_pinchZoomViewport.page_scale_factor();
1487 m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta);
[email protected]94f206c12012-08-25 00:09:141488}
1489
[email protected]96baf3e2012-10-22 23:09:551490static void collectScrollDeltas(ScrollAndScaleSet* scrollInfo, LayerImpl* layerImpl)
[email protected]94f206c12012-08-25 00:09:141491{
1492 if (!layerImpl)
1493 return;
1494
[email protected]c9c1ebe2012-11-05 20:46:131495 if (!layerImpl->scrollDelta().IsZero()) {
1496 gfx::Vector2d scrollDelta = gfx::ToFlooredVector2d(layerImpl->scrollDelta());
[email protected]96baf3e2012-10-22 23:09:551497 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]94f206c12012-08-25 00:09:141498 scroll.layerId = layerImpl->id();
1499 scroll.scrollDelta = scrollDelta;
[email protected]787465c2012-10-29 01:12:271500 scrollInfo->scrolls.push_back(scroll);
[email protected]94f206c12012-08-25 00:09:141501 layerImpl->setSentScrollDelta(scrollDelta);
1502 }
1503
1504 for (size_t i = 0; i < layerImpl->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031505 collectScrollDeltas(scrollInfo, layerImpl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141506}
1507
[email protected]96baf3e2012-10-22 23:09:551508scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::processScrollDeltas()
[email protected]94f206c12012-08-25 00:09:141509{
[email protected]96baf3e2012-10-22 23:09:551510 scoped_ptr<ScrollAndScaleSet> scrollInfo(new ScrollAndScaleSet());
[email protected]94f206c12012-08-25 00:09:141511
1512 if (m_pinchGestureActive || m_pageScaleAnimation) {
[email protected]1c0c9bc2012-10-08 22:41:481513 scrollInfo->pageScaleDelta = 1;
[email protected]a823df82013-01-10 02:38:171514 m_pinchZoomViewport.set_sent_page_scale_delta(1);
[email protected]f6250742012-11-09 04:46:561515 // FIXME(aelias): Make pinch-zoom painting optimization compatible with
[email protected]1c0c9bc2012-10-08 22:41:481516 // compositor-side scaling.
[email protected]9bdcfd642012-11-14 21:24:261517 if (!m_settings.pageScalePinchZoomEnabled && m_pinchGestureActive)
[email protected]f6250742012-11-09 04:46:561518 computePinchZoomDeltas(scrollInfo.get());
1519 else if (m_pageScaleAnimation.get())
1520 computeDoubleTapZoomDeltas(scrollInfo.get());
[email protected]a9f4bf22012-10-11 23:39:211521 return scrollInfo.Pass();
[email protected]94f206c12012-08-25 00:09:141522 }
1523
[email protected]3b31c6ac2012-12-06 21:27:291524 collectScrollDeltas(scrollInfo.get(), rootLayer());
[email protected]a823df82013-01-10 02:38:171525 scrollInfo->pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
1526 m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta);
[email protected]94f206c12012-08-25 00:09:141527
[email protected]a9f4bf22012-10-11 23:39:211528 return scrollInfo.Pass();
[email protected]94f206c12012-08-25 00:09:141529}
1530
[email protected]c8686a02012-11-27 08:29:001531gfx::Transform LayerTreeHostImpl::implTransform() const
[email protected]1c0c9bc2012-10-08 22:41:481532{
[email protected]a823df82013-01-10 02:38:171533 return m_pinchZoomViewport.ImplTransform(m_settings.pageScalePinchZoomEnabled);
[email protected]1c0c9bc2012-10-08 22:41:481534}
1535
[email protected]96baf3e2012-10-22 23:09:551536void LayerTreeHostImpl::setFullRootLayerDamage()
[email protected]94f206c12012-08-25 00:09:141537{
[email protected]3b31c6ac2012-12-06 21:27:291538 if (rootLayer()) {
1539 RenderSurfaceImpl* renderSurface = rootLayer()->renderSurface();
[email protected]94f206c12012-08-25 00:09:141540 if (renderSurface)
1541 renderSurface->damageTracker()->forceFullDamageNextUpdate();
1542 }
1543}
1544
[email protected]30faac92012-10-29 00:06:291545void LayerTreeHostImpl::animatePageScale(base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141546{
[email protected]3b31c6ac2012-12-06 21:27:291547 if (!m_pageScaleAnimation || !rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141548 return;
1549
[email protected]30faac92012-10-29 00:06:291550 double monotonicTime = (time - base::TimeTicks()).InSecondsF();
[email protected]3b31c6ac2012-12-06 21:27:291551 gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]94f206c12012-08-25 00:09:141552
[email protected]a823df82013-01-10 02:38:171553 setPageScaleDelta(m_pageScaleAnimation->pageScaleFactorAtTime(monotonicTime) / m_pinchZoomViewport.page_scale_factor());
[email protected]c9c1ebe2012-11-05 20:46:131554 gfx::Vector2dF nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime);
[email protected]f6250742012-11-09 04:46:561555
[email protected]9bdcfd642012-11-14 21:24:261556 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]a823df82013-01-10 02:38:171557 nextScroll.Scale(m_pinchZoomViewport.page_scale_factor());
[email protected]3b31c6ac2012-12-06 21:27:291558 rootScrollLayer()->scrollBy(nextScroll - scrollTotal);
[email protected]94f206c12012-08-25 00:09:141559 m_client->setNeedsRedrawOnImplThread();
1560
1561 if (m_pageScaleAnimation->isAnimationCompleteAtTime(monotonicTime)) {
[email protected]0023e8b2012-10-15 12:52:451562 m_pageScaleAnimation.reset();
[email protected]94f206c12012-08-25 00:09:141563 m_client->setNeedsCommitOnImplThread();
1564 }
1565}
1566
[email protected]30faac92012-10-29 00:06:291567void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime)
[email protected]94f206c12012-08-25 00:09:141568{
[email protected]de4afb5e2012-12-20 00:11:341569 if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty() || !rootLayer())
[email protected]94f206c12012-08-25 00:09:141570 return;
1571
[email protected]96baf3e2012-10-22 23:09:551572 TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers");
[email protected]94f206c12012-08-25 00:09:141573
[email protected]de4afb5e2012-12-20 00:11:341574 double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF();
[email protected]df1ec1a2012-12-08 17:01:181575
[email protected]de4afb5e2012-12-20 00:11:341576 scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
1577 AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers();
1578 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter)
1579 (*iter).second->animate(monotonicSeconds, events.get());
[email protected]94f206c12012-08-25 00:09:141580
[email protected]d3143c732012-10-05 19:17:591581 if (!events->empty())
[email protected]ec1d6d52012-10-10 01:28:571582 m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
[email protected]94f206c12012-08-25 00:09:141583
[email protected]de4afb5e2012-12-20 00:11:341584 m_client->setNeedsRedrawOnImplThread();
[email protected]de4afb5e2012-12-20 00:11:341585 setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141586}
1587
[email protected]96baf3e2012-10-22 23:09:551588base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const
[email protected]94f206c12012-08-25 00:09:141589{
[email protected]4481ddb622012-09-20 16:33:471590 return base::TimeDelta::FromSeconds(1);
[email protected]94f206c12012-08-25 00:09:141591}
1592
[email protected]3be2171d2012-12-06 06:13:201593void LayerTreeHostImpl::sendDidLoseOutputSurfaceRecursive(LayerImpl* current)
[email protected]94f206c12012-08-25 00:09:141594{
[email protected]1d993172012-10-18 18:15:041595 DCHECK(current);
[email protected]3be2171d2012-12-06 06:13:201596 current->didLoseOutputSurface();
[email protected]94f206c12012-08-25 00:09:141597 if (current->maskLayer())
[email protected]3be2171d2012-12-06 06:13:201598 sendDidLoseOutputSurfaceRecursive(current->maskLayer());
[email protected]94f206c12012-08-25 00:09:141599 if (current->replicaLayer())
[email protected]3be2171d2012-12-06 06:13:201600 sendDidLoseOutputSurfaceRecursive(current->replicaLayer());
[email protected]94f206c12012-08-25 00:09:141601 for (size_t i = 0; i < current->children().size(); ++i)
[email protected]3be2171d2012-12-06 06:13:201602 sendDidLoseOutputSurfaceRecursive(current->children()[i]);
[email protected]94f206c12012-08-25 00:09:141603}
1604
[email protected]96baf3e2012-10-22 23:09:551605void LayerTreeHostImpl::clearRenderSurfaces()
[email protected]94f206c12012-08-25 00:09:141606{
[email protected]76ffd9e2012-12-20 19:12:471607 activeTree()->ClearRenderSurfaces();
1608 if (pendingTree())
1609 pendingTree()->ClearRenderSurfaces();
[email protected]94f206c12012-08-25 00:09:141610}
1611
[email protected]96baf3e2012-10-22 23:09:551612std::string LayerTreeHostImpl::layerTreeAsText() const
[email protected]94f206c12012-08-25 00:09:141613{
[email protected]515e8d232012-09-10 19:15:271614 std::string str;
[email protected]3b31c6ac2012-12-06 21:27:291615 if (rootLayer()) {
1616 str = rootLayer()->layerTreeAsText();
[email protected]515e8d232012-09-10 19:15:271617 str += "RenderSurfaces:\n";
[email protected]3b31c6ac2012-12-06 21:27:291618 dumpRenderSurfaces(&str, 1, rootLayer());
[email protected]94f206c12012-08-25 00:09:141619 }
[email protected]515e8d232012-09-10 19:15:271620 return str;
[email protected]94f206c12012-08-25 00:09:141621}
1622
[email protected]4a23c374c2012-12-08 08:38:551623std::string LayerTreeHostImpl::layerTreeAsJson() const
1624{
1625 std::string str;
1626 if (rootLayer()) {
1627 scoped_ptr<base::Value> json(rootLayer()->layerTreeAsJson());
1628 base::JSONWriter::WriteWithOptions(
1629 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1630 }
1631 return str;
1632}
1633
[email protected]96baf3e2012-10-22 23:09:551634void LayerTreeHostImpl::dumpRenderSurfaces(std::string* str, int indent, const LayerImpl* layer) const
[email protected]94f206c12012-08-25 00:09:141635{
1636 if (layer->renderSurface())
[email protected]515e8d232012-09-10 19:15:271637 layer->renderSurface()->dumpSurface(str, indent);
[email protected]94f206c12012-08-25 00:09:141638
1639 for (size_t i = 0; i < layer->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031640 dumpRenderSurfaces(str, indent, layer->children()[i]);
[email protected]94f206c12012-08-25 00:09:141641}
1642
[email protected]96baf3e2012-10-22 23:09:551643int LayerTreeHostImpl::sourceAnimationFrameNumber() const
[email protected]94f206c12012-08-25 00:09:141644{
1645 return fpsCounter()->currentFrameNumber();
1646}
1647
[email protected]96baf3e2012-10-22 23:09:551648void LayerTreeHostImpl::renderingStats(RenderingStats* stats) const
[email protected]94f206c12012-08-25 00:09:141649{
[email protected]8b9af6b2012-09-27 00:36:361650 stats->numFramesSentToScreen = fpsCounter()->currentFrameNumber();
1651 stats->droppedFrameCount = fpsCounter()->droppedFrameCount();
[email protected]5c6fe1f82012-10-03 18:00:271652 stats->numImplThreadScrolls = m_numImplThreadScrolls;
1653 stats->numMainThreadScrolls = m_numMainThreadScrolls;
[email protected]b2136f12012-11-30 02:45:531654 stats->numLayersDrawn = m_cumulativeNumLayersDrawn;
[email protected]f2bbb4e2012-12-07 21:40:491655 stats->numMissingTiles = m_cumulativeNumMissingTiles;
[email protected]4d3c5c912012-11-30 05:55:021656
1657 if (m_tileManager)
[email protected]ee371e02012-12-16 20:13:441658 m_tileManager->GetRenderingStats(stats);
[email protected]94f206c12012-08-25 00:09:141659}
1660
[email protected]d3afa112012-12-08 06:24:281661void LayerTreeHostImpl::sendManagedMemoryStats(
1662 size_t memoryVisibleBytes,
1663 size_t memoryVisibleAndNearbyBytes,
1664 size_t memoryUseBytes)
1665{
1666 if (!renderer())
1667 return;
1668
1669 // Round the numbers being sent up to the next 8MB, to throttle the rate
1670 // at which we spam the GPU process.
1671 static const size_t roundingStep = 8 * 1024 * 1024;
1672 memoryVisibleBytes = RoundUp(memoryVisibleBytes, roundingStep);
1673 memoryVisibleAndNearbyBytes = RoundUp(memoryVisibleAndNearbyBytes, roundingStep);
1674 memoryUseBytes = RoundUp(memoryUseBytes, roundingStep);
1675 if (m_lastSentMemoryVisibleBytes == memoryVisibleBytes &&
1676 m_lastSentMemoryVisibleAndNearbyBytes == memoryVisibleAndNearbyBytes &&
1677 m_lastSentMemoryUseBytes == memoryUseBytes) {
1678 return;
1679 }
1680 m_lastSentMemoryVisibleBytes = memoryVisibleBytes;
1681 m_lastSentMemoryVisibleAndNearbyBytes = memoryVisibleAndNearbyBytes;
1682 m_lastSentMemoryUseBytes = memoryUseBytes;
1683
1684 renderer()->sendManagedMemoryStats(m_lastSentMemoryVisibleBytes,
1685 m_lastSentMemoryVisibleAndNearbyBytes,
1686 m_lastSentMemoryUseBytes);
1687}
1688
[email protected]30faac92012-10-29 00:06:291689void LayerTreeHostImpl::animateScrollbars(base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141690{
[email protected]3b31c6ac2012-12-06 21:27:291691 animateScrollbarsRecursive(rootLayer(), time);
[email protected]94f206c12012-08-25 00:09:141692}
1693
[email protected]30faac92012-10-29 00:06:291694void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141695{
1696 if (!layer)
1697 return;
1698
[email protected]96baf3e2012-10-22 23:09:551699 ScrollbarAnimationController* scrollbarController = layer->scrollbarAnimationController();
[email protected]e45638c2013-01-17 22:01:401700 if (scrollbarController && scrollbarController->animate(time))
[email protected]94f206c12012-08-25 00:09:141701 m_client->setNeedsRedrawOnImplThread();
1702
1703 for (size_t i = 0; i < layer->children().size(); ++i)
[email protected]30faac92012-10-29 00:06:291704 animateScrollbarsRecursive(layer->children()[i], time);
[email protected]94f206c12012-08-25 00:09:141705}
1706
[email protected]362f1e8b2013-01-21 16:54:301707void LayerTreeHostImpl::setTreePriority(TreePriority priority)
1708{
1709 if (!m_tileManager)
1710 return;
1711
1712 GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState());
1713 if (new_state.tree_priority == priority)
1714 return;
1715
[email protected]362f1e8b2013-01-21 16:54:301716 new_state.tree_priority = priority;
1717 m_tileManager->SetGlobalState(new_state);
1718}
1719
[email protected]b9dcf43a2013-01-09 00:15:291720// static
1721LayerImpl* LayerTreeHostImpl::getNonCompositedContentLayerRecursive(LayerImpl* layer)
1722{
1723 if (!layer)
1724 return NULL;
1725
1726 if (layer->drawsContent())
1727 return layer;
1728
1729 for (LayerImpl::LayerList::const_iterator it = layer->children().begin();
1730 it != layer->children().end(); ++it) {
1731 LayerImpl* nccr = getNonCompositedContentLayerRecursive(*it);
1732 if (nccr)
1733 return nccr;
1734 }
1735
1736 return NULL;
1737}
1738
1739skia::RefPtr<SkPicture> LayerTreeHostImpl::capturePicture()
1740{
1741 LayerTreeImpl* tree = pendingTree() ? pendingTree() : activeTree();
1742 LayerImpl* layer = getNonCompositedContentLayerRecursive(tree->RootLayer());
1743 return layer ? layer->getPicture() : skia::RefPtr<SkPicture>();
1744}
1745
[email protected]0edbfbe9f2013-01-17 03:33:031746void LayerTreeHostImpl::savePaintTime(const base::TimeDelta& totalPaintTime)
1747{
1748 m_paintTimeCounter->SavePaintTime(totalPaintTime);
1749}
1750
[email protected]d3143c732012-10-05 19:17:591751} // namespace cc