blob: 82e518f3502109fbd60f5c3fea2908186312c48d [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]d3afa112012-12-08 06:24:2842#include "cc/util.h"
[email protected]d455d552012-11-02 00:19:0643#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1344#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1445
[email protected]94f206c12012-08-25 00:09:1446namespace {
47
[email protected]96baf3e2012-10-22 23:09:5548void didVisibilityChange(cc::LayerTreeHostImpl* id, bool visible)
[email protected]94f206c12012-08-25 00:09:1449{
50 if (visible) {
[email protected]96baf3e2012-10-22 23:09:5551 TRACE_EVENT_ASYNC_BEGIN1("webkit", "LayerTreeHostImpl::setVisible", id, "LayerTreeHostImpl", id);
[email protected]94f206c12012-08-25 00:09:1452 return;
53 }
54
[email protected]96baf3e2012-10-22 23:09:5555 TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::setVisible", id);
[email protected]94f206c12012-08-25 00:09:1456}
57
58} // namespace
59
[email protected]9c88e562012-09-14 22:21:3060namespace cc {
[email protected]94f206c12012-08-25 00:09:1461
[email protected]96baf3e2012-10-22 23:09:5562class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
[email protected]94f206c12012-08-25 00:09:1463public:
[email protected]96baf3e2012-10-22 23:09:5564 static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> create(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource)
[email protected]94f206c12012-08-25 00:09:1465 {
[email protected]96baf3e2012-10-22 23:09:5566 return make_scoped_ptr(new LayerTreeHostImplTimeSourceAdapter(layerTreeHostImpl, timeSource));
[email protected]94f206c12012-08-25 00:09:1467 }
[email protected]96baf3e2012-10-22 23:09:5568 virtual ~LayerTreeHostImplTimeSourceAdapter()
[email protected]94f206c12012-08-25 00:09:1469 {
70 m_timeSource->setClient(0);
71 m_timeSource->setActive(false);
72 }
73
74 virtual void onTimerTick() OVERRIDE
75 {
[email protected]373974232013-01-10 22:20:5076 // In single threaded mode we attempt to simulate changing the current
77 // thread by maintaining a fake thread id. When we switch from one
78 // thread to another, we construct DebugScopedSetXXXThread objects that
79 // update the thread id. This lets DCHECKS that ensure we're on the
80 // right thread to work correctly in single threaded mode. The problem
81 // here is that the timer tasks are run via the message loop, and when
82 // they run, we've had no chance to construct a DebugScopedSetXXXThread
83 // object. The result is that we report that we're running on the main
84 // thread. In multi-threaded mode, this timer is run on the compositor
85 // thread, so to keep this consistent in single-threaded mode, we'll
86 // construct a DebugScopedSetImplThread object. There is no need to do
87 // this in multi-threaded mode since the real thread id's will be
88 // correct. In fact, setting fake thread id's interferes with the real
89 // thread id's and causes breakage.
90 scoped_ptr<DebugScopedSetImplThread> setImplThread;
91 if (!m_layerTreeHostImpl->proxy()->hasImplThread())
92 setImplThread.reset(new DebugScopedSetImplThread(m_layerTreeHostImpl->proxy()));
93
[email protected]eabe5002013-01-12 22:07:4894 m_layerTreeHostImpl->activatePendingTreeIfNeeded();
[email protected]30faac92012-10-29 00:06:2995 m_layerTreeHostImpl->animate(base::TimeTicks::Now(), base::Time::Now());
[email protected]94f206c12012-08-25 00:09:1496 }
97
98 void setActive(bool active)
99 {
100 if (active != m_timeSource->active())
101 m_timeSource->setActive(active);
102 }
103
104private:
[email protected]96baf3e2012-10-22 23:09:55105 LayerTreeHostImplTimeSourceAdapter(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource)
[email protected]94f206c12012-08-25 00:09:14106 : m_layerTreeHostImpl(layerTreeHostImpl)
107 , m_timeSource(timeSource)
108 {
109 m_timeSource->setClient(this);
110 }
111
[email protected]96baf3e2012-10-22 23:09:55112 LayerTreeHostImpl* m_layerTreeHostImpl;
113 scoped_refptr<DelayBasedTimeSource> m_timeSource;
[email protected]fd2d4f22012-09-28 22:57:20114
[email protected]96baf3e2012-10-22 23:09:55115 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
[email protected]94f206c12012-08-25 00:09:14116};
117
[email protected]96baf3e2012-10-22 23:09:55118LayerTreeHostImpl::FrameData::FrameData()
[email protected]493067512012-09-19 23:34:10119{
120}
121
[email protected]96baf3e2012-10-22 23:09:55122LayerTreeHostImpl::FrameData::~FrameData()
[email protected]493067512012-09-19 23:34:10123{
124}
125
[email protected]61de5812012-11-08 07:03:44126scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::create(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy)
[email protected]94f206c12012-08-25 00:09:14127{
[email protected]61de5812012-11-08 07:03:44128 return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy));
[email protected]94f206c12012-08-25 00:09:14129}
130
[email protected]61de5812012-11-08 07:03:44131LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy)
[email protected]94f206c12012-08-25 00:09:14132 : m_client(client)
[email protected]61de5812012-11-08 07:03:44133 , m_proxy(proxy)
[email protected]31bfe272012-10-19 18:49:52134 , m_scrollDeltaIsInViewportSpace(false)
[email protected]94f206c12012-08-25 00:09:14135 , m_settings(settings)
[email protected]f511afb2012-11-30 01:55:20136 , m_debugState(settings.initialDebugState)
[email protected]94f206c12012-08-25 00:09:14137 , m_deviceScaleFactor(1)
138 , m_visible(true)
[email protected]3b10a302012-11-07 21:16:40139 , m_managedMemoryPolicy(PrioritizedResourceManager::defaultMemoryAllocationLimit(),
[email protected]9b0b79a02013-01-02 22:47:27140 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
[email protected]a0a00842012-10-22 22:50:28141 0,
[email protected]9b0b79a02013-01-02 22:47:27142 ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING)
[email protected]0ede3bb2012-12-09 09:14:39143 , m_needsUpdateDrawProperties(false)
[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.
177 m_activeTree.reset();
178 m_pendingTree.reset();
179 }
[email protected]94f206c12012-08-25 00:09:14180}
181
[email protected]96baf3e2012-10-22 23:09:55182void LayerTreeHostImpl::beginCommit()
[email protected]94f206c12012-08-25 00:09:14183{
184}
185
[email protected]96baf3e2012-10-22 23:09:55186void LayerTreeHostImpl::commitComplete()
[email protected]94f206c12012-08-25 00:09:14187{
[email protected]96baf3e2012-10-22 23:09:55188 TRACE_EVENT0("cc", "LayerTreeHostImpl::commitComplete");
[email protected]0ede3bb2012-12-09 09:14:39189
190 // Impl-side painting needs an update immediately post-commit to have the
191 // opportunity to create tilings. Other paths can call updateDrawProperties
192 // more lazily when needed prior to drawing.
193 setNeedsUpdateDrawProperties();
194 if (m_settings.implSidePainting)
195 updateDrawProperties();
196
[email protected]94f206c12012-08-25 00:09:14197 // Recompute max scroll position; must be after layer content bounds are
198 // updated.
[email protected]c9c1ebe2012-11-05 20:46:13199 updateMaxScrollOffset();
[email protected]3d21e022012-10-25 20:03:08200 m_client->sendManagedMemoryStats();
[email protected]94f206c12012-08-25 00:09:14201}
202
[email protected]96baf3e2012-10-22 23:09:55203bool LayerTreeHostImpl::canDraw()
[email protected]94f206c12012-08-25 00:09:14204{
[email protected]8db2213c2012-09-05 22:08:21205 // Note: If you are changing this function or any other function that might
206 // affect the result of canDraw, make sure to call m_client->onCanDrawStateChanged
207 // in the proper places and update the notifyIfCanDrawChanged test.
208
[email protected]3b31c6ac2012-12-06 21:27:29209 if (!rootLayer()) {
[email protected]96baf3e2012-10-22 23:09:55210 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no root layer");
[email protected]94f206c12012-08-25 00:09:14211 return false;
212 }
[email protected]aad0a0072012-11-01 18:15:58213 if (deviceViewportSize().IsEmpty()) {
[email protected]96baf3e2012-10-22 23:09:55214 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw empty viewport");
[email protected]94f206c12012-08-25 00:09:14215 return false;
216 }
217 if (!m_renderer) {
[email protected]96baf3e2012-10-22 23:09:55218 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no renderer");
[email protected]94f206c12012-08-25 00:09:14219 return false;
220 }
[email protected]6f90b9e2013-01-17 23:42:00221 if (m_activeTree->ContentsTexturesPurged()) {
[email protected]96baf3e2012-10-22 23:09:55222 TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw contents textures purged");
[email protected]94f206c12012-08-25 00:09:14223 return false;
224 }
225 return true;
226}
227
[email protected]3be2171d2012-12-06 06:13:20228OutputSurface* LayerTreeHostImpl::outputSurface() const
[email protected]94f206c12012-08-25 00:09:14229{
[email protected]3be2171d2012-12-06 06:13:20230 return m_outputSurface.get();
[email protected]94f206c12012-08-25 00:09:14231}
232
[email protected]30faac92012-10-29 00:06:29233void LayerTreeHostImpl::animate(base::TimeTicks monotonicTime, base::Time wallClockTime)
[email protected]94f206c12012-08-25 00:09:14234{
235 animatePageScale(monotonicTime);
236 animateLayers(monotonicTime, wallClockTime);
[email protected]94f206c12012-08-25 00:09:14237 animateScrollbars(monotonicTime);
[email protected]3ba4cae2013-01-16 03:58:38238 if (m_topControlsManager)
239 m_topControlsManager->Animate(monotonicTime);
[email protected]94f206c12012-08-25 00:09:14240}
241
[email protected]8947cbe2012-11-28 05:27:43242void LayerTreeHostImpl::manageTiles()
243{
244 DCHECK(m_tileManager);
245 m_tileManager->ManageTiles();
[email protected]9b0b79a02013-01-02 22:47:27246
247 size_t memoryRequiredBytes;
248 size_t memoryNiceToHaveBytes;
249 size_t memoryUsedBytes;
250 m_tileManager->GetMemoryStats(&memoryRequiredBytes,
251 &memoryNiceToHaveBytes,
252 &memoryUsedBytes);
253 sendManagedMemoryStats(memoryRequiredBytes,
254 memoryNiceToHaveBytes,
255 memoryUsedBytes);
[email protected]8947cbe2012-11-28 05:27:43256}
257
[email protected]69a2a5be2012-11-14 06:51:44258void LayerTreeHostImpl::startPageScaleAnimation(gfx::Vector2d targetOffset, bool anchorPoint, float pageScale, base::TimeTicks startTime, base::TimeDelta duration)
[email protected]94f206c12012-08-25 00:09:14259{
[email protected]3b31c6ac2012-12-06 21:27:29260 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:14261 return;
262
[email protected]3b31c6ac2012-12-06 21:27:29263 gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]42ccdbef2013-01-21 07:54:54264 gfx::SizeF scaledScrollableSize = activeTree()->ScrollableSize();
[email protected]9bdcfd642012-11-14 21:24:26265 if (!m_settings.pageScalePinchZoomEnabled) {
[email protected]a823df82013-01-10 02:38:17266 scrollTotal.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]42ccdbef2013-01-21 07:54:54267 scaledScrollableSize.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]f6250742012-11-09 04:46:56268 }
[email protected]01a15a72012-11-10 09:34:28269 gfx::SizeF viewportSize = gfx::ScaleSize(m_deviceViewportSize, 1 / m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:14270
[email protected]30faac92012-10-29 00:06:29271 double startTimeSeconds = (startTime - base::TimeTicks()).InSecondsF();
[email protected]42ccdbef2013-01-21 07:54:54272 m_pageScaleAnimation = PageScaleAnimation::create(scrollTotal, m_pinchZoomViewport.total_page_scale_factor(), viewportSize, scaledScrollableSize, startTimeSeconds);
[email protected]94f206c12012-08-25 00:09:14273
274 if (anchorPoint) {
[email protected]69a2a5be2012-11-14 06:51:44275 gfx::Vector2dF anchor(targetOffset);
[email protected]9bdcfd642012-11-14 21:24:26276 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]f6250742012-11-09 04:46:56277 anchor.Scale(1 / pageScale);
278 m_pageScaleAnimation->zoomWithAnchor(anchor, pageScale, duration.InSecondsF());
279 } else {
[email protected]69a2a5be2012-11-14 06:51:44280 gfx::Vector2dF scaledTargetOffset = targetOffset;
[email protected]9bdcfd642012-11-14 21:24:26281 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]69a2a5be2012-11-14 06:51:44282 scaledTargetOffset.Scale(1 / pageScale);
283 m_pageScaleAnimation->zoomTo(scaledTargetOffset, pageScale, duration.InSecondsF());
[email protected]f6250742012-11-09 04:46:56284 }
[email protected]94f206c12012-08-25 00:09:14285
[email protected]0ede3bb2012-12-09 09:14:39286 setNeedsUpdateDrawProperties();
[email protected]94f206c12012-08-25 00:09:14287 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]0ede3bb2012-12-09 09:14:39330void LayerTreeHostImpl::updateDrawProperties()
331{
332 if (!needsUpdateDrawProperties())
333 return;
334
[email protected]76ffd9e2012-12-20 19:12:47335 if (!m_renderer) { // For maxTextureSize.
336 // This will get set if renderer gets initialized.
337 m_needsUpdateDrawProperties = false;
[email protected]2d692992012-12-19 01:19:32338 return;
[email protected]94f206c12012-08-25 00:09:14339 }
[email protected]2e7ca422012-12-20 02:57:27340
[email protected]3ba4cae2013-01-16 03:58:38341 if (m_topControlsManager)
342 m_topControlsManager->UpdateDrawPositions();
[email protected]76ffd9e2012-12-20 19:12:47343 activeTree()->UpdateDrawProperties();
344 if (pendingTree())
345 pendingTree()->UpdateDrawProperties();
346
347 m_needsUpdateDrawProperties = false;
[email protected]94f206c12012-08-25 00:09:14348}
349
[email protected]96baf3e2012-10-22 23:09:55350void LayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<RenderPass> renderPass)
[email protected]467b3612012-08-28 07:41:16351{
[email protected]20062042012-12-21 22:16:36352 renderPassesById[renderPass->id] = renderPass.get();
[email protected]ead39c52013-01-09 07:22:45353 renderPasses.push_back(renderPass.Pass());
[email protected]f57bbc02012-11-21 07:02:15354}
355
356static void appendQuadsForLayer(RenderPass* targetRenderPass, LayerImpl* layer, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData)
357{
358 bool forSurface = false;
359 QuadCuller quadCuller(targetRenderPass->quad_list,
360 targetRenderPass->shared_quad_state_list,
361 layer,
362 occlusionTracker,
363 layer->showDebugBorders(),
364 forSurface);
365 layer->appendQuads(quadCuller, appendQuadsData);
366}
367
368static void appendQuadsForRenderSurfaceLayer(RenderPass* targetRenderPass, LayerImpl* layer, const RenderPass* contributingRenderPass, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData)
369{
370 bool forSurface = true;
371 QuadCuller quadCuller(targetRenderPass->quad_list,
372 targetRenderPass->shared_quad_state_list,
373 layer,
374 occlusionTracker,
375 layer->showDebugBorders(),
376 forSurface);
377
378 bool isReplica = false;
379 layer->renderSurface()->appendQuads(quadCuller,
380 appendQuadsData,
381 isReplica,
382 contributingRenderPass->id);
383
384 // Add replica after the surface so that it appears below the surface.
385 if (layer->hasReplica()) {
386 isReplica = true;
387 layer->renderSurface()->appendQuads(quadCuller,
388 appendQuadsData,
389 isReplica,
390 contributingRenderPass->id);
391 }
392}
393
394static void appendQuadsToFillScreen(RenderPass* targetRenderPass, LayerImpl* rootLayer, SkColor screenBackgroundColor, const OcclusionTrackerImpl& occlusionTracker)
395{
396 if (!rootLayer || !SkColorGetA(screenBackgroundColor))
397 return;
398
399 Region fillRegion = occlusionTracker.computeVisibleRegionInScreen();
400 if (fillRegion.IsEmpty())
401 return;
402
403 bool forSurface = false;
404 QuadCuller quadCuller(targetRenderPass->quad_list,
405 targetRenderPass->shared_quad_state_list,
406 rootLayer,
407 occlusionTracker,
408 rootLayer->showDebugBorders(),
409 forSurface);
410
411 // Manually create the quad state for the gutter quads, as the root layer
412 // doesn't have any bounds and so can't generate this itself.
413 // FIXME: Make the gutter quads generated by the solid color layer (make it smarter about generating quads to fill unoccluded areas).
414
[email protected]f57bbc02012-11-21 07:02:15415 gfx::Rect rootTargetRect = rootLayer->renderSurface()->contentRect();
416 float opacity = 1;
417 SharedQuadState* sharedQuadState = quadCuller.useSharedQuadState(SharedQuadState::Create());
418 sharedQuadState->SetAll(rootLayer->drawTransform(),
419 rootTargetRect,
420 rootTargetRect,
[email protected]dc462d782012-11-21 21:43:01421 rootTargetRect,
422 false,
[email protected]f57bbc02012-11-21 07:02:15423 opacity);
424
425 AppendQuadsData appendQuadsData;
[email protected]bda41962013-01-07 18:46:17426
427 gfx::Transform transformToLayerSpace(gfx::Transform::kSkipInitialization);
428 bool didInvert = rootLayer->screenSpaceTransform().GetInverse(&transformToLayerSpace);
429 DCHECK(didInvert);
[email protected]f57bbc02012-11-21 07:02:15430 for (Region::Iterator fillRects(fillRegion); fillRects.has_rect(); fillRects.next()) {
431 // The root layer transform is composed of translations and scales only,
[email protected]bda41962013-01-07 18:46:17432 // no perspective, so mapping is sufficient (as opposed to projecting).
[email protected]f57bbc02012-11-21 07:02:15433 gfx::Rect layerRect = MathUtil::mapClippedRect(transformToLayerSpace, fillRects.rect());
434 // Skip the quad culler and just append the quads directly to avoid
435 // occlusion checks.
436 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
437 quad->SetNew(sharedQuadState, layerRect, screenBackgroundColor);
438 quadCuller.append(quad.PassAs<DrawQuad>(), appendQuadsData);
439 }
[email protected]467b3612012-08-28 07:41:16440}
441
[email protected]96baf3e2012-10-22 23:09:55442bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14443{
[email protected]ead39c52013-01-09 07:22:45444 DCHECK(frame.renderPasses.empty());
[email protected]94f206c12012-08-25 00:09:14445
[email protected]2e7ca422012-12-20 02:57:27446 if (!canDraw() || !rootLayer())
[email protected]2d692992012-12-19 01:19:32447 return false;
448
[email protected]0ede3bb2012-12-09 09:14:39449 trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList);
[email protected]94f206c12012-08-25 00:09:14450
[email protected]96baf3e2012-10-22 23:09:55451 TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList->size()));
[email protected]94f206c12012-08-25 00:09:14452
453 // Create the render passes in dependency order.
[email protected]94f206c12012-08-25 00:09:14454 for (int surfaceIndex = frame.renderSurfaceLayerList->size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
[email protected]96baf3e2012-10-22 23:09:55455 LayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceIndex];
[email protected]467b3612012-08-28 07:41:16456 renderSurfaceLayer->renderSurface()->appendRenderPasses(frame);
[email protected]94f206c12012-08-25 00:09:14457 }
458
[email protected]9bdcfd642012-11-14 21:24:26459 bool recordMetricsForFrame = m_settings.showOverdrawInTracing && base::debug::TraceLog::GetInstance() && base::debug::TraceLog::GetInstance()->IsEnabled();
[email protected]3b31c6ac2012-12-06 21:27:29460 OcclusionTrackerImpl occlusionTracker(rootLayer()->renderSurface()->contentRect(), recordMetricsForFrame);
[email protected]94f206c12012-08-25 00:09:14461 occlusionTracker.setMinimumTrackingSize(m_settings.minimumOcclusionTrackingSize);
462
[email protected]f511afb2012-11-30 01:55:20463 if (m_debugState.showOccludingRects)
[email protected]94f206c12012-08-25 00:09:14464 occlusionTracker.setOccludingScreenSpaceRectsContainer(&frame.occludingScreenSpaceRects);
[email protected]f511afb2012-11-30 01:55:20465 if (m_debugState.showNonOccludingRects)
[email protected]4d8804e2012-11-15 01:51:10466 occlusionTracker.setNonOccludingScreenSpaceRectsContainer(&frame.nonOccludingScreenSpaceRects);
[email protected]94f206c12012-08-25 00:09:14467
468 // 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:55469 typedef LayerIterator<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerIteratorActions::FrontToBack> LayerIteratorType;
[email protected]94f206c12012-08-25 00:09:14470
471 // Typically when we are missing a texture and use a checkerboard quad, we still draw the frame. However when the layer being
472 // checkerboarded is moving due to an impl-animation, we drop the frame to avoid flashing due to the texture suddenly appearing
473 // in the future.
474 bool drawFrame = true;
475
[email protected]96baf3e2012-10-22 23:09:55476 LayerIteratorType end = LayerIteratorType::end(frame.renderSurfaceLayerList);
477 for (LayerIteratorType it = LayerIteratorType::begin(frame.renderSurfaceLayerList); it != end; ++it) {
478 RenderPass::Id targetRenderPassId = it.targetRenderSurfaceLayer()->renderSurface()->renderPassId();
[email protected]20062042012-12-21 22:16:36479 RenderPass* targetRenderPass = frame.renderPassesById[targetRenderPassId];
[email protected]94f206c12012-08-25 00:09:14480
481 occlusionTracker.enterLayer(it);
482
[email protected]f57bbc02012-11-21 07:02:15483 AppendQuadsData appendQuadsData(targetRenderPass->id);
[email protected]89228202012-08-29 03:20:30484
[email protected]94f206c12012-08-25 00:09:14485 if (it.representsContributingRenderSurface()) {
[email protected]96baf3e2012-10-22 23:09:55486 RenderPass::Id contributingRenderPassId = it->renderSurface()->renderPassId();
[email protected]20062042012-12-21 22:16:36487 RenderPass* contributingRenderPass = frame.renderPassesById[contributingRenderPassId];
[email protected]f57bbc02012-11-21 07:02:15488 appendQuadsForRenderSurfaceLayer(targetRenderPass, *it, contributingRenderPass, occlusionTracker, appendQuadsData);
[email protected]aad0a0072012-11-01 18:15:58489 } else if (it.representsItself() && !it->visibleContentRect().IsEmpty()) {
[email protected]94f206c12012-08-25 00:09:14490 bool hasOcclusionFromOutsideTargetSurface;
[email protected]710ffc02012-10-30 21:42:02491 bool implDrawTransformIsUnknown = false;
492 if (occlusionTracker.occluded(it->renderTarget(), it->visibleContentRect(), it->drawTransform(), implDrawTransformIsUnknown, it->drawableContentRect(), &hasOcclusionFromOutsideTargetSurface))
[email protected]89228202012-08-29 03:20:30493 appendQuadsData.hadOcclusionFromOutsideTargetSurface |= hasOcclusionFromOutsideTargetSurface;
494 else {
[email protected]2e7ca422012-12-20 02:57:27495 DCHECK_EQ(activeTree(), it->layerTreeImpl());
[email protected]94f206c12012-08-25 00:09:14496 it->willDraw(m_resourceProvider.get());
[email protected]d58499a2012-10-09 22:27:47497 frame.willDrawLayers.push_back(*it);
[email protected]7d929c02012-09-20 17:26:57498
499 if (it->hasContributingDelegatedRenderPasses()) {
[email protected]96baf3e2012-10-22 23:09:55500 RenderPass::Id contributingRenderPassId = it->firstContributingRenderPassId();
[email protected]20062042012-12-21 22:16:36501 while (frame.renderPassesById.find(contributingRenderPassId) != frame.renderPassesById.end()) {
502 RenderPass* renderPass = frame.renderPassesById[contributingRenderPassId];
[email protected]7d929c02012-09-20 17:26:57503
[email protected]f57bbc02012-11-21 07:02:15504 AppendQuadsData appendQuadsData(renderPass->id);
505 appendQuadsForLayer(renderPass, *it, occlusionTracker, appendQuadsData);
[email protected]7d929c02012-09-20 17:26:57506
507 contributingRenderPassId = it->nextContributingRenderPassId(contributingRenderPassId);
508 }
509 }
510
[email protected]f57bbc02012-11-21 07:02:15511 appendQuadsForLayer(targetRenderPass, *it, occlusionTracker, appendQuadsData);
[email protected]94f206c12012-08-25 00:09:14512 }
[email protected]9c2be6a2012-11-27 19:16:10513
[email protected]b2136f12012-11-30 02:45:53514 ++m_cumulativeNumLayersDrawn;
[email protected]94f206c12012-08-25 00:09:14515 }
516
[email protected]89228202012-08-29 03:20:30517 if (appendQuadsData.hadOcclusionFromOutsideTargetSurface)
[email protected]f57bbc02012-11-21 07:02:15518 targetRenderPass->has_occlusion_from_outside_target_surface = true;
[email protected]89228202012-08-29 03:20:30519
[email protected]f2bbb4e2012-12-07 21:40:49520 if (appendQuadsData.numMissingTiles) {
521 m_cumulativeNumMissingTiles += appendQuadsData.numMissingTiles;
[email protected]94f206c12012-08-25 00:09:14522 bool layerHasAnimatingTransform = it->screenSpaceTransformIsAnimating() || it->drawTransformIsAnimating();
[email protected]22619922012-11-14 17:58:10523 if (layerHasAnimatingTransform)
[email protected]94f206c12012-08-25 00:09:14524 drawFrame = false;
525 }
526
527 occlusionTracker.leaveLayer(it);
528 }
529
[email protected]1d993172012-10-18 18:15:04530#ifndef NDEBUG
[email protected]94f206c12012-08-25 00:09:14531 for (size_t i = 0; i < frame.renderPasses.size(); ++i) {
[email protected]f57bbc02012-11-21 07:02:15532 for (size_t j = 0; j < frame.renderPasses[i]->quad_list.size(); ++j)
533 DCHECK(frame.renderPasses[i]->quad_list[j]->shared_quad_state);
[email protected]20062042012-12-21 22:16:36534 DCHECK(frame.renderPassesById.find(frame.renderPasses[i]->id)
535 != frame.renderPassesById.end());
[email protected]94f206c12012-08-25 00:09:14536 }
537#endif
[email protected]217a89a2013-01-20 19:55:39538 DCHECK(frame.renderPasses.back()->output_rect.origin().IsOrigin());
[email protected]94f206c12012-08-25 00:09:14539
[email protected]a30290142013-01-05 01:27:00540 if (!activeTree()->has_transparent_background()) {
[email protected]ead39c52013-01-09 07:22:45541 frame.renderPasses.back()->has_transparent_background = false;
542 appendQuadsToFillScreen(frame.renderPasses.back(), rootLayer(), activeTree()->background_color(), occlusionTracker);
[email protected]94f206c12012-08-25 00:09:14543 }
544
545 if (drawFrame)
546 occlusionTracker.overdrawMetrics().recordMetrics(this);
547
548 removeRenderPasses(CullRenderPassesWithNoQuads(), frame);
549 m_renderer->decideRenderPassAllocationsForFrame(frame.renderPasses);
550 removeRenderPasses(CullRenderPassesWithCachedTextures(*m_renderer), frame);
551
552 return drawFrame;
553}
554
[email protected]96baf3e2012-10-22 23:09:55555void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled)
[email protected]94f206c12012-08-25 00:09:14556{
557 // Lazily create the timeSource adapter so that we can vary the interval for testing.
558 if (!m_timeSourceClientAdapter)
[email protected]61de5812012-11-08 07:03:44559 m_timeSourceClientAdapter = LayerTreeHostImplTimeSourceAdapter::create(this, DelayBasedTimeSource::create(lowFrequencyAnimationInterval(), m_proxy->currentThread()));
[email protected]94f206c12012-08-25 00:09:14560
561 m_timeSourceClientAdapter->setActive(enabled);
562}
563
[email protected]96baf3e2012-10-22 23:09:55564static inline RenderPass* findRenderPassById(RenderPass::Id renderPassId, const LayerTreeHostImpl::FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14565{
[email protected]96baf3e2012-10-22 23:09:55566 RenderPassIdHashMap::const_iterator it = frame.renderPassesById.find(renderPassId);
[email protected]20062042012-12-21 22:16:36567 return it != frame.renderPassesById.end() ? it->second : NULL;
[email protected]94f206c12012-08-25 00:09:14568}
569
[email protected]96baf3e2012-10-22 23:09:55570static void removeRenderPassesRecursive(RenderPass::Id removeRenderPassId, LayerTreeHostImpl::FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14571{
[email protected]96baf3e2012-10-22 23:09:55572 RenderPass* removeRenderPass = findRenderPassById(removeRenderPassId, frame);
[email protected]20062042012-12-21 22:16:36573 // The pass was already removed by another quad - probably the original, and we are the replica.
574 if (!removeRenderPass)
575 return;
[email protected]96baf3e2012-10-22 23:09:55576 RenderPassList& renderPasses = frame.renderPasses;
577 RenderPassList::iterator toRemove = std::find(renderPasses.begin(), renderPasses.end(), removeRenderPass);
[email protected]94f206c12012-08-25 00:09:14578
[email protected]20062042012-12-21 22:16:36579 DCHECK(toRemove != renderPasses.end());
[email protected]94f206c12012-08-25 00:09:14580
[email protected]ead39c52013-01-09 07:22:45581 scoped_ptr<RenderPass> removedPass = renderPasses.take(toRemove);
582 frame.renderPasses.erase(toRemove);
[email protected]20062042012-12-21 22:16:36583 frame.renderPassesById.erase(removeRenderPassId);
[email protected]94f206c12012-08-25 00:09:14584
585 // Now follow up for all RenderPass quads and remove their RenderPasses recursively.
[email protected]f57bbc02012-11-21 07:02:15586 const QuadList& quadList = removedPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55587 QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14588 for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
[email protected]96baf3e2012-10-22 23:09:55589 DrawQuad* currentQuad = (*quadListIterator);
[email protected]1bc93f62012-11-17 19:29:50590 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14591 continue;
592
[email protected]c22418b2012-11-20 23:06:26593 RenderPass::Id nextRemoveRenderPassId = RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id;
[email protected]94f206c12012-08-25 00:09:14594 removeRenderPassesRecursive(nextRemoveRenderPassId, frame);
595 }
596}
597
[email protected]96baf3e2012-10-22 23:09:55598bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData&) const
[email protected]94f206c12012-08-25 00:09:14599{
[email protected]ec2eb5f2012-12-16 04:42:27600 if (!quad.contents_changed_since_last_frame.IsEmpty()) {
601 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage");
602 return false;
603 } else if (!m_renderer.haveCachedResourcesForRenderPassId(quad.render_pass_id)) {
604 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture");
605 return false;
606 }
607 TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!");
608 return true;
[email protected]94f206c12012-08-25 00:09:14609}
610
[email protected]96baf3e2012-10-22 23:09:55611bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData& frame) const
[email protected]94f206c12012-08-25 00:09:14612{
[email protected]c22418b2012-11-20 23:06:26613 const RenderPass* renderPass = findRenderPassById(quad.render_pass_id, frame);
[email protected]20062042012-12-21 22:16:36614 if (!renderPass)
[email protected]94f206c12012-08-25 00:09:14615 return false;
616
617 // If any quad or RenderPass draws into this RenderPass, then keep it.
[email protected]20062042012-12-21 22:16:36618 const QuadList& quadList = renderPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55619 for (QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
620 DrawQuad* currentQuad = *quadListIterator;
[email protected]94f206c12012-08-25 00:09:14621
[email protected]1bc93f62012-11-17 19:29:50622 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14623 return false;
624
[email protected]c22418b2012-11-20 23:06:26625 const RenderPass* contributingPass = findRenderPassById(RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id, frame);
[email protected]20062042012-12-21 22:16:36626 if (contributingPass)
[email protected]94f206c12012-08-25 00:09:14627 return false;
628 }
629 return true;
630}
631
632// Defined for linking tests.
[email protected]52347c842012-11-02 21:06:20633template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(CullRenderPassesWithCachedTextures, FrameData&);
634template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithNoQuads>(CullRenderPassesWithNoQuads, FrameData&);
[email protected]94f206c12012-08-25 00:09:14635
636// static
637template<typename RenderPassCuller>
[email protected]96baf3e2012-10-22 23:09:55638void LayerTreeHostImpl::removeRenderPasses(RenderPassCuller culler, FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14639{
640 for (size_t it = culler.renderPassListBegin(frame.renderPasses); it != culler.renderPassListEnd(frame.renderPasses); it = culler.renderPassListNext(it)) {
[email protected]96baf3e2012-10-22 23:09:55641 const RenderPass* currentPass = frame.renderPasses[it];
[email protected]f57bbc02012-11-21 07:02:15642 const QuadList& quadList = currentPass->quad_list;
[email protected]96baf3e2012-10-22 23:09:55643 QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
[email protected]94f206c12012-08-25 00:09:14644
645 for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
[email protected]96baf3e2012-10-22 23:09:55646 DrawQuad* currentQuad = *quadListIterator;
[email protected]94f206c12012-08-25 00:09:14647
[email protected]1bc93f62012-11-17 19:29:50648 if (currentQuad->material != DrawQuad::RENDER_PASS)
[email protected]94f206c12012-08-25 00:09:14649 continue;
650
[email protected]96baf3e2012-10-22 23:09:55651 RenderPassDrawQuad* renderPassQuad = static_cast<RenderPassDrawQuad*>(currentQuad);
[email protected]94f206c12012-08-25 00:09:14652 if (!culler.shouldRemoveRenderPass(*renderPassQuad, frame))
653 continue;
654
655 // We are changing the vector in the middle of iteration. Because we
656 // delete render passes that draw into the current pass, we are
657 // guaranteed that any data from the iterator to the end will not
658 // change. So, capture the iterator position from the end of the
659 // list, and restore it after the change.
660 int positionFromEnd = frame.renderPasses.size() - it;
[email protected]c22418b2012-11-20 23:06:26661 removeRenderPassesRecursive(renderPassQuad->render_pass_id, frame);
[email protected]94f206c12012-08-25 00:09:14662 it = frame.renderPasses.size() - positionFromEnd;
[email protected]1d993172012-10-18 18:15:04663 DCHECK(it >= 0);
[email protected]94f206c12012-08-25 00:09:14664 }
665 }
666}
667
[email protected]96baf3e2012-10-22 23:09:55668bool LayerTreeHostImpl::prepareToDraw(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14669{
[email protected]96baf3e2012-10-22 23:09:55670 TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw");
[email protected]94f206c12012-08-25 00:09:14671
[email protected]76ffd9e2012-12-20 19:12:47672 updateDrawProperties();
[email protected]2e7ca422012-12-20 02:57:27673
[email protected]76ffd9e2012-12-20 19:12:47674 frame.renderSurfaceLayerList = &activeTree()->RenderSurfaceLayerList();
[email protected]94f206c12012-08-25 00:09:14675 frame.renderPasses.clear();
676 frame.renderPassesById.clear();
[email protected]94f206c12012-08-25 00:09:14677 frame.willDrawLayers.clear();
678
679 if (!calculateRenderPasses(frame))
680 return false;
681
682 // If we return true, then we expect drawLayers() to be called before this function is called again.
683 return true;
684}
685
[email protected]96baf3e2012-10-22 23:09:55686void LayerTreeHostImpl::enforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy)
[email protected]94f206c12012-08-25 00:09:14687{
[email protected]a0a00842012-10-22 22:50:28688 bool evictedResources = m_client->reduceContentsTextureMemoryOnImplThread(
689 m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible,
[email protected]9b0b79a02013-01-02 22:47:27690 ManagedMemoryPolicy::priorityCutoffToValue(
691 m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible));
[email protected]b1969fa2012-10-17 20:16:29692 if (evictedResources) {
[email protected]6f90b9e2013-01-17 23:42:00693 activeTree()->SetContentsTexturesPurged();
694 if (pendingTree())
695 pendingTree()->SetContentsTexturesPurged();
[email protected]b1969fa2012-10-17 20:16:29696 m_client->setNeedsCommitOnImplThread();
697 m_client->onCanDrawStateChanged(canDraw());
[email protected]362f1e8b2013-01-21 16:54:30698 m_client->renewTreePriority();
[email protected]b1969fa2012-10-17 20:16:29699 }
[email protected]3d21e022012-10-25 20:03:08700 m_client->sendManagedMemoryStats();
[email protected]8947cbe2012-11-28 05:27:43701
702 if (m_tileManager) {
[email protected]8947cbe2012-11-28 05:27:43703 GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState());
[email protected]9b0b79a02013-01-02 22:47:27704 new_state.memory_limit_in_bytes = m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible;
705 new_state.memory_limit_policy = ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy(
706 m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible);
[email protected]8947cbe2012-11-28 05:27:43707 m_tileManager->SetGlobalState(new_state);
708 }
[email protected]94f206c12012-08-25 00:09:14709}
710
[email protected]61de5812012-11-08 07:03:44711bool LayerTreeHostImpl::hasImplThread() const
712{
713 return m_proxy->hasImplThread();
714}
715
[email protected]8947cbe2012-11-28 05:27:43716void LayerTreeHostImpl::ScheduleManageTiles()
717{
718 if (m_client)
719 m_client->setNeedsManageTilesOnImplThread();
720}
721
[email protected]74d9063c2013-01-18 03:14:47722void LayerTreeHostImpl::DidUploadVisibleHighResolutionTile()
723{
724 if (m_client)
725 m_client->didUploadVisibleHighResolutionTileOnImplTread();
726}
727
[email protected]f35e2322012-12-15 21:45:52728bool LayerTreeHostImpl::shouldClearRootRenderPass() const
729{
730 return m_settings.shouldClearRootRenderPass;
731}
732
[email protected]96baf3e2012-10-22 23:09:55733void LayerTreeHostImpl::setManagedMemoryPolicy(const ManagedMemoryPolicy& policy)
[email protected]94f206c12012-08-25 00:09:14734{
[email protected]a0a00842012-10-22 22:50:28735 if (m_managedMemoryPolicy == policy)
[email protected]94f206c12012-08-25 00:09:14736 return;
[email protected]61de5812012-11-08 07:03:44737
[email protected]a0a00842012-10-22 22:50:28738 m_managedMemoryPolicy = policy;
[email protected]61de5812012-11-08 07:03:44739 if (!m_proxy->hasImplThread()) {
740 // FIXME: In single-thread mode, this can be called on the main thread
741 // by GLRenderer::onMemoryAllocationChanged.
742 DebugScopedSetImplThread implThread(m_proxy);
743 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
744 } else {
745 DCHECK(m_proxy->isImplThread());
746 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
747 }
[email protected]a0a00842012-10-22 22:50:28748 // We always need to commit after changing the memory policy because the new
749 // limit can result in more or less content having texture allocated for it.
[email protected]94f206c12012-08-25 00:09:14750 m_client->setNeedsCommitOnImplThread();
751}
752
[email protected]a46f32932012-12-07 21:43:16753void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval)
[email protected]94f206c12012-08-25 00:09:14754{
[email protected]30faac92012-10-29 00:06:29755 m_client->onVSyncParametersChanged(timebase, interval);
[email protected]94f206c12012-08-25 00:09:14756}
757
[email protected]b6f3d7e2012-12-08 00:11:21758void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack)
[email protected]a46f32932012-12-07 21:43:16759{
[email protected]b6f3d7e2012-12-08 00:11:21760 if (!m_renderer)
761 return;
762
763 // TODO(piman): We may need to do some validation on this ack before processing it.
764 m_renderer->receiveCompositorFrameAck(ack);
[email protected]a46f32932012-12-07 21:43:16765}
766
[email protected]3b31c6ac2012-12-06 21:27:29767void LayerTreeHostImpl::OnCanDrawStateChangedForTree(LayerTreeImpl*)
768{
[email protected]a46f32932012-12-07 21:43:16769 m_client->onCanDrawStateChanged(canDraw());
[email protected]3b31c6ac2012-12-06 21:27:29770}
771
[email protected]bf189f62012-12-18 03:42:11772CompositorFrameMetadata LayerTreeHostImpl::makeCompositorFrameMetadata() const
773{
[email protected]bf189f62012-12-18 03:42:11774 CompositorFrameMetadata metadata;
[email protected]a823df82013-01-10 02:38:17775 metadata.page_scale_factor = m_pinchZoomViewport.total_page_scale_factor();
[email protected]42ccdbef2013-01-21 07:54:54776 metadata.viewport_size = m_pinchZoomViewport.ZoomedViewport().size();
777 metadata.root_layer_size = activeTree()->ScrollableSize();
[email protected]a823df82013-01-10 02:38:17778 metadata.min_page_scale_factor = m_pinchZoomViewport.min_page_scale_factor();
779 metadata.max_page_scale_factor = m_pinchZoomViewport.max_page_scale_factor();
[email protected]3ba4cae2013-01-16 03:58:38780 if (m_topControlsManager) {
781 metadata.location_bar_offset = gfx::Vector2dF(0.f, m_topControlsManager->controls_top_offset());
782 metadata.location_bar_content_translation = gfx::Vector2dF(0.f, m_topControlsManager->content_top_offset());
783 }
[email protected]bf189f62012-12-18 03:42:11784
[email protected]05469632013-01-16 03:41:00785 if (!rootScrollLayer())
786 return metadata;
787
788 metadata.root_scroll_offset = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
789 if (!m_settings.pageScalePinchZoomEnabled)
790 metadata.root_scroll_offset.Scale(1 / m_pinchZoomViewport.page_scale_factor());
791
[email protected]bf189f62012-12-18 03:42:11792 return metadata;
793}
794
[email protected]85167c72012-12-04 03:56:07795void LayerTreeHostImpl::drawLayers(FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14796{
[email protected]96baf3e2012-10-22 23:09:55797 TRACE_EVENT0("cc", "LayerTreeHostImpl::drawLayers");
[email protected]1d993172012-10-18 18:15:04798 DCHECK(canDraw());
[email protected]ead39c52013-01-09 07:22:45799 DCHECK(!frame.renderPasses.empty());
[email protected]94f206c12012-08-25 00:09:14800
801 // FIXME: use the frame begin time from the overall compositor scheduler.
802 // This value is currently inaccessible because it is up in Chromium's
803 // RenderWidget.
[email protected]d03b5c262013-01-16 04:06:18804 m_fpsCounter->saveTimeStamp(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:14805
[email protected]f511afb2012-11-30 01:55:20806 if (m_debugState.showHudRects())
[email protected]3b31c6ac2012-12-06 21:27:29807 m_debugRectHistory->saveDebugRectsForCurrentFrame(rootLayer(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, frame.nonOccludingScreenSpaceRects, m_debugState);
[email protected]94f206c12012-08-25 00:09:14808
809 // Because the contents of the HUD depend on everything else in the frame, the contents
810 // of its texture are updated as the last thing before the frame is drawn.
[email protected]3b31c6ac2012-12-06 21:27:29811 if (m_activeTree->hud_layer())
812 m_activeTree->hud_layer()->updateHudTexture(m_resourceProvider.get());
[email protected]94f206c12012-08-25 00:09:14813
[email protected]20062042012-12-21 22:16:36814 m_renderer->drawFrame(frame.renderPasses);
[email protected]85167c72012-12-04 03:56:07815 // The render passes should be consumed by the renderer.
[email protected]ead39c52013-01-09 07:22:45816 DCHECK(frame.renderPasses.empty());
[email protected]20062042012-12-21 22:16:36817 frame.renderPassesById.clear();
[email protected]94f206c12012-08-25 00:09:14818
819 // The next frame should start by assuming nothing has changed, and changes are noted as they occur.
820 for (unsigned int i = 0; i < frame.renderSurfaceLayerList->size(); i++)
821 (*frame.renderSurfaceLayerList)[i]->renderSurface()->damageTracker()->didDrawDamagedArea();
[email protected]3b31c6ac2012-12-06 21:27:29822 rootLayer()->resetAllChangeTrackingForSubtree();
[email protected]94f206c12012-08-25 00:09:14823}
824
[email protected]96baf3e2012-10-22 23:09:55825void LayerTreeHostImpl::didDrawAllLayers(const FrameData& frame)
[email protected]94f206c12012-08-25 00:09:14826{
827 for (size_t i = 0; i < frame.willDrawLayers.size(); ++i)
828 frame.willDrawLayers[i]->didDraw(m_resourceProvider.get());
[email protected]b914e102012-10-02 08:11:52829
830 // Once all layers have been drawn, pending texture uploads should no
831 // longer block future uploads.
[email protected]e2249592012-10-19 06:59:09832 m_resourceProvider->markPendingUploadsAsNonBlocking();
[email protected]94f206c12012-08-25 00:09:14833}
834
[email protected]96baf3e2012-10-22 23:09:55835void LayerTreeHostImpl::finishAllRendering()
[email protected]94f206c12012-08-25 00:09:14836{
837 if (m_renderer)
838 m_renderer->finish();
839}
840
[email protected]96baf3e2012-10-22 23:09:55841bool LayerTreeHostImpl::isContextLost()
[email protected]94f206c12012-08-25 00:09:14842{
843 return m_renderer && m_renderer->isContextLost();
844}
845
[email protected]96baf3e2012-10-22 23:09:55846const RendererCapabilities& LayerTreeHostImpl::rendererCapabilities() const
[email protected]94f206c12012-08-25 00:09:14847{
848 return m_renderer->capabilities();
849}
850
[email protected]96baf3e2012-10-22 23:09:55851bool LayerTreeHostImpl::swapBuffers()
[email protected]94f206c12012-08-25 00:09:14852{
[email protected]1d993172012-10-18 18:15:04853 DCHECK(m_renderer);
[email protected]74d9063c2013-01-18 03:14:47854 bool result = m_renderer->swapBuffers();
855
856 if (m_settings.implSidePainting &&
857 !activeTree()->AreVisibleResourcesReady()) {
858 m_client->didSwapUseIncompleteTextureOnImplThread();
859 }
860
861 return result;
[email protected]94f206c12012-08-25 00:09:14862}
863
[email protected]aad0a0072012-11-01 18:15:58864const gfx::Size& LayerTreeHostImpl::deviceViewportSize() const
[email protected]493067512012-09-19 23:34:10865{
866 return m_deviceViewportSize;
867}
868
[email protected]96baf3e2012-10-22 23:09:55869const LayerTreeSettings& LayerTreeHostImpl::settings() const
[email protected]493067512012-09-19 23:34:10870{
871 return m_settings;
872}
873
[email protected]3be2171d2012-12-06 06:13:20874void LayerTreeHostImpl::didLoseOutputSurface()
[email protected]94f206c12012-08-25 00:09:14875{
[email protected]3be2171d2012-12-06 06:13:20876 m_client->didLoseOutputSurfaceOnImplThread();
[email protected]94f206c12012-08-25 00:09:14877}
878
[email protected]96baf3e2012-10-22 23:09:55879void LayerTreeHostImpl::onSwapBuffersComplete()
[email protected]94f206c12012-08-25 00:09:14880{
881 m_client->onSwapBuffersCompleteOnImplThread();
882}
883
[email protected]aad0a0072012-11-01 18:15:58884void LayerTreeHostImpl::readback(void* pixels, const gfx::Rect& rect)
[email protected]94f206c12012-08-25 00:09:14885{
[email protected]1d993172012-10-18 18:15:04886 DCHECK(m_renderer);
[email protected]94f206c12012-08-25 00:09:14887 m_renderer->getFramebufferPixels(pixels, rect);
888}
889
[email protected]69b50ec2013-01-19 04:58:01890bool LayerTreeHostImpl::haveRootScrollLayer() const {
891 return rootScrollLayer();
892}
893
894float LayerTreeHostImpl::rootScrollLayerTotalScrollY() const {
895 if (LayerImpl* layer = rootScrollLayer())
896 return layer->scrollOffset().y() + layer->scrollDelta().y();
897 return 0.0f;
898}
899
[email protected]8bef40572012-12-11 21:38:08900LayerImpl* LayerTreeHostImpl::rootLayer() const
901{
902 return m_activeTree->RootLayer();
903}
904
905LayerImpl* LayerTreeHostImpl::rootScrollLayer() const
906{
[email protected]69b50ec2013-01-19 04:58:01907 return m_activeTree->RootScrollLayer();
[email protected]8bef40572012-12-11 21:38:08908}
909
910LayerImpl* LayerTreeHostImpl::currentlyScrollingLayer() const
911{
[email protected]69b50ec2013-01-19 04:58:01912 return m_activeTree->CurrentlyScrollingLayer();
[email protected]8bef40572012-12-11 21:38:08913}
914
[email protected]94f206c12012-08-25 00:09:14915// Content layers can be either directly scrollable or contained in an outer
916// scrolling layer which applies the scroll transform. Given a content layer,
917// this function returns the associated scroll layer if any.
[email protected]96baf3e2012-10-22 23:09:55918static LayerImpl* findScrollLayerForContentLayer(LayerImpl* layerImpl)
[email protected]94f206c12012-08-25 00:09:14919{
920 if (!layerImpl)
921 return 0;
922
923 if (layerImpl->scrollable())
924 return layerImpl;
925
926 if (layerImpl->drawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable())
927 return layerImpl->parent();
928
929 return 0;
930}
931
[email protected]2e7ca422012-12-20 02:57:27932void LayerTreeHostImpl::createPendingTree()
933{
934 CHECK(!m_pendingTree);
935 m_pendingTree = LayerTreeImpl::create(this);
936 m_client->onCanDrawStateChanged(canDraw());
937 m_client->onHasPendingTreeStateChanged(pendingTree());
938}
939
[email protected]74d9063c2013-01-18 03:14:47940void LayerTreeHostImpl::checkForCompletedTextures()
[email protected]eabe5002013-01-12 22:07:48941{
[email protected]74d9063c2013-01-18 03:14:47942 DCHECK(!m_client->isInsideDraw()) << "Checking for completed textures within a draw may trigger spurious redraws.";
[email protected]eabe5002013-01-12 22:07:48943 if (m_tileManager)
[email protected]74d9063c2013-01-18 03:14:47944 m_tileManager->CheckForCompletedTextures();
[email protected]eabe5002013-01-12 22:07:48945}
946
[email protected]2e7ca422012-12-20 02:57:27947void LayerTreeHostImpl::activatePendingTreeIfNeeded()
948{
949 if (!pendingTree())
950 return;
951
[email protected]b0a917c8d2013-01-12 17:42:25952 // It's always fine to activate to an empty tree. Otherwise, only
953 // activate once all visible resources in pending tree are ready.
954 if (activeTree()->RootLayer() &&
955 !pendingTree()->AreVisibleResourcesReady())
956 return;
[email protected]2e7ca422012-12-20 02:57:27957
[email protected]2e7ca422012-12-20 02:57:27958 activatePendingTree();
959}
960
961void LayerTreeHostImpl::activatePendingTree()
962{
963 CHECK(m_pendingTree);
[email protected]1e0f8d62013-01-09 07:41:35964
965 m_activeTree->PushPersistedState(m_pendingTree.get());
[email protected]2e7ca422012-12-20 02:57:27966 m_activeTree.swap(m_pendingTree);
967 // TODO(enne): consider recycling this tree to prevent layer churn
968 m_pendingTree.reset();
[email protected]37386f052013-01-13 00:42:22969 m_activeTree->DidBecomeActive();
970
[email protected]2e7ca422012-12-20 02:57:27971 m_client->onCanDrawStateChanged(canDraw());
972 m_client->onHasPendingTreeStateChanged(pendingTree());
[email protected]eabe5002013-01-12 22:07:48973 m_client->setNeedsRedrawOnImplThread();
[email protected]362f1e8b2013-01-21 16:54:30974 m_client->renewTreePriority();
[email protected]2e7ca422012-12-20 02:57:27975}
976
[email protected]96baf3e2012-10-22 23:09:55977void LayerTreeHostImpl::setVisible(bool visible)
[email protected]94f206c12012-08-25 00:09:14978{
[email protected]61de5812012-11-08 07:03:44979 DCHECK(m_proxy->isImplThread());
[email protected]94f206c12012-08-25 00:09:14980
981 if (m_visible == visible)
982 return;
983 m_visible = visible;
984 didVisibilityChange(this, m_visible);
[email protected]a0a00842012-10-22 22:50:28985 enforceManagedMemoryPolicy(m_managedMemoryPolicy);
[email protected]94f206c12012-08-25 00:09:14986
987 if (!m_renderer)
988 return;
989
990 m_renderer->setVisible(visible);
991
[email protected]de4afb5e2012-12-20 00:11:34992 setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:14993}
994
[email protected]3be2171d2012-12-06 06:13:20995bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface)
[email protected]94f206c12012-08-25 00:09:14996{
[email protected]be3181652012-09-25 13:02:13997 // Since we will create a new resource provider, we cannot continue to use
998 // the old resources (i.e. renderSurfaces and texture IDs). Clear them
999 // before we destroy the old resource provider.
[email protected]45c4b1e2013-01-16 02:19:401000 if (rootLayer())
[email protected]94f206c12012-08-25 00:09:141001 clearRenderSurfaces();
[email protected]45c4b1e2013-01-16 02:19:401002 if (activeTree()->RootLayer())
1003 sendDidLoseOutputSurfaceRecursive(activeTree()->RootLayer());
1004 if (pendingTree() && pendingTree()->RootLayer())
1005 sendDidLoseOutputSurfaceRecursive(pendingTree()->RootLayer());
1006
[email protected]be3181652012-09-25 13:02:131007 // Note: order is important here.
[email protected]0704caf2012-10-16 03:39:471008 m_renderer.reset();
[email protected]8947cbe2012-11-28 05:27:431009 m_tileManager.reset();
[email protected]a7aa5562012-10-17 14:12:441010 m_resourceProvider.reset();
[email protected]3be2171d2012-12-06 06:13:201011 m_outputSurface.reset();
[email protected]94f206c12012-08-25 00:09:141012
[email protected]a46f32932012-12-07 21:43:161013 if (!outputSurface->BindToClient(this))
[email protected]be3181652012-09-25 13:02:131014 return false;
1015
[email protected]3be2171d2012-12-06 06:13:201016 scoped_ptr<ResourceProvider> resourceProvider = ResourceProvider::create(outputSurface.get());
[email protected]be3181652012-09-25 13:02:131017 if (!resourceProvider)
1018 return false;
1019
[email protected]8947cbe2012-11-28 05:27:431020 if (m_settings.implSidePainting)
[email protected]876e9e82012-12-04 20:12:141021 m_tileManager.reset(new TileManager(this, resourceProvider.get(), m_settings.numRasterThreads));
[email protected]8947cbe2012-11-28 05:27:431022
[email protected]ea9d8f22012-12-08 03:39:291023 if (outputSurface->Capabilities().has_parent_compositor)
[email protected]05469632013-01-16 03:41:001024 m_renderer = DelegatingRenderer::Create(this, outputSurface.get(), resourceProvider.get());
[email protected]ea9d8f22012-12-08 03:39:291025 else if (outputSurface->Context3D())
[email protected]bf189f62012-12-18 03:42:111026 m_renderer = GLRenderer::create(this, outputSurface.get(), resourceProvider.get());
[email protected]a46f32932012-12-07 21:43:161027 else if (outputSurface->SoftwareDevice())
1028 m_renderer = SoftwareRenderer::create(this, resourceProvider.get(), outputSurface->SoftwareDevice());
[email protected]be3181652012-09-25 13:02:131029 if (!m_renderer)
1030 return false;
1031
[email protected]76ffd9e2012-12-20 19:12:471032 setNeedsUpdateDrawProperties();
[email protected]a7aa5562012-10-17 14:12:441033 m_resourceProvider = resourceProvider.Pass();
[email protected]3be2171d2012-12-06 06:13:201034 m_outputSurface = outputSurface.Pass();
[email protected]94f206c12012-08-25 00:09:141035
[email protected]be3181652012-09-25 13:02:131036 if (!m_visible)
1037 m_renderer->setVisible(m_visible);
[email protected]94f206c12012-08-25 00:09:141038
[email protected]8db2213c2012-09-05 22:08:211039 m_client->onCanDrawStateChanged(canDraw());
1040
[email protected]be3181652012-09-25 13:02:131041 return true;
[email protected]94f206c12012-08-25 00:09:141042}
1043
[email protected]aad0a0072012-11-01 18:15:581044void LayerTreeHostImpl::setViewportSize(const gfx::Size& layoutViewportSize, const gfx::Size& deviceViewportSize)
[email protected]94f206c12012-08-25 00:09:141045{
1046 if (layoutViewportSize == m_layoutViewportSize && deviceViewportSize == m_deviceViewportSize)
1047 return;
1048
1049 m_layoutViewportSize = layoutViewportSize;
1050 m_deviceViewportSize = deviceViewportSize;
1051
[email protected]a823df82013-01-10 02:38:171052 m_pinchZoomViewport.set_layout_viewport_size(layoutViewportSize);
[email protected]42ccdbef2013-01-21 07:54:541053 m_pinchZoomViewport.set_device_viewport_size(deviceViewportSize);
[email protected]1c0c9bc2012-10-08 22:41:481054
[email protected]c9c1ebe2012-11-05 20:46:131055 updateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141056
1057 if (m_renderer)
1058 m_renderer->viewportChanged();
[email protected]8db2213c2012-09-05 22:08:211059
1060 m_client->onCanDrawStateChanged(canDraw());
[email protected]94f206c12012-08-25 00:09:141061}
1062
[email protected]96baf3e2012-10-22 23:09:551063static void adjustScrollsForPageScaleChange(LayerImpl* layerImpl, float pageScaleChange)
[email protected]94f206c12012-08-25 00:09:141064{
1065 if (!layerImpl)
1066 return;
1067
1068 if (layerImpl->scrollable()) {
1069 // We need to convert impl-side scroll deltas to pageScale space.
[email protected]c9c1ebe2012-11-05 20:46:131070 gfx::Vector2dF scrollDelta = layerImpl->scrollDelta();
1071 scrollDelta.Scale(pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141072 layerImpl->setScrollDelta(scrollDelta);
1073 }
1074
1075 for (size_t i = 0; i < layerImpl->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031076 adjustScrollsForPageScaleChange(layerImpl->children()[i], pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141077}
1078
[email protected]96baf3e2012-10-22 23:09:551079void LayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor)
[email protected]94f206c12012-08-25 00:09:141080{
1081 if (deviceScaleFactor == m_deviceScaleFactor)
1082 return;
1083 m_deviceScaleFactor = deviceScaleFactor;
[email protected]a823df82013-01-10 02:38:171084 m_pinchZoomViewport.set_device_scale_factor(m_deviceScaleFactor);
[email protected]c0dd24c2012-08-30 23:25:271085
[email protected]c9c1ebe2012-11-05 20:46:131086 updateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141087}
1088
[email protected]96baf3e2012-10-22 23:09:551089float LayerTreeHostImpl::pageScaleFactor() const
[email protected]94f206c12012-08-25 00:09:141090{
[email protected]a823df82013-01-10 02:38:171091 return m_pinchZoomViewport.page_scale_factor();
[email protected]1c0c9bc2012-10-08 22:41:481092}
[email protected]94f206c12012-08-25 00:09:141093
[email protected]96baf3e2012-10-22 23:09:551094void LayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
[email protected]1c0c9bc2012-10-08 22:41:481095{
1096 if (!pageScaleFactor)
1097 return;
[email protected]94f206c12012-08-25 00:09:141098
[email protected]a823df82013-01-10 02:38:171099 float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.page_scale_factor();
1100 m_pinchZoomViewport.SetPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor);
[email protected]94f206c12012-08-25 00:09:141101
[email protected]0ede3bb2012-12-09 09:14:391102 if (!m_settings.pageScalePinchZoomEnabled && pageScaleChange != 1)
1103 adjustScrollsForPageScaleChange(rootScrollLayer(), pageScaleChange);
[email protected]94f206c12012-08-25 00:09:141104
1105 // Clamp delta to limits and refresh display matrix.
[email protected]a823df82013-01-10 02:38:171106 setPageScaleDelta(m_pinchZoomViewport.page_scale_delta() / m_pinchZoomViewport.sent_page_scale_delta());
1107 m_pinchZoomViewport.set_sent_page_scale_delta(1);
[email protected]94f206c12012-08-25 00:09:141108}
1109
[email protected]96baf3e2012-10-22 23:09:551110void LayerTreeHostImpl::setPageScaleDelta(float delta)
[email protected]94f206c12012-08-25 00:09:141111{
[email protected]a823df82013-01-10 02:38:171112 m_pinchZoomViewport.set_page_scale_delta(delta);
[email protected]94f206c12012-08-25 00:09:141113
[email protected]c9c1ebe2012-11-05 20:46:131114 updateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141115}
1116
[email protected]c9c1ebe2012-11-05 20:46:131117void LayerTreeHostImpl::updateMaxScrollOffset()
[email protected]94f206c12012-08-25 00:09:141118{
[email protected]caa567d2012-12-20 07:56:161119 activeTree()->UpdateMaxScrollOffset();
1120 if (pendingTree())
1121 pendingTree()->UpdateMaxScrollOffset();
[email protected]94f206c12012-08-25 00:09:141122}
1123
[email protected]3ba4cae2013-01-16 03:58:381124void LayerTreeHostImpl::setNeedsUpdateDrawProperties()
1125{
1126 m_needsUpdateDrawProperties = true;
1127}
1128
[email protected]96baf3e2012-10-22 23:09:551129void LayerTreeHostImpl::setNeedsRedraw()
[email protected]94f206c12012-08-25 00:09:141130{
1131 m_client->setNeedsRedrawOnImplThread();
1132}
1133
[email protected]96baf3e2012-10-22 23:09:551134bool LayerTreeHostImpl::ensureRenderSurfaceLayerList()
[email protected]94f206c12012-08-25 00:09:141135{
[email protected]0ede3bb2012-12-09 09:14:391136 updateDrawProperties();
[email protected]76ffd9e2012-12-20 19:12:471137 return activeTree()->RenderSurfaceLayerList().size();
[email protected]94f206c12012-08-25 00:09:141138}
1139
[email protected]c9c1ebe2012-11-05 20:46:131140InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewportPoint, InputHandlerClient::ScrollInputType type)
[email protected]94f206c12012-08-25 00:09:141141{
[email protected]96baf3e2012-10-22 23:09:551142 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin");
[email protected]94f206c12012-08-25 00:09:141143
[email protected]3ba4cae2013-01-16 03:58:381144 if (m_topControlsManager)
1145 m_topControlsManager->ScrollBegin();
1146
[email protected]3b31c6ac2012-12-06 21:27:291147 DCHECK(!currentlyScrollingLayer());
[email protected]94f206c12012-08-25 00:09:141148 clearCurrentlyScrollingLayer();
1149
1150 if (!ensureRenderSurfaceLayerList())
1151 return ScrollIgnored;
1152
[email protected]faf56352012-11-09 21:44:131153 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:141154
1155 // First find out which layer was hit from the saved list of visible layers
1156 // in the most recent frame.
[email protected]76ffd9e2012-12-20 19:12:471157 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(deviceViewportPoint, activeTree()->RenderSurfaceLayerList());
[email protected]94f206c12012-08-25 00:09:141158
1159 // Walk up the hierarchy and look for a scrollable layer.
[email protected]96baf3e2012-10-22 23:09:551160 LayerImpl* potentiallyScrollingLayerImpl = 0;
[email protected]94f206c12012-08-25 00:09:141161 for (; layerImpl; layerImpl = layerImpl->parent()) {
1162 // The content layer can also block attempts to scroll outside the main thread.
[email protected]5c6fe1f82012-10-03 18:00:271163 if (layerImpl->tryScroll(deviceViewportPoint, type) == ScrollOnMainThread) {
1164 m_numMainThreadScrolls++;
[email protected]94f206c12012-08-25 00:09:141165 return ScrollOnMainThread;
[email protected]5c6fe1f82012-10-03 18:00:271166 }
[email protected]94f206c12012-08-25 00:09:141167
[email protected]96baf3e2012-10-22 23:09:551168 LayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl);
[email protected]94f206c12012-08-25 00:09:141169 if (!scrollLayerImpl)
1170 continue;
1171
[email protected]31bfe272012-10-19 18:49:521172 ScrollStatus status = scrollLayerImpl->tryScroll(deviceViewportPoint, type);
[email protected]94f206c12012-08-25 00:09:141173
1174 // If any layer wants to divert the scroll event to the main thread, abort.
[email protected]5c6fe1f82012-10-03 18:00:271175 if (status == ScrollOnMainThread) {
1176 m_numMainThreadScrolls++;
[email protected]94f206c12012-08-25 00:09:141177 return ScrollOnMainThread;
[email protected]5c6fe1f82012-10-03 18:00:271178 }
[email protected]94f206c12012-08-25 00:09:141179
1180 if (status == ScrollStarted && !potentiallyScrollingLayerImpl)
1181 potentiallyScrollingLayerImpl = scrollLayerImpl;
1182 }
1183
1184 if (potentiallyScrollingLayerImpl) {
[email protected]3b31c6ac2012-12-06 21:27:291185 m_activeTree->set_currently_scrolling_layer(potentiallyScrollingLayerImpl);
[email protected]31bfe272012-10-19 18:49:521186 // Gesture events need to be transformed from viewport coordinates to local layer coordinates
[email protected]94f206c12012-08-25 00:09:141187 // so that the scrolling contents exactly follow the user's finger. In contrast, wheel
1188 // events are already in local layer coordinates so we can just apply them directly.
[email protected]31bfe272012-10-19 18:49:521189 m_scrollDeltaIsInViewportSpace = (type == Gesture);
[email protected]5c6fe1f82012-10-03 18:00:271190 m_numImplThreadScrolls++;
[email protected]0ede3bb2012-12-09 09:14:391191 setNeedsUpdateDrawProperties();
[email protected]94f206c12012-08-25 00:09:141192 return ScrollStarted;
1193 }
1194 return ScrollIgnored;
1195}
1196
[email protected]c9c1ebe2012-11-05 20:46:131197static gfx::Vector2dF scrollLayerWithViewportSpaceDelta(PinchZoomViewport* viewport, LayerImpl& layerImpl, float scaleFromViewportToScreenSpace, gfx::PointF viewportPoint, gfx::Vector2dF viewportDelta)
[email protected]94f206c12012-08-25 00:09:141198{
1199 // Layers with non-invertible screen space transforms should not have passed the scroll hit
1200 // test in the first place.
[email protected]c8686a02012-11-27 08:29:001201 DCHECK(layerImpl.screenSpaceTransform().IsInvertible());
[email protected]bda41962013-01-07 18:46:171202 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitialization);
1203 bool didInvert = layerImpl.screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform);
1204 // TODO: With the advent of impl-side crolling for non-root layers, we may
1205 // need to explicitly handle uninvertible transforms here.
1206 DCHECK(didInvert);
[email protected]94f206c12012-08-25 00:09:141207
[email protected]faf56352012-11-09 21:44:131208 gfx::PointF screenSpacePoint = gfx::ScalePoint(viewportPoint, scaleFromViewportToScreenSpace);
[email protected]31bfe272012-10-19 18:49:521209
[email protected]c9c1ebe2012-11-05 20:46:131210 gfx::Vector2dF screenSpaceDelta = viewportDelta;
1211 screenSpaceDelta.Scale(scaleFromViewportToScreenSpace);
[email protected]31bfe272012-10-19 18:49:521212
[email protected]94f206c12012-08-25 00:09:141213 // First project the scroll start and end points to local layer space to find the scroll delta
1214 // in layer coordinates.
1215 bool startClipped, endClipped;
[email protected]d455d552012-11-02 00:19:061216 gfx::PointF screenSpaceEndPoint = screenSpacePoint + screenSpaceDelta;
1217 gfx::PointF localStartPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpacePoint, startClipped);
1218 gfx::PointF localEndPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpaceEndPoint, endClipped);
[email protected]94f206c12012-08-25 00:09:141219
1220 // In general scroll point coordinates should not get clipped.
[email protected]1d993172012-10-18 18:15:041221 DCHECK(!startClipped);
1222 DCHECK(!endClipped);
[email protected]94f206c12012-08-25 00:09:141223 if (startClipped || endClipped)
[email protected]c9c1ebe2012-11-05 20:46:131224 return gfx::Vector2dF();
[email protected]94f206c12012-08-25 00:09:141225
[email protected]31bfe272012-10-19 18:49:521226 // localStartPoint and localEndPoint are in content space but we want to move them to layer space for scrolling.
[email protected]aad0a0072012-11-01 18:15:581227 float widthScale = 1 / layerImpl.contentsScaleX();
1228 float heightScale = 1 / layerImpl.contentsScaleY();
[email protected]faf56352012-11-09 21:44:131229 localStartPoint.Scale(widthScale, heightScale);
1230 localEndPoint.Scale(widthScale, heightScale);
[email protected]31bfe272012-10-19 18:49:521231
[email protected]94f206c12012-08-25 00:09:141232 // Apply the scroll delta.
[email protected]c9c1ebe2012-11-05 20:46:131233 gfx::Vector2dF previousDelta = layerImpl.scrollDelta();
1234 gfx::Vector2dF unscrolled = layerImpl.scrollBy(localEndPoint - localStartPoint);
[email protected]caa567d2012-12-20 07:56:161235 gfx::Vector2dF scrollAmount = localEndPoint - localStartPoint;
[email protected]1c0c9bc2012-10-08 22:41:481236
[email protected]aeaa50a2012-11-21 20:12:371237 gfx::Vector2dF viewportAppliedPan;
[email protected]1c0c9bc2012-10-08 22:41:481238 if (viewport)
[email protected]a823df82013-01-10 02:38:171239 viewportAppliedPan = unscrolled - viewport->ApplyScroll(unscrolled);
[email protected]94f206c12012-08-25 00:09:141240
[email protected]31bfe272012-10-19 18:49:521241 // Get the end point in the layer's content space so we can apply its screenSpaceTransform.
[email protected]aeaa50a2012-11-21 20:12:371242 gfx::PointF actualLocalEndPoint = localStartPoint + layerImpl.scrollDelta() + viewportAppliedPan - previousDelta;
[email protected]faf56352012-11-09 21:44:131243 gfx::PointF actualLocalContentEndPoint = gfx::ScalePoint(actualLocalEndPoint, 1 / widthScale, 1 / heightScale);
[email protected]31bfe272012-10-19 18:49:521244
1245 // Calculate the applied scroll delta in viewport space coordinates.
[email protected]d455d552012-11-02 00:19:061246 gfx::PointF actualScreenSpaceEndPoint = MathUtil::mapPoint(layerImpl.screenSpaceTransform(), actualLocalContentEndPoint, endClipped);
[email protected]1d993172012-10-18 18:15:041247 DCHECK(!endClipped);
[email protected]94f206c12012-08-25 00:09:141248 if (endClipped)
[email protected]c9c1ebe2012-11-05 20:46:131249 return gfx::Vector2dF();
[email protected]faf56352012-11-09 21:44:131250 gfx::PointF actualViewportEndPoint = gfx::ScalePoint(actualScreenSpaceEndPoint, 1 / scaleFromViewportToScreenSpace);
[email protected]c9c1ebe2012-11-05 20:46:131251 return actualViewportEndPoint - viewportPoint;
[email protected]94f206c12012-08-25 00:09:141252}
1253
[email protected]c9c1ebe2012-11-05 20:46:131254static gfx::Vector2dF scrollLayerWithLocalDelta(LayerImpl& layerImpl, gfx::Vector2dF localDelta)
[email protected]94f206c12012-08-25 00:09:141255{
[email protected]c9c1ebe2012-11-05 20:46:131256 gfx::Vector2dF previousDelta(layerImpl.scrollDelta());
[email protected]94f206c12012-08-25 00:09:141257 layerImpl.scrollBy(localDelta);
1258 return layerImpl.scrollDelta() - previousDelta;
1259}
1260
[email protected]a9710962012-11-14 20:11:021261bool LayerTreeHostImpl::scrollBy(const gfx::Point& viewportPoint,
1262 const gfx::Vector2d& scrollDelta)
[email protected]94f206c12012-08-25 00:09:141263{
[email protected]96baf3e2012-10-22 23:09:551264 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBy");
[email protected]3b31c6ac2012-12-06 21:27:291265 if (!currentlyScrollingLayer())
[email protected]a9710962012-11-14 20:11:021266 return false;
[email protected]94f206c12012-08-25 00:09:141267
[email protected]c9c1ebe2012-11-05 20:46:131268 gfx::Vector2dF pendingDelta = scrollDelta;
[email protected]1ca52a3a2012-12-04 22:47:101269 bool didScroll = false;
[email protected]94f206c12012-08-25 00:09:141270
[email protected]3b31c6ac2012-12-06 21:27:291271 for (LayerImpl* layerImpl = currentlyScrollingLayer(); layerImpl; layerImpl = layerImpl->parent()) {
[email protected]94f206c12012-08-25 00:09:141272 if (!layerImpl->scrollable())
1273 continue;
1274
[email protected]dbed4272012-12-06 08:50:481275 PinchZoomViewport* viewport = NULL;
[email protected]3b31c6ac2012-12-06 21:27:291276 if (m_settings.pageScalePinchZoomEnabled && layerImpl == rootScrollLayer())
[email protected]dbed4272012-12-06 08:50:481277 viewport = &m_pinchZoomViewport;
[email protected]c9c1ebe2012-11-05 20:46:131278 gfx::Vector2dF appliedDelta;
[email protected]3ba4cae2013-01-16 03:58:381279 if (m_topControlsManager && layerImpl == rootScrollLayer())
1280 pendingDelta = m_topControlsManager->ScrollBy(pendingDelta);
1281
[email protected]31bfe272012-10-19 18:49:521282 if (m_scrollDeltaIsInViewportSpace) {
1283 float scaleFromViewportToScreenSpace = m_deviceScaleFactor;
1284 appliedDelta = scrollLayerWithViewportSpaceDelta(viewport, *layerImpl, scaleFromViewportToScreenSpace, viewportPoint, pendingDelta);
1285 } else
[email protected]94f206c12012-08-25 00:09:141286 appliedDelta = scrollLayerWithLocalDelta(*layerImpl, pendingDelta);
1287
1288 // If the layer wasn't able to move, try the next one in the hierarchy.
[email protected]23bbb412012-08-30 20:03:381289 float moveThresholdSquared = 0.1f * 0.1f;
[email protected]c9c1ebe2012-11-05 20:46:131290 if (appliedDelta.LengthSquared() < moveThresholdSquared)
[email protected]94f206c12012-08-25 00:09:141291 continue;
[email protected]1ca52a3a2012-12-04 22:47:101292 didScroll = true;
[email protected]94f206c12012-08-25 00:09:141293
1294 // If the applied delta is within 45 degrees of the input delta, bail out to make it easier
1295 // to scroll just one layer in one direction without affecting any of its parents.
1296 float angleThreshold = 45;
[email protected]96baf3e2012-10-22 23:09:551297 if (MathUtil::smallestAngleBetweenVectors(appliedDelta, pendingDelta) < angleThreshold) {
[email protected]c9c1ebe2012-11-05 20:46:131298 pendingDelta = gfx::Vector2d();
[email protected]94f206c12012-08-25 00:09:141299 break;
1300 }
1301
1302 // Allow further movement only on an axis perpendicular to the direction in which the layer
1303 // moved.
[email protected]c9c1ebe2012-11-05 20:46:131304 gfx::Vector2dF perpendicularAxis(-appliedDelta.y(), appliedDelta.x());
[email protected]96baf3e2012-10-22 23:09:551305 pendingDelta = MathUtil::projectVector(pendingDelta, perpendicularAxis);
[email protected]94f206c12012-08-25 00:09:141306
[email protected]c9c1ebe2012-11-05 20:46:131307 if (gfx::ToFlooredVector2d(pendingDelta).IsZero())
[email protected]94f206c12012-08-25 00:09:141308 break;
1309 }
1310
[email protected]1ca52a3a2012-12-04 22:47:101311 if (didScroll) {
[email protected]94f206c12012-08-25 00:09:141312 m_client->setNeedsCommitOnImplThread();
1313 m_client->setNeedsRedrawOnImplThread();
[email protected]0ede3bb2012-12-09 09:14:391314 setNeedsUpdateDrawProperties();
[email protected]94f206c12012-08-25 00:09:141315 }
[email protected]1ca52a3a2012-12-04 22:47:101316 return didScroll;
[email protected]94f206c12012-08-25 00:09:141317}
1318
[email protected]96baf3e2012-10-22 23:09:551319void LayerTreeHostImpl::clearCurrentlyScrollingLayer()
[email protected]94f206c12012-08-25 00:09:141320{
[email protected]3b31c6ac2012-12-06 21:27:291321 m_activeTree->ClearCurrentlyScrollingLayer();
[email protected]94f206c12012-08-25 00:09:141322}
1323
[email protected]96baf3e2012-10-22 23:09:551324void LayerTreeHostImpl::scrollEnd()
[email protected]94f206c12012-08-25 00:09:141325{
[email protected]3ba4cae2013-01-16 03:58:381326 if (m_topControlsManager)
1327 m_topControlsManager->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141328 clearCurrentlyScrollingLayer();
1329}
1330
[email protected]96baf3e2012-10-22 23:09:551331void LayerTreeHostImpl::pinchGestureBegin()
[email protected]94f206c12012-08-25 00:09:141332{
1333 m_pinchGestureActive = true;
[email protected]c9c1ebe2012-11-05 20:46:131334 m_previousPinchAnchor = gfx::Point();
[email protected]94f206c12012-08-25 00:09:141335}
1336
[email protected]c9c1ebe2012-11-05 20:46:131337void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor)
[email protected]94f206c12012-08-25 00:09:141338{
[email protected]96baf3e2012-10-22 23:09:551339 TRACE_EVENT0("cc", "LayerTreeHostImpl::pinchGestureUpdate");
[email protected]94f206c12012-08-25 00:09:141340
[email protected]3b31c6ac2012-12-06 21:27:291341 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141342 return;
1343
[email protected]94f206c12012-08-25 00:09:141344 // Keep the center-of-pinch anchor specified by (x, y) in a stable
1345 // position over the course of the magnify.
[email protected]a823df82013-01-10 02:38:171346 float pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
[email protected]c77745d2012-11-20 04:11:571347 gfx::PointF previousScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta);
[email protected]1c0c9bc2012-10-08 22:41:481348 setPageScaleDelta(pageScaleDelta * magnifyDelta);
[email protected]a823df82013-01-10 02:38:171349 pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
[email protected]faf56352012-11-09 21:44:131350 gfx::PointF newScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta);
[email protected]c9c1ebe2012-11-05 20:46:131351 gfx::Vector2dF move = previousScaleAnchor - newScaleAnchor;
[email protected]94f206c12012-08-25 00:09:141352
1353 m_previousPinchAnchor = anchor;
1354
[email protected]9bdcfd642012-11-14 21:24:261355 if (m_settings.pageScalePinchZoomEnabled) {
[email protected]1c0c9bc2012-10-08 22:41:481356 // Compute the application of the delta with respect to the current page zoom of the page.
[email protected]a823df82013-01-10 02:38:171357 move.Scale(1 / m_pinchZoomViewport.page_scale_factor());
[email protected]1c0c9bc2012-10-08 22:41:481358 }
1359
[email protected]a823df82013-01-10 02:38:171360 gfx::Vector2dF scrollOverflow = m_settings.pageScalePinchZoomEnabled ? m_pinchZoomViewport.ApplyScroll(move) : move;
[email protected]3b31c6ac2012-12-06 21:27:291361 rootScrollLayer()->scrollBy(scrollOverflow);
[email protected]94f206c12012-08-25 00:09:141362
[email protected]3b31c6ac2012-12-06 21:27:291363 if (rootScrollLayer()->scrollbarAnimationController())
[email protected]e45638c2013-01-17 22:01:401364 rootScrollLayer()->scrollbarAnimationController()->didPinchGestureUpdate(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141365
1366 m_client->setNeedsCommitOnImplThread();
1367 m_client->setNeedsRedrawOnImplThread();
[email protected]0ede3bb2012-12-09 09:14:391368 setNeedsUpdateDrawProperties();
[email protected]94f206c12012-08-25 00:09:141369}
1370
[email protected]96baf3e2012-10-22 23:09:551371void LayerTreeHostImpl::pinchGestureEnd()
[email protected]94f206c12012-08-25 00:09:141372{
1373 m_pinchGestureActive = false;
1374
[email protected]3b31c6ac2012-12-06 21:27:291375 if (rootScrollLayer() && rootScrollLayer()->scrollbarAnimationController())
[email protected]e45638c2013-01-17 22:01:401376 rootScrollLayer()->scrollbarAnimationController()->didPinchGestureEnd(base::TimeTicks::Now());
[email protected]94f206c12012-08-25 00:09:141377
1378 m_client->setNeedsCommitOnImplThread();
1379}
1380
[email protected]96baf3e2012-10-22 23:09:551381void LayerTreeHostImpl::computeDoubleTapZoomDeltas(ScrollAndScaleSet* scrollInfo)
[email protected]94f206c12012-08-25 00:09:141382{
[email protected]f6250742012-11-09 04:46:561383 gfx::Vector2dF scaledScrollOffset = m_pageScaleAnimation->targetScrollOffset();
[email protected]9bdcfd642012-11-14 21:24:261384 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]a823df82013-01-10 02:38:171385 scaledScrollOffset.Scale(m_pinchZoomViewport.page_scale_factor());
[email protected]f6250742012-11-09 04:46:561386 makeScrollAndScaleSet(scrollInfo, ToFlooredVector2d(scaledScrollOffset), m_pageScaleAnimation->targetPageScaleFactor());
[email protected]94f206c12012-08-25 00:09:141387}
1388
[email protected]96baf3e2012-10-22 23:09:551389void LayerTreeHostImpl::computePinchZoomDeltas(ScrollAndScaleSet* scrollInfo)
[email protected]94f206c12012-08-25 00:09:141390{
[email protected]3b31c6ac2012-12-06 21:27:291391 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141392 return;
1393
1394 // Only send fake scroll/zoom deltas if we're pinch zooming out by a
1395 // significant amount. This also ensures only one fake delta set will be
1396 // sent.
[email protected]23bbb412012-08-30 20:03:381397 const float pinchZoomOutSensitivity = 0.95f;
[email protected]a823df82013-01-10 02:38:171398 if (m_pinchZoomViewport.page_scale_delta() > pinchZoomOutSensitivity)
[email protected]94f206c12012-08-25 00:09:141399 return;
1400
1401 // Compute where the scroll offset/page scale would be if fully pinch-zoomed
1402 // out from the anchor point.
[email protected]3b31c6ac2012-12-06 21:27:291403 gfx::Vector2dF scrollBegin = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]a823df82013-01-10 02:38:171404 scrollBegin.Scale(m_pinchZoomViewport.page_scale_delta());
1405 float scaleBegin = m_pinchZoomViewport.total_page_scale_factor();
1406 float pageScaleDeltaToSend = m_pinchZoomViewport.min_page_scale_factor() / m_pinchZoomViewport.page_scale_factor();
[email protected]42ccdbef2013-01-21 07:54:541407 gfx::SizeF scaledScrollableSize = gfx::ScaleSize(activeTree()->ScrollableSize(), pageScaleDeltaToSend);
[email protected]94f206c12012-08-25 00:09:141408
[email protected]c9c1ebe2012-11-05 20:46:131409 gfx::Vector2d anchorOffset = m_previousPinchAnchor.OffsetFromOrigin();
1410 gfx::Vector2dF scrollEnd = scrollBegin + anchorOffset;
[email protected]a823df82013-01-10 02:38:171411 scrollEnd.Scale(m_pinchZoomViewport.min_page_scale_factor() / scaleBegin);
[email protected]c9c1ebe2012-11-05 20:46:131412 scrollEnd -= anchorOffset;
[email protected]42ccdbef2013-01-21 07:54:541413 scrollEnd.ClampToMax(gfx::RectF(scaledScrollableSize).bottom_right() - gfx::Rect(m_deviceViewportSize).bottom_right());
[email protected]fe07b642012-11-10 00:07:591414 scrollEnd.ClampToMin(gfx::Vector2d());
[email protected]c9c1ebe2012-11-05 20:46:131415 scrollEnd.Scale(1 / pageScaleDeltaToSend);
1416 scrollEnd.Scale(m_deviceScaleFactor);
[email protected]94f206c12012-08-25 00:09:141417
[email protected]a823df82013-01-10 02:38:171418 makeScrollAndScaleSet(scrollInfo, gfx::ToRoundedVector2d(scrollEnd), m_pinchZoomViewport.min_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:141419}
1420
[email protected]c9c1ebe2012-11-05 20:46:131421void LayerTreeHostImpl::makeScrollAndScaleSet(ScrollAndScaleSet* scrollInfo, gfx::Vector2d scrollOffset, float pageScale)
[email protected]94f206c12012-08-25 00:09:141422{
[email protected]3b31c6ac2012-12-06 21:27:291423 if (!rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141424 return;
1425
[email protected]96baf3e2012-10-22 23:09:551426 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]3b31c6ac2012-12-06 21:27:291427 scroll.layerId = rootScrollLayer()->id();
1428 scroll.scrollDelta = scrollOffset - rootScrollLayer()->scrollOffset();
[email protected]787465c2012-10-29 01:12:271429 scrollInfo->scrolls.push_back(scroll);
[email protected]69b50ec2013-01-19 04:58:011430 activeTree()->RootScrollLayer()->setSentScrollDelta(scroll.scrollDelta);
[email protected]a823df82013-01-10 02:38:171431 scrollInfo->pageScaleDelta = pageScale / m_pinchZoomViewport.page_scale_factor();
1432 m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta);
[email protected]94f206c12012-08-25 00:09:141433}
1434
[email protected]96baf3e2012-10-22 23:09:551435static void collectScrollDeltas(ScrollAndScaleSet* scrollInfo, LayerImpl* layerImpl)
[email protected]94f206c12012-08-25 00:09:141436{
1437 if (!layerImpl)
1438 return;
1439
[email protected]c9c1ebe2012-11-05 20:46:131440 if (!layerImpl->scrollDelta().IsZero()) {
1441 gfx::Vector2d scrollDelta = gfx::ToFlooredVector2d(layerImpl->scrollDelta());
[email protected]96baf3e2012-10-22 23:09:551442 LayerTreeHostCommon::ScrollUpdateInfo scroll;
[email protected]94f206c12012-08-25 00:09:141443 scroll.layerId = layerImpl->id();
1444 scroll.scrollDelta = scrollDelta;
[email protected]787465c2012-10-29 01:12:271445 scrollInfo->scrolls.push_back(scroll);
[email protected]94f206c12012-08-25 00:09:141446 layerImpl->setSentScrollDelta(scrollDelta);
1447 }
1448
1449 for (size_t i = 0; i < layerImpl->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031450 collectScrollDeltas(scrollInfo, layerImpl->children()[i]);
[email protected]94f206c12012-08-25 00:09:141451}
1452
[email protected]96baf3e2012-10-22 23:09:551453scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::processScrollDeltas()
[email protected]94f206c12012-08-25 00:09:141454{
[email protected]96baf3e2012-10-22 23:09:551455 scoped_ptr<ScrollAndScaleSet> scrollInfo(new ScrollAndScaleSet());
[email protected]94f206c12012-08-25 00:09:141456
1457 if (m_pinchGestureActive || m_pageScaleAnimation) {
[email protected]1c0c9bc2012-10-08 22:41:481458 scrollInfo->pageScaleDelta = 1;
[email protected]a823df82013-01-10 02:38:171459 m_pinchZoomViewport.set_sent_page_scale_delta(1);
[email protected]f6250742012-11-09 04:46:561460 // FIXME(aelias): Make pinch-zoom painting optimization compatible with
[email protected]1c0c9bc2012-10-08 22:41:481461 // compositor-side scaling.
[email protected]9bdcfd642012-11-14 21:24:261462 if (!m_settings.pageScalePinchZoomEnabled && m_pinchGestureActive)
[email protected]f6250742012-11-09 04:46:561463 computePinchZoomDeltas(scrollInfo.get());
1464 else if (m_pageScaleAnimation.get())
1465 computeDoubleTapZoomDeltas(scrollInfo.get());
[email protected]a9f4bf22012-10-11 23:39:211466 return scrollInfo.Pass();
[email protected]94f206c12012-08-25 00:09:141467 }
1468
[email protected]3b31c6ac2012-12-06 21:27:291469 collectScrollDeltas(scrollInfo.get(), rootLayer());
[email protected]a823df82013-01-10 02:38:171470 scrollInfo->pageScaleDelta = m_pinchZoomViewport.page_scale_delta();
1471 m_pinchZoomViewport.set_sent_page_scale_delta(scrollInfo->pageScaleDelta);
[email protected]94f206c12012-08-25 00:09:141472
[email protected]a9f4bf22012-10-11 23:39:211473 return scrollInfo.Pass();
[email protected]94f206c12012-08-25 00:09:141474}
1475
[email protected]c8686a02012-11-27 08:29:001476gfx::Transform LayerTreeHostImpl::implTransform() const
[email protected]1c0c9bc2012-10-08 22:41:481477{
[email protected]a823df82013-01-10 02:38:171478 return m_pinchZoomViewport.ImplTransform(m_settings.pageScalePinchZoomEnabled);
[email protected]1c0c9bc2012-10-08 22:41:481479}
1480
[email protected]96baf3e2012-10-22 23:09:551481void LayerTreeHostImpl::setFullRootLayerDamage()
[email protected]94f206c12012-08-25 00:09:141482{
[email protected]3b31c6ac2012-12-06 21:27:291483 if (rootLayer()) {
1484 RenderSurfaceImpl* renderSurface = rootLayer()->renderSurface();
[email protected]94f206c12012-08-25 00:09:141485 if (renderSurface)
1486 renderSurface->damageTracker()->forceFullDamageNextUpdate();
1487 }
1488}
1489
[email protected]30faac92012-10-29 00:06:291490void LayerTreeHostImpl::animatePageScale(base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141491{
[email protected]3b31c6ac2012-12-06 21:27:291492 if (!m_pageScaleAnimation || !rootScrollLayer())
[email protected]94f206c12012-08-25 00:09:141493 return;
1494
[email protected]30faac92012-10-29 00:06:291495 double monotonicTime = (time - base::TimeTicks()).InSecondsF();
[email protected]3b31c6ac2012-12-06 21:27:291496 gfx::Vector2dF scrollTotal = rootScrollLayer()->scrollOffset() + rootScrollLayer()->scrollDelta();
[email protected]94f206c12012-08-25 00:09:141497
[email protected]a823df82013-01-10 02:38:171498 setPageScaleDelta(m_pageScaleAnimation->pageScaleFactorAtTime(monotonicTime) / m_pinchZoomViewport.page_scale_factor());
[email protected]c9c1ebe2012-11-05 20:46:131499 gfx::Vector2dF nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime);
[email protected]f6250742012-11-09 04:46:561500
[email protected]9bdcfd642012-11-14 21:24:261501 if (!m_settings.pageScalePinchZoomEnabled)
[email protected]a823df82013-01-10 02:38:171502 nextScroll.Scale(m_pinchZoomViewport.page_scale_factor());
[email protected]3b31c6ac2012-12-06 21:27:291503 rootScrollLayer()->scrollBy(nextScroll - scrollTotal);
[email protected]94f206c12012-08-25 00:09:141504 m_client->setNeedsRedrawOnImplThread();
[email protected]0ede3bb2012-12-09 09:14:391505 setNeedsUpdateDrawProperties();
[email protected]94f206c12012-08-25 00:09:141506
1507 if (m_pageScaleAnimation->isAnimationCompleteAtTime(monotonicTime)) {
[email protected]0023e8b2012-10-15 12:52:451508 m_pageScaleAnimation.reset();
[email protected]94f206c12012-08-25 00:09:141509 m_client->setNeedsCommitOnImplThread();
1510 }
1511}
1512
[email protected]30faac92012-10-29 00:06:291513void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime)
[email protected]94f206c12012-08-25 00:09:141514{
[email protected]de4afb5e2012-12-20 00:11:341515 if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty() || !rootLayer())
[email protected]94f206c12012-08-25 00:09:141516 return;
1517
[email protected]96baf3e2012-10-22 23:09:551518 TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers");
[email protected]94f206c12012-08-25 00:09:141519
[email protected]de4afb5e2012-12-20 00:11:341520 double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF();
[email protected]df1ec1a2012-12-08 17:01:181521
[email protected]de4afb5e2012-12-20 00:11:341522 scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
1523 AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers();
1524 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter)
1525 (*iter).second->animate(monotonicSeconds, events.get());
[email protected]94f206c12012-08-25 00:09:141526
[email protected]d3143c732012-10-05 19:17:591527 if (!events->empty())
[email protected]ec1d6d52012-10-10 01:28:571528 m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
[email protected]94f206c12012-08-25 00:09:141529
[email protected]de4afb5e2012-12-20 00:11:341530 m_client->setNeedsRedrawOnImplThread();
1531 setNeedsUpdateDrawProperties();
1532 setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
[email protected]94f206c12012-08-25 00:09:141533}
1534
[email protected]96baf3e2012-10-22 23:09:551535base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const
[email protected]94f206c12012-08-25 00:09:141536{
[email protected]4481ddb622012-09-20 16:33:471537 return base::TimeDelta::FromSeconds(1);
[email protected]94f206c12012-08-25 00:09:141538}
1539
[email protected]3be2171d2012-12-06 06:13:201540void LayerTreeHostImpl::sendDidLoseOutputSurfaceRecursive(LayerImpl* current)
[email protected]94f206c12012-08-25 00:09:141541{
[email protected]1d993172012-10-18 18:15:041542 DCHECK(current);
[email protected]3be2171d2012-12-06 06:13:201543 current->didLoseOutputSurface();
[email protected]94f206c12012-08-25 00:09:141544 if (current->maskLayer())
[email protected]3be2171d2012-12-06 06:13:201545 sendDidLoseOutputSurfaceRecursive(current->maskLayer());
[email protected]94f206c12012-08-25 00:09:141546 if (current->replicaLayer())
[email protected]3be2171d2012-12-06 06:13:201547 sendDidLoseOutputSurfaceRecursive(current->replicaLayer());
[email protected]94f206c12012-08-25 00:09:141548 for (size_t i = 0; i < current->children().size(); ++i)
[email protected]3be2171d2012-12-06 06:13:201549 sendDidLoseOutputSurfaceRecursive(current->children()[i]);
[email protected]94f206c12012-08-25 00:09:141550}
1551
[email protected]96baf3e2012-10-22 23:09:551552void LayerTreeHostImpl::clearRenderSurfaces()
[email protected]94f206c12012-08-25 00:09:141553{
[email protected]76ffd9e2012-12-20 19:12:471554 activeTree()->ClearRenderSurfaces();
1555 if (pendingTree())
1556 pendingTree()->ClearRenderSurfaces();
[email protected]94f206c12012-08-25 00:09:141557}
1558
[email protected]96baf3e2012-10-22 23:09:551559std::string LayerTreeHostImpl::layerTreeAsText() const
[email protected]94f206c12012-08-25 00:09:141560{
[email protected]515e8d232012-09-10 19:15:271561 std::string str;
[email protected]3b31c6ac2012-12-06 21:27:291562 if (rootLayer()) {
1563 str = rootLayer()->layerTreeAsText();
[email protected]515e8d232012-09-10 19:15:271564 str += "RenderSurfaces:\n";
[email protected]3b31c6ac2012-12-06 21:27:291565 dumpRenderSurfaces(&str, 1, rootLayer());
[email protected]94f206c12012-08-25 00:09:141566 }
[email protected]515e8d232012-09-10 19:15:271567 return str;
[email protected]94f206c12012-08-25 00:09:141568}
1569
[email protected]4a23c374c2012-12-08 08:38:551570std::string LayerTreeHostImpl::layerTreeAsJson() const
1571{
1572 std::string str;
1573 if (rootLayer()) {
1574 scoped_ptr<base::Value> json(rootLayer()->layerTreeAsJson());
1575 base::JSONWriter::WriteWithOptions(
1576 json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
1577 }
1578 return str;
1579}
1580
[email protected]96baf3e2012-10-22 23:09:551581void LayerTreeHostImpl::dumpRenderSurfaces(std::string* str, int indent, const LayerImpl* layer) const
[email protected]94f206c12012-08-25 00:09:141582{
1583 if (layer->renderSurface())
[email protected]515e8d232012-09-10 19:15:271584 layer->renderSurface()->dumpSurface(str, indent);
[email protected]94f206c12012-08-25 00:09:141585
1586 for (size_t i = 0; i < layer->children().size(); ++i)
[email protected]0920e24f2012-09-20 03:34:031587 dumpRenderSurfaces(str, indent, layer->children()[i]);
[email protected]94f206c12012-08-25 00:09:141588}
1589
[email protected]96baf3e2012-10-22 23:09:551590int LayerTreeHostImpl::sourceAnimationFrameNumber() const
[email protected]94f206c12012-08-25 00:09:141591{
1592 return fpsCounter()->currentFrameNumber();
1593}
1594
[email protected]96baf3e2012-10-22 23:09:551595void LayerTreeHostImpl::renderingStats(RenderingStats* stats) const
[email protected]94f206c12012-08-25 00:09:141596{
[email protected]8b9af6b2012-09-27 00:36:361597 stats->numFramesSentToScreen = fpsCounter()->currentFrameNumber();
1598 stats->droppedFrameCount = fpsCounter()->droppedFrameCount();
[email protected]5c6fe1f82012-10-03 18:00:271599 stats->numImplThreadScrolls = m_numImplThreadScrolls;
1600 stats->numMainThreadScrolls = m_numMainThreadScrolls;
[email protected]b2136f12012-11-30 02:45:531601 stats->numLayersDrawn = m_cumulativeNumLayersDrawn;
[email protected]f2bbb4e2012-12-07 21:40:491602 stats->numMissingTiles = m_cumulativeNumMissingTiles;
[email protected]4d3c5c912012-11-30 05:55:021603
1604 if (m_tileManager)
[email protected]ee371e02012-12-16 20:13:441605 m_tileManager->GetRenderingStats(stats);
[email protected]94f206c12012-08-25 00:09:141606}
1607
[email protected]d3afa112012-12-08 06:24:281608void LayerTreeHostImpl::sendManagedMemoryStats(
1609 size_t memoryVisibleBytes,
1610 size_t memoryVisibleAndNearbyBytes,
1611 size_t memoryUseBytes)
1612{
1613 if (!renderer())
1614 return;
1615
1616 // Round the numbers being sent up to the next 8MB, to throttle the rate
1617 // at which we spam the GPU process.
1618 static const size_t roundingStep = 8 * 1024 * 1024;
1619 memoryVisibleBytes = RoundUp(memoryVisibleBytes, roundingStep);
1620 memoryVisibleAndNearbyBytes = RoundUp(memoryVisibleAndNearbyBytes, roundingStep);
1621 memoryUseBytes = RoundUp(memoryUseBytes, roundingStep);
1622 if (m_lastSentMemoryVisibleBytes == memoryVisibleBytes &&
1623 m_lastSentMemoryVisibleAndNearbyBytes == memoryVisibleAndNearbyBytes &&
1624 m_lastSentMemoryUseBytes == memoryUseBytes) {
1625 return;
1626 }
1627 m_lastSentMemoryVisibleBytes = memoryVisibleBytes;
1628 m_lastSentMemoryVisibleAndNearbyBytes = memoryVisibleAndNearbyBytes;
1629 m_lastSentMemoryUseBytes = memoryUseBytes;
1630
1631 renderer()->sendManagedMemoryStats(m_lastSentMemoryVisibleBytes,
1632 m_lastSentMemoryVisibleAndNearbyBytes,
1633 m_lastSentMemoryUseBytes);
1634}
1635
[email protected]30faac92012-10-29 00:06:291636void LayerTreeHostImpl::animateScrollbars(base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141637{
[email protected]3b31c6ac2012-12-06 21:27:291638 animateScrollbarsRecursive(rootLayer(), time);
[email protected]94f206c12012-08-25 00:09:141639}
1640
[email protected]30faac92012-10-29 00:06:291641void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeTicks time)
[email protected]94f206c12012-08-25 00:09:141642{
1643 if (!layer)
1644 return;
1645
[email protected]96baf3e2012-10-22 23:09:551646 ScrollbarAnimationController* scrollbarController = layer->scrollbarAnimationController();
[email protected]e45638c2013-01-17 22:01:401647 if (scrollbarController && scrollbarController->animate(time))
[email protected]94f206c12012-08-25 00:09:141648 m_client->setNeedsRedrawOnImplThread();
1649
1650 for (size_t i = 0; i < layer->children().size(); ++i)
[email protected]30faac92012-10-29 00:06:291651 animateScrollbarsRecursive(layer->children()[i], time);
[email protected]94f206c12012-08-25 00:09:141652}
1653
[email protected]362f1e8b2013-01-21 16:54:301654void LayerTreeHostImpl::setTreePriority(TreePriority priority)
1655{
1656 if (!m_tileManager)
1657 return;
1658
1659 GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState());
1660 if (new_state.tree_priority == priority)
1661 return;
1662
1663 TRACE_COUNTER_ID1("cc", "TreePriority", this, priority);
1664 new_state.tree_priority = priority;
1665 m_tileManager->SetGlobalState(new_state);
1666}
1667
[email protected]b9dcf43a2013-01-09 00:15:291668// static
1669LayerImpl* LayerTreeHostImpl::getNonCompositedContentLayerRecursive(LayerImpl* layer)
1670{
1671 if (!layer)
1672 return NULL;
1673
1674 if (layer->drawsContent())
1675 return layer;
1676
1677 for (LayerImpl::LayerList::const_iterator it = layer->children().begin();
1678 it != layer->children().end(); ++it) {
1679 LayerImpl* nccr = getNonCompositedContentLayerRecursive(*it);
1680 if (nccr)
1681 return nccr;
1682 }
1683
1684 return NULL;
1685}
1686
1687skia::RefPtr<SkPicture> LayerTreeHostImpl::capturePicture()
1688{
1689 LayerTreeImpl* tree = pendingTree() ? pendingTree() : activeTree();
1690 LayerImpl* layer = getNonCompositedContentLayerRecursive(tree->RootLayer());
1691 return layer ? layer->getPicture() : skia::RefPtr<SkPicture>();
1692}
1693
[email protected]0edbfbe9f2013-01-17 03:33:031694void LayerTreeHostImpl::savePaintTime(const base::TimeDelta& totalPaintTime)
1695{
1696 m_paintTimeCounter->SavePaintTime(totalPaintTime);
1697}
1698
[email protected]d3143c732012-10-05 19:17:591699} // namespace cc