Chromium Code Reviews| Index: cc/layer_tree_host_impl.cc |
| diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc |
| index 18280b9e089376d3e2d0d11a12bc35033bb720e2..86cb078daad2673da09159d5638f7ebb6f41c1f1 100644 |
| --- a/cc/layer_tree_host_impl.cc |
| +++ b/cc/layer_tree_host_impl.cc |
| @@ -50,1691 +50,1881 @@ |
| namespace { |
| -void didVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) |
| -{ |
| - if (visible) { |
| - TRACE_EVENT_ASYNC_BEGIN1("webkit", "LayerTreeHostImpl::setVisible", id, "LayerTreeHostImpl", id); |
| - return; |
| - } |
| +void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) { |
| + if (visible) { |
| + TRACE_EVENT_ASYNC_BEGIN1("webkit", |
| + "LayerTreeHostImpl::setVisible", |
| + id, |
| + "LayerTreeHostImpl", |
| + id); |
| + return; |
| + } |
| - TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::setVisible", id); |
| + TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::setVisible", id); |
| } |
| -std::string ValueToString(scoped_ptr<base::Value> value) |
| -{ |
| - std::string str; |
| - base::JSONWriter::Write(value.get(), &str); |
| - return str; |
| +std::string ValueToString(scoped_ptr<base::Value> value) { |
| + std::string str; |
| + base::JSONWriter::Write(value.get(), &str); |
| + return str; |
| } |
| -} // namespace |
| +} // namespace |
| namespace cc { |
| class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { |
| -public: |
| - static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource) |
| - { |
| - return make_scoped_ptr(new LayerTreeHostImplTimeSourceAdapter(layerTreeHostImpl, timeSource)); |
| - } |
| - virtual ~LayerTreeHostImplTimeSourceAdapter() |
| - { |
| - m_timeSource->setClient(0); |
| - m_timeSource->setActive(false); |
| - } |
| - |
| - virtual void onTimerTick() OVERRIDE |
| - { |
| - // In single threaded mode we attempt to simulate changing the current |
| - // thread by maintaining a fake thread id. When we switch from one |
| - // thread to another, we construct DebugScopedSetXXXThread objects that |
| - // update the thread id. This lets DCHECKS that ensure we're on the |
| - // right thread to work correctly in single threaded mode. The problem |
| - // here is that the timer tasks are run via the message loop, and when |
| - // they run, we've had no chance to construct a DebugScopedSetXXXThread |
| - // object. The result is that we report that we're running on the main |
| - // thread. In multi-threaded mode, this timer is run on the compositor |
| - // thread, so to keep this consistent in single-threaded mode, we'll |
| - // construct a DebugScopedSetImplThread object. There is no need to do |
| - // this in multi-threaded mode since the real thread id's will be |
| - // correct. In fact, setting fake thread id's interferes with the real |
| - // thread id's and causes breakage. |
| - scoped_ptr<DebugScopedSetImplThread> setImplThread; |
| - if (!m_layerTreeHostImpl->proxy()->HasImplThread()) |
| - setImplThread.reset(new DebugScopedSetImplThread(m_layerTreeHostImpl->proxy())); |
| - |
| - m_layerTreeHostImpl->activatePendingTreeIfNeeded(); |
| - m_layerTreeHostImpl->animate(base::TimeTicks::Now(), base::Time::Now()); |
| - m_layerTreeHostImpl->beginNextFrame(); |
| + public: |
| + static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create( |
| + LayerTreeHostImpl* layer_tree_host_impl, |
| + scoped_refptr<DelayBasedTimeSource> time_source) { |
| + return make_scoped_ptr( |
| + new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl, |
| + time_source)); |
| + } |
| + virtual ~LayerTreeHostImplTimeSourceAdapter() { |
| + time_source_->setClient(NULL); |
| + time_source_->setActive(false); |
| + } |
| + |
| + virtual void onTimerTick() OVERRIDE { |
| + // In single threaded mode we attempt to simulate changing the current |
| + // thread by maintaining a fake thread id. When we switch from one |
| + // thread to another, we construct DebugScopedSetXXXThread objects that |
| + // update the thread id. This lets DCHECKS that ensure we're on the |
| + // right thread to work correctly in single threaded mode. The problem |
| + // here is that the timer tasks are run via the message loop, and when |
| + // they run, we've had no chance to construct a DebugScopedSetXXXThread |
| + // object. The result is that we report that we're running on the main |
| + // thread. In multi-threaded mode, this timer is run on the compositor |
| + // thread, so to keep this consistent in single-threaded mode, we'll |
| + // construct a DebugScopedSetImplThread object. There is no need to do |
| + // this in multi-threaded mode since the real thread id's will be |
| + // correct. In fact, setting fake thread id's interferes with the real |
| + // thread id's and causes breakage. |
| + scoped_ptr<DebugScopedSetImplThread> set_impl_thread; |
| + if (!layer_tree_host_impl_->proxy()->HasImplThread()) { |
| + set_impl_thread.reset( |
| + new DebugScopedSetImplThread(layer_tree_host_impl_->proxy())); |
| } |
| - void setActive(bool active) |
| - { |
| - if (active != m_timeSource->active()) |
| - m_timeSource->setActive(active); |
| - } |
| - |
| -private: |
| - LayerTreeHostImplTimeSourceAdapter(LayerTreeHostImpl* layerTreeHostImpl, scoped_refptr<DelayBasedTimeSource> timeSource) |
| - : m_layerTreeHostImpl(layerTreeHostImpl) |
| - , m_timeSource(timeSource) |
| - { |
| - m_timeSource->setClient(this); |
| - } |
| - |
| - LayerTreeHostImpl* m_layerTreeHostImpl; |
| - scoped_refptr<DelayBasedTimeSource> m_timeSource; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter); |
| + layer_tree_host_impl_->ActivatePendingTreeIfNeeded(); |
| + layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now()); |
| + layer_tree_host_impl_->BeginNextFrame(); |
| + } |
| + |
| + void SetActive(bool active) { |
| + if (active != time_source_->active()) |
| + time_source_->setActive(active); |
| + } |
| + |
| + private: |
| + LayerTreeHostImplTimeSourceAdapter( |
| + LayerTreeHostImpl* layer_tree_host_impl, |
| + scoped_refptr<DelayBasedTimeSource> time_source) |
| + : layer_tree_host_impl_(layer_tree_host_impl), |
| + time_source_(time_source) { |
| + time_source_->setClient(this); |
| + } |
| + |
| + LayerTreeHostImpl* layer_tree_host_impl_; |
| + scoped_refptr<DelayBasedTimeSource> time_source_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter); |
| }; |
| LayerTreeHostImpl::FrameData::FrameData() |
| - : containsIncompleteTile(false) |
| -{ |
| -} |
| - |
| -LayerTreeHostImpl::FrameData::~FrameData() |
| -{ |
| -} |
| - |
| -scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::create(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy) |
| -{ |
| - return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy)); |
| -} |
| - |
| -LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy) |
| - : m_client(client) |
| - , m_proxy(proxy) |
| - , m_didLockScrollingLayer(false) |
| - , m_shouldBubbleScrolls(false) |
| - , m_wheelScrolling(false) |
| - , m_settings(settings) |
| - , m_deviceScaleFactor(1) |
| - , m_visible(true) |
| - , m_managedMemoryPolicy(PrioritizedResourceManager::defaultMemoryAllocationLimit(), |
| - ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, |
| - 0, |
| - ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING) |
| - , m_pinchGestureActive(false) |
| - , m_fpsCounter(FrameRateCounter::create(m_proxy->HasImplThread())) |
| - , m_paintTimeCounter(PaintTimeCounter::create()) |
| - , m_memoryHistory(MemoryHistory::Create()) |
| - , m_debugRectHistory(DebugRectHistory::create()) |
| - , m_numImplThreadScrolls(0) |
| - , m_numMainThreadScrolls(0) |
| - , m_cumulativeNumLayersDrawn(0) |
| - , m_cumulativeNumMissingTiles(0) |
| - , m_lastSentMemoryVisibleBytes(0) |
| - , m_lastSentMemoryVisibleAndNearbyBytes(0) |
| - , m_lastSentMemoryUseBytes(0) |
| - , m_animationRegistrar(AnimationRegistrar::create()) |
| -{ |
| - DCHECK(m_proxy->IsImplThread()); |
| - didVisibilityChange(this, m_visible); |
| - |
| - setDebugState(settings.initialDebugState); |
| - |
| - if (settings.calculateTopControlsPosition) { |
| - m_topControlsManager = TopControlsManager::Create(this, |
| - settings.topControlsHeight, |
| - settings.topControlsShowThreshold, |
| - settings.topControlsHideThreshold); |
| - } |
| - |
| - setDebugState(settings.initialDebugState); |
| - |
| - // LTHI always has an active tree. |
| - m_activeTree = LayerTreeImpl::create(this); |
| -} |
| - |
| -LayerTreeHostImpl::~LayerTreeHostImpl() |
| -{ |
| - DCHECK(m_proxy->IsImplThread()); |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); |
| - |
| - if (rootLayer()) { |
| - clearRenderSurfaces(); |
| - // The layer trees must be destroyed before the layer tree host. We've |
| - // made a contract with our animation controllers that the registrar |
| - // will outlive them, and we must make good. |
| - m_recycleTree.reset(); |
| - m_pendingTree.reset(); |
| - m_activeTree.reset(); |
| - } |
| -} |
| - |
| -void LayerTreeHostImpl::beginCommit() |
| -{ |
| -} |
| - |
| -void LayerTreeHostImpl::commitComplete() |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::commitComplete"); |
| - |
| - // Impl-side painting needs an update immediately post-commit to have the |
| - // opportunity to create tilings. Other paths can call updateDrawProperties |
| - // more lazily when needed prior to drawing. |
| - if (m_settings.implSidePainting) { |
| - pendingTree()->set_needs_update_draw_properties(); |
| - pendingTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE); |
| - } else { |
| - activeTree()->set_needs_update_draw_properties(); |
| - } |
| - |
| - m_client->sendManagedMemoryStats(); |
| -} |
| - |
| -bool LayerTreeHostImpl::canDraw() |
| -{ |
| - // Note: If you are changing this function or any other function that might |
| - // affect the result of canDraw, make sure to call m_client->onCanDrawStateChanged |
| - // in the proper places and update the notifyIfCanDrawChanged test. |
| - |
| - if (!rootLayer()) { |
| - TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no root layer"); |
| - return false; |
| - } |
| - if (DeviceViewportSize().IsEmpty()) { |
| - TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw empty viewport"); |
| - return false; |
| - } |
| - if (m_activeTree->ViewportSizeInvalid()) { |
| - TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw viewport size recently changed"); |
| - return false; |
| - } |
| - if (!m_renderer) { |
| - TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no renderer"); |
| - return false; |
| - } |
| - if (m_activeTree->ContentsTexturesPurged()) { |
| - TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw contents textures purged"); |
| - return false; |
| - } |
| - return true; |
| -} |
| - |
| -OutputSurface* LayerTreeHostImpl::outputSurface() const |
| -{ |
| - return m_outputSurface.get(); |
| -} |
| - |
| -void LayerTreeHostImpl::animate(base::TimeTicks monotonicTime, base::Time wallClockTime) |
| -{ |
| - animatePageScale(monotonicTime); |
| - animateLayers(monotonicTime, wallClockTime); |
| - animateScrollbars(monotonicTime); |
| - if (m_topControlsManager) |
| - m_topControlsManager->Animate(monotonicTime); |
| -} |
| - |
| -void LayerTreeHostImpl::manageTiles() |
| -{ |
| - DCHECK(m_tileManager); |
| - m_tileManager->ManageTiles(); |
| - |
| - size_t memoryRequiredBytes; |
| - size_t memoryNiceToHaveBytes; |
| - size_t memoryUsedBytes; |
| - m_tileManager->GetMemoryStats(&memoryRequiredBytes, |
| - &memoryNiceToHaveBytes, |
| - &memoryUsedBytes); |
| - sendManagedMemoryStats(memoryRequiredBytes, |
| - memoryNiceToHaveBytes, |
| - memoryUsedBytes); |
| -} |
| - |
| -void LayerTreeHostImpl::startPageScaleAnimation(gfx::Vector2d targetOffset, bool anchorPoint, float pageScale, base::TimeTicks startTime, base::TimeDelta duration) |
| -{ |
| - if (!rootScrollLayer()) |
| - return; |
| - |
| - gfx::Vector2dF scrollTotal = rootScrollLayer()->scroll_offset() + rootScrollLayer()->scroll_delta(); |
| - gfx::SizeF scaledScrollableSize = activeTree()->ScrollableSize(); |
| - gfx::SizeF viewportSize = gfx::ScaleSize(m_deviceViewportSize, 1 / m_deviceScaleFactor); |
| - |
| - double startTimeSeconds = (startTime - base::TimeTicks()).InSecondsF(); |
| - m_pageScaleAnimation = PageScaleAnimation::Create(scrollTotal, activeTree()->total_page_scale_factor(), viewportSize, scaledScrollableSize, startTimeSeconds); |
| - |
| - if (anchorPoint) { |
| - gfx::Vector2dF anchor(targetOffset); |
| - m_pageScaleAnimation->ZoomWithAnchor(anchor, pageScale, duration.InSecondsF()); |
| - } else { |
| - gfx::Vector2dF scaledTargetOffset = targetOffset; |
| - m_pageScaleAnimation->ZoomTo(scaledTargetOffset, pageScale, duration.InSecondsF()); |
| - } |
| - |
| - m_client->setNeedsRedrawOnImplThread(); |
| - m_client->setNeedsCommitOnImplThread(); |
| - m_client->renewTreePriority(); |
| -} |
| - |
| -void LayerTreeHostImpl::scheduleAnimation() |
| -{ |
| - m_client->setNeedsRedrawOnImplThread(); |
| -} |
| - |
| -bool LayerTreeHostImpl::haveTouchEventHandlersAt(const gfx::Point& viewportPoint) |
| -{ |
| - if (!ensureRenderSurfaceLayerList()) |
| - return false; |
| - |
| - gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceScaleFactor); |
| - |
| - // First find out which layer was hit from the saved list of visible layers |
| - // in the most recent frame. |
| - LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(deviceViewportPoint, activeTree()->RenderSurfaceLayerList()); |
| - |
| - // Walk up the hierarchy and look for a layer with a touch event handler region that the given point hits. |
| - for (; layerImpl; layerImpl = layerImpl->parent()) { |
| - if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(deviceViewportPoint,layerImpl)) |
| - return true; |
| - } |
| - |
| + : contains_incomplete_tile(false) {} |
| + |
| +LayerTreeHostImpl::FrameData::~FrameData() {} |
| + |
| +scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( |
| + const LayerTreeSettings& settings, |
| + LayerTreeHostImplClient* client, |
| + Proxy* proxy) { |
| + return make_scoped_ptr(new LayerTreeHostImpl(settings, client, proxy)); |
| +} |
| + |
| +LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, |
| + LayerTreeHostImplClient* client, |
| + Proxy* proxy) |
| + : client_(client), |
| + proxy_(proxy), |
| + did_lock_scrolling_layer_(false), |
| + should_bubble_scrolls_(false), |
| + wheel_scrolling_(false), |
| + settings_(settings), |
| + device_scale_factor_(1.f), |
| + visible_(true), |
| + managed_memory_policy_( |
| + PrioritizedResourceManager::defaultMemoryAllocationLimit(), |
| + ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, |
| + 0, |
| + ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING), |
| + pinch_gesture_active_(false), |
| + fps_counter_(FrameRateCounter::create(proxy_->HasImplThread())), |
| + paint_time_counter_(PaintTimeCounter::create()), |
| + memory_history_(MemoryHistory::Create()), |
| + debug_rect_history_(DebugRectHistory::create()), |
| + num_impl_thread_scrolls_(0), |
| + num_main_thread_scrolls_(0), |
| + cumulative_num_layers_drawn_(0), |
| + cumulative_num_missing_tiles_(0), |
| + last_sent_memory_visible_bytes_(0), |
| + last_sent_memory_visible_and_nearby_bytes_(0), |
| + last_sent_memory_use_bytes_(0), |
| + animation_registrar_(AnimationRegistrar::create()) { |
| + DCHECK(proxy_->IsImplThread()); |
| + DidVisibilityChange(this, visible_); |
| + |
| + SetDebugState(settings.initialDebugState); |
| + |
| + if (settings.calculateTopControlsPosition) { |
| + top_controls_manager_ = |
| + TopControlsManager::Create(this, |
| + settings.topControlsHeight, |
| + settings.topControlsShowThreshold, |
| + settings.topControlsHideThreshold); |
| + } |
| + |
| + SetDebugState(settings.initialDebugState); |
| + |
| + // LTHI always has an active tree. |
| + active_tree_ = LayerTreeImpl::create(this); |
| +} |
| + |
| +LayerTreeHostImpl::~LayerTreeHostImpl() { |
| + DCHECK(proxy_->IsImplThread()); |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); |
| + |
| + if (active_tree_->root_layer()) { |
| + ClearRenderSurfaces(); |
| + // The layer trees must be destroyed before the layer tree host. We've |
| + // made a contract with our animation controllers that the registrar |
| + // will outlive them, and we must make good. |
| + recycle_tree_.reset(); |
| + pending_tree_.reset(); |
| + active_tree_.reset(); |
| + } |
| +} |
| + |
| +void LayerTreeHostImpl::BeginCommit() {} |
| + |
| +void LayerTreeHostImpl::CommitComplete() { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::commitComplete"); |
| + |
| + // Impl-side painting needs an update immediately post-commit to have the |
| + // opportunity to create tilings. Other paths can call updateDrawProperties |
|
enne (OOO)
2013/03/13 05:22:05
UpdateDrawProperties
danakj
2013/03/13 15:49:11
Done.
|
| + // more lazily when needed prior to drawing. |
| + if (settings_.implSidePainting) { |
| + pending_tree_->set_needs_update_draw_properties(); |
| + pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE); |
| + } else { |
| + active_tree_->set_needs_update_draw_properties(); |
| + } |
| + |
| + client_->SendManagedMemoryStats(); |
| +} |
| + |
| +bool LayerTreeHostImpl::CanDraw() { |
| + // Note: If you are changing this function or any other function that might |
| + // affect the result of CanDraw, make sure to call |
| + // client_->OnCanDrawStateChanged in the proper places and update the |
| + // NotifyIfCanDrawChanged test. |
| + |
| + if (!active_tree_->root_layer()) { |
| + TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no root layer"); |
|
enne (OOO)
2013/03/13 05:22:05
CanDraw
danakj
2013/03/13 15:49:11
Done.
|
| + return false; |
| + } |
| + if (device_viewport_size_.IsEmpty()) { |
| + TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw empty viewport"); |
|
enne (OOO)
2013/03/13 05:22:05
CanDraw
danakj
2013/03/13 15:49:11
Done.
|
| + return false; |
| + } |
| + if (active_tree_->ViewportSizeInvalid()) { |
| + TRACE_EVENT_INSTANT0( |
| + "cc", "LayerTreeHostImpl::canDraw viewport size recently changed"); |
|
enne (OOO)
2013/03/13 05:22:05
CanDraw
danakj
2013/03/13 15:49:11
Done.
|
| + return false; |
| + } |
| + if (!renderer_) { |
| + TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no renderer"); |
|
enne (OOO)
2013/03/13 05:22:05
CanDraw
danakj
2013/03/13 15:49:11
Done.
|
| + return false; |
| + } |
| + if (active_tree_->ContentsTexturesPurged()) { |
| + TRACE_EVENT_INSTANT0( |
| + "cc", "LayerTreeHostImpl::canDraw contents textures purged"); |
|
enne (OOO)
2013/03/13 05:22:05
CanDraw
danakj
2013/03/13 15:49:11
Done.
|
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time, |
| + base::Time wall_clock_time) { |
| + AnimatePageScale(monotonic_time); |
| + AnimateLayers(monotonic_time, wall_clock_time); |
| + AnimateScrollbars(monotonic_time); |
| + if (top_controls_manager_) |
| + top_controls_manager_->Animate(monotonic_time); |
| +} |
| + |
| +void LayerTreeHostImpl::ManageTiles() { |
| + DCHECK(tile_manager_); |
| + tile_manager_->ManageTiles(); |
| + |
| + size_t memory_required_bytes; |
| + size_t memory_nice_to_have_bytes; |
| + size_t memory_used_bytes; |
| + tile_manager_->GetMemoryStats(&memory_required_bytes, |
| + &memory_nice_to_have_bytes, |
| + &memory_used_bytes); |
| + SendManagedMemoryStats(memory_required_bytes, |
| + memory_nice_to_have_bytes, |
| + memory_used_bytes); |
| +} |
| + |
| +void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset, |
| + bool anchor_point, |
| + float page_scale, |
| + base::TimeTicks start_time, |
| + base::TimeDelta duration) { |
| + if (!RootScrollLayer()) |
| + return; |
| + |
| + gfx::Vector2dF scroll_total = |
| + RootScrollLayer()->scroll_offset() + RootScrollLayer()->scroll_delta(); |
| + gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize(); |
| + gfx::SizeF viewport_size = |
| + gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor_); |
| + |
| + double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF(); |
| + page_scale_animation_ = |
| + PageScaleAnimation::Create(scroll_total, |
| + active_tree_->total_page_scale_factor(), |
| + viewport_size, |
| + scaled_scrollable_size, |
| + start_time_seconds); |
| + |
| + if (anchor_point) { |
| + gfx::Vector2dF anchor(target_offset); |
| + page_scale_animation_->ZoomWithAnchor(anchor, |
| + page_scale, |
| + duration.InSecondsF()); |
| + } else { |
| + gfx::Vector2dF scaled_target_offset = target_offset; |
| + page_scale_animation_->ZoomTo(scaled_target_offset, |
| + page_scale, |
| + duration.InSecondsF()); |
| + } |
| + |
| + client_->SetNeedsRedrawOnImplThread(); |
| + client_->SetNeedsCommitOnImplThread(); |
| + client_->RenewTreePriority(); |
| +} |
| + |
| +void LayerTreeHostImpl::ScheduleAnimation() { |
| + client_->SetNeedsRedrawOnImplThread(); |
| +} |
| + |
| +bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) { |
| + if (!EnsureRenderSurfaceLayerList()) |
| return false; |
| -} |
| - |
| -void LayerTreeHostImpl::trackDamageForAllSurfaces(LayerImpl* rootDrawLayer, const LayerList& renderSurfaceLayerList) |
| -{ |
| - // For now, we use damage tracking to compute a global scissor. To do this, we must |
| - // compute all damage tracking before drawing anything, so that we know the root |
| - // damage rect. The root damage rect is then used to scissor each surface. |
| - |
| - for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { |
| - LayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; |
| - RenderSurfaceImpl* renderSurface = renderSurfaceLayer->render_surface(); |
| - DCHECK(renderSurface); |
| - renderSurface->damage_tracker()->UpdateDamageTrackingState(renderSurface->layer_list(), renderSurfaceLayer->id(), renderSurface->SurfacePropertyChangedOnlyFromDescendant(), renderSurface->content_rect(), renderSurfaceLayer->mask_layer(), renderSurfaceLayer->filters(), renderSurfaceLayer->filter().get()); |
| - } |
| -} |
| - |
| -void LayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<RenderPass> renderPass) |
| -{ |
| - renderPassesById[renderPass->id] = renderPass.get(); |
| - renderPasses.push_back(renderPass.Pass()); |
| -} |
| - |
| -static void appendQuadsForLayer(RenderPass* targetRenderPass, LayerImpl* layer, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData) |
| -{ |
| - bool forSurface = false; |
| - QuadCuller quadCuller(targetRenderPass->quad_list, |
| - targetRenderPass->shared_quad_state_list, |
| - layer, |
| - occlusionTracker, |
| - layer->ShowDebugBorders(), |
| - forSurface); |
| - layer->AppendQuads(&quadCuller, &appendQuadsData); |
| -} |
| - |
| -static void appendQuadsForRenderSurfaceLayer(RenderPass* targetRenderPass, LayerImpl* layer, const RenderPass* contributingRenderPass, OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData) |
| -{ |
| - bool forSurface = true; |
| - QuadCuller quadCuller(targetRenderPass->quad_list, |
| - targetRenderPass->shared_quad_state_list, |
| - layer, |
| - occlusionTracker, |
| - layer->ShowDebugBorders(), |
| - forSurface); |
| - bool isReplica = false; |
| + gfx::PointF device_viewport_point = |
| + gfx::ScalePoint(viewport_point, device_scale_factor_); |
| + |
| + // First find out which layer was hit from the saved list of visible layers |
| + // in the most recent frame. |
| + LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint( |
| + device_viewport_point, |
| + active_tree_->RenderSurfaceLayerList()); |
| + |
| + // Walk up the hierarchy and look for a layer with a touch event handler |
| + // region that the given point hits. |
| + for (; layer_impl; layer_impl = layer_impl->parent()) { |
| + if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(device_viewport_point, |
| + layer_impl)) |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +void LayerTreeHostImpl::TrackDamageForAllSurfaces( |
| + LayerImpl* root_draw_layer, |
| + const LayerList& render_surface_layer_list) { |
| + // For now, we use damage tracking to compute a global scissor. To do this, we |
| + // must compute all damage tracking before drawing anything, so that we know |
| + // the root damage rect. The root damage rect is then used to scissor each |
| + // surface. |
| + |
| + for (int surfaceIndex = render_surface_layer_list.size() - 1; |
| + surfaceIndex >= 0 ; |
| + --surfaceIndex) { |
| + LayerImpl* render_surface_layer = render_surface_layer_list[surfaceIndex]; |
| + RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); |
| + DCHECK(render_surface); |
| + render_surface->damage_tracker()->UpdateDamageTrackingState( |
| + render_surface->layer_list(), |
| + render_surface_layer->id(), |
| + render_surface->SurfacePropertyChangedOnlyFromDescendant(), |
| + render_surface->content_rect(), |
| + render_surface_layer->mask_layer(), |
| + render_surface_layer->filters(), |
| + render_surface_layer->filter().get()); |
| + } |
| +} |
| + |
| +void LayerTreeHostImpl::FrameData::AppendRenderPass( |
| + scoped_ptr<RenderPass> render_pass) { |
| + render_passes_by_id[render_pass->id] = render_pass.get(); |
| + render_passes.push_back(render_pass.Pass()); |
| +} |
| + |
| +static void AppendQuadsForLayer(RenderPass* target_render_pass, |
| + LayerImpl* layer, |
| + const OcclusionTrackerImpl& occlusion_tracker, |
| + AppendQuadsData* append_quads_data) { |
| + bool for_surface = false; |
| + QuadCuller quadCuller(target_render_pass->quad_list, |
| + target_render_pass->shared_quad_state_list, |
| + layer, |
| + occlusion_tracker, |
| + layer->ShowDebugBorders(), |
| + for_surface); |
| + layer->AppendQuads(&quadCuller, append_quads_data); |
| +} |
| + |
| +static void AppendQuadsForRenderSurfaceLayer( |
| + RenderPass* target_render_pass, |
| + LayerImpl* layer, |
| + const RenderPass* contributing_render_pass, |
| + const OcclusionTrackerImpl& occlusion_tracker, |
| + AppendQuadsData* append_quads_data) { |
| + bool for_surface = true; |
| + QuadCuller quadCuller(target_render_pass->quad_list, |
| + target_render_pass->shared_quad_state_list, |
| + layer, |
| + occlusion_tracker, |
| + layer->ShowDebugBorders(), |
| + for_surface); |
| + |
| + bool is_replica = false; |
| + layer->render_surface()->AppendQuads(&quadCuller, |
| + append_quads_data, |
| + is_replica, |
| + contributing_render_pass->id); |
| + |
| + // Add replica after the surface so that it appears below the surface. |
| + if (layer->has_replica()) { |
| + is_replica = true; |
| layer->render_surface()->AppendQuads(&quadCuller, |
| - &appendQuadsData, |
| - isReplica, |
| - contributingRenderPass->id); |
| - |
| - // Add replica after the surface so that it appears below the surface. |
| - if (layer->has_replica()) { |
| - isReplica = true; |
| - layer->render_surface()->AppendQuads(&quadCuller, |
| - &appendQuadsData, |
| - isReplica, |
| - contributingRenderPass->id); |
| - } |
| -} |
| - |
| -static void appendQuadsToFillScreen(RenderPass* targetRenderPass, LayerImpl* rootLayer, SkColor screenBackgroundColor, const OcclusionTrackerImpl& occlusionTracker) |
| -{ |
| - if (!rootLayer || !SkColorGetA(screenBackgroundColor)) |
| - return; |
| - |
| - Region fillRegion = occlusionTracker.ComputeVisibleRegionInScreen(); |
| - if (fillRegion.IsEmpty()) |
| - return; |
| - |
| - bool forSurface = false; |
| - QuadCuller quadCuller(targetRenderPass->quad_list, |
| - targetRenderPass->shared_quad_state_list, |
| - rootLayer, |
| - occlusionTracker, |
| - rootLayer->ShowDebugBorders(), |
| - forSurface); |
| - |
| - // Manually create the quad state for the gutter quads, as the root layer |
| - // doesn't have any bounds and so can't generate this itself. |
| - // FIXME: Make the gutter quads generated by the solid color layer (make it smarter about generating quads to fill unoccluded areas). |
| - |
| - gfx::Rect rootTargetRect = rootLayer->render_surface()->content_rect(); |
| - float opacity = 1; |
| - SharedQuadState* sharedQuadState = quadCuller.useSharedQuadState(SharedQuadState::Create()); |
| - sharedQuadState->SetAll(rootLayer->draw_transform(), |
| - rootTargetRect.size(), |
| - rootTargetRect, |
| - rootTargetRect, |
| + append_quads_data, |
| + is_replica, |
| + contributing_render_pass->id); |
| + } |
| +} |
| + |
| +static void AppendQuadsToFillScreen( |
| + RenderPass* target_render_pass, |
| + LayerImpl* root_layer, |
| + SkColor screen_background_color, |
| + const OcclusionTrackerImpl& occlusion_tracker) { |
| + if (!root_layer || !SkColorGetA(screen_background_color)) |
| + return; |
| + |
| + Region fill_region = occlusion_tracker.ComputeVisibleRegionInScreen(); |
| + if (fill_region.IsEmpty()) |
| + return; |
| + |
| + bool for_surface = false; |
| + QuadCuller quadCuller(target_render_pass->quad_list, |
| + target_render_pass->shared_quad_state_list, |
| + root_layer, |
| + occlusion_tracker, |
| + root_layer->ShowDebugBorders(), |
| + for_surface); |
| + |
| + // Manually create the quad state for the gutter quads, as the root layer |
| + // doesn't have any bounds and so can't generate this itself. |
| + // TODO(danakj): Make the gutter quads generated by the solid color layer |
| + // (make it smarter about generating quads to fill unoccluded areas). |
| + |
| + gfx::Rect root_target_rect = root_layer->render_surface()->content_rect(); |
| + float opacity = 1; |
|
enne (OOO)
2013/03/13 05:22:05
1.f
danakj
2013/03/13 15:49:11
Done.
|
| + SharedQuadState* shared_quad_state = |
| + quadCuller.useSharedQuadState(SharedQuadState::Create()); |
| + shared_quad_state->SetAll(root_layer->draw_transform(), |
| + root_target_rect.size(), |
| + root_target_rect, |
| + root_target_rect, |
| false, |
| opacity); |
| - AppendQuadsData appendQuadsData; |
| - |
| - gfx::Transform transformToLayerSpace(gfx::Transform::kSkipInitialization); |
| - bool didInvert = rootLayer->screen_space_transform().GetInverse(&transformToLayerSpace); |
| - DCHECK(didInvert); |
| - for (Region::Iterator fillRects(fillRegion); fillRects.has_rect(); fillRects.next()) { |
| - // The root layer transform is composed of translations and scales only, |
| - // no perspective, so mapping is sufficient (as opposed to projecting). |
| - gfx::Rect layerRect = MathUtil::mapClippedRect(transformToLayerSpace, fillRects.rect()); |
| - // Skip the quad culler and just append the quads directly to avoid |
| - // occlusion checks. |
| - scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); |
| - quad->SetNew(sharedQuadState, layerRect, screenBackgroundColor); |
| - quadCuller.append(quad.PassAs<DrawQuad>(), &appendQuadsData); |
| - } |
| -} |
| - |
| -bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) |
| -{ |
| - DCHECK(frame.renderPasses.empty()); |
| - |
| - if (!canDraw() || !rootLayer()) |
| - return false; |
| - |
| - trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList); |
| - |
| - TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList->size())); |
| - |
| - // Create the render passes in dependency order. |
| - for (int surfaceIndex = frame.renderSurfaceLayerList->size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { |
| - LayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceIndex]; |
| - renderSurfaceLayer->render_surface()->AppendRenderPasses(&frame); |
| - } |
| - |
| - bool recordMetricsForFrame = m_settings.showOverdrawInTracing && base::debug::TraceLog::GetInstance() && base::debug::TraceLog::GetInstance()->IsEnabled(); |
| - OcclusionTrackerImpl occlusionTracker(rootLayer()->render_surface()->content_rect(), recordMetricsForFrame); |
| - occlusionTracker.set_minimum_tracking_size(m_settings.minimumOcclusionTrackingSize); |
| - |
| - if (m_debugState.showOccludingRects) |
| - occlusionTracker.set_occluding_screen_space_rects_container(&frame.occludingScreenSpaceRects); |
| - if (m_debugState.showNonOccludingRects) |
| - occlusionTracker.set_non_occluding_screen_space_rects_container(&frame.nonOccludingScreenSpaceRects); |
| - |
| - // Add quads to the Render passes in FrontToBack order to allow for testing occlusion and performing culling during the tree walk. |
| - typedef LayerIterator<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerIteratorActions::FrontToBack> LayerIteratorType; |
| - |
| - // Typically when we are missing a texture and use a checkerboard quad, we still draw the frame. However when the layer being |
| - // checkerboarded is moving due to an impl-animation, we drop the frame to avoid flashing due to the texture suddenly appearing |
| - // in the future. |
| - bool drawFrame = true; |
| - |
| - LayerIteratorType end = LayerIteratorType::end(frame.renderSurfaceLayerList); |
| - for (LayerIteratorType it = LayerIteratorType::begin(frame.renderSurfaceLayerList); it != end; ++it) { |
| - RenderPass::Id targetRenderPassId = it.targetRenderSurfaceLayer()->render_surface()->RenderPassId(); |
| - RenderPass* targetRenderPass = frame.renderPassesById[targetRenderPassId]; |
| - |
| - occlusionTracker.EnterLayer(it); |
| - |
| - AppendQuadsData appendQuadsData(targetRenderPass->id); |
| - |
| - if (it.representsContributingRenderSurface()) { |
| - RenderPass::Id contributingRenderPassId = it->render_surface()->RenderPassId(); |
| - RenderPass* contributingRenderPass = frame.renderPassesById[contributingRenderPassId]; |
| - appendQuadsForRenderSurfaceLayer(targetRenderPass, *it, contributingRenderPass, occlusionTracker, appendQuadsData); |
| - } else if (it.representsItself() && !it->visible_content_rect().IsEmpty()) { |
| - bool hasOcclusionFromOutsideTargetSurface; |
| - bool implDrawTransformIsUnknown = false; |
| - if (occlusionTracker.Occluded(it->render_target(), it->visible_content_rect(), it->draw_transform(), implDrawTransformIsUnknown, it->is_clipped(), it->clip_rect(), &hasOcclusionFromOutsideTargetSurface)) |
| - appendQuadsData.hadOcclusionFromOutsideTargetSurface |= hasOcclusionFromOutsideTargetSurface; |
| - else { |
| - DCHECK_EQ(activeTree(), it->layer_tree_impl()); |
| - it->WillDraw(m_resourceProvider.get()); |
| - frame.willDrawLayers.push_back(*it); |
| - |
| - if (it->HasContributingDelegatedRenderPasses()) { |
| - RenderPass::Id contributingRenderPassId = it->FirstContributingRenderPassId(); |
| - while (frame.renderPassesById.find(contributingRenderPassId) != frame.renderPassesById.end()) { |
| - RenderPass* renderPass = frame.renderPassesById[contributingRenderPassId]; |
| - |
| - AppendQuadsData appendQuadsData(renderPass->id); |
| - appendQuadsForLayer(renderPass, *it, occlusionTracker, appendQuadsData); |
| - |
| - contributingRenderPassId = it->NextContributingRenderPassId(contributingRenderPassId); |
| - } |
| - } |
| - |
| - appendQuadsForLayer(targetRenderPass, *it, occlusionTracker, appendQuadsData); |
| - } |
| - |
| - ++m_cumulativeNumLayersDrawn; |
| - } |
| - |
| - if (appendQuadsData.hadOcclusionFromOutsideTargetSurface) |
| - targetRenderPass->has_occlusion_from_outside_target_surface = true; |
| + AppendQuadsData append_quads_data; |
| + |
| + gfx::Transform transform_to_layer_space(gfx::Transform::kSkipInitialization); |
| + bool did_invert = root_layer->screen_space_transform().GetInverse( |
| + &transform_to_layer_space); |
| + DCHECK(did_invert); |
| + for (Region::Iterator fillRects(fill_region); |
| + fillRects.has_rect(); |
| + fillRects.next()) { |
| + // The root layer transform is composed of translations and scales only, |
| + // no perspective, so mapping is sufficient (as opposed to projecting). |
| + gfx::Rect layer_rect = |
| + MathUtil::mapClippedRect(transform_to_layer_space, fillRects.rect()); |
| + // Skip the quad culler and just append the quads directly to avoid |
| + // occlusion checks. |
| + scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); |
| + quad->SetNew(shared_quad_state, layer_rect, screen_background_color); |
| + quadCuller.append(quad.PassAs<DrawQuad>(), &append_quads_data); |
| + } |
| +} |
| + |
| +bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { |
| + DCHECK(frame->render_passes.empty()); |
| + |
| + if (!CanDraw() || !active_tree_->root_layer()) |
| + return false; |
| - if (appendQuadsData.numMissingTiles) { |
| - m_cumulativeNumMissingTiles += appendQuadsData.numMissingTiles; |
| - bool layerHasAnimatingTransform = it->screen_space_transform_is_animating() || it->draw_transform_is_animating(); |
| - if (layerHasAnimatingTransform) |
| - drawFrame = false; |
| + TrackDamageForAllSurfaces(active_tree_->root_layer(), |
| + *frame->render_surface_layer_list); |
| + |
| + TRACE_EVENT1("cc", |
| + "LayerTreeHostImpl::calculateRenderPasses", |
|
enne (OOO)
2013/03/13 05:22:05
CalculateRenderPasses
danakj
2013/03/13 15:49:11
Done.
|
| + "render_surface_layer_list.size()", |
| + static_cast<long long unsigned>( |
| + frame->render_surface_layer_list->size())); |
| + |
| + // Create the render passes in dependency order. |
| + for (int surfaceIndex = frame->render_surface_layer_list->size() - 1; |
| + surfaceIndex >= 0 ; |
| + --surfaceIndex) { |
| + LayerImpl* render_surface_layer = |
| + (*frame->render_surface_layer_list)[surfaceIndex]; |
| + render_surface_layer->render_surface()->AppendRenderPasses(frame); |
| + } |
| + |
| + bool record_metrics_for_frame = |
| + settings_.showOverdrawInTracing && |
| + base::debug::TraceLog::GetInstance() && |
| + base::debug::TraceLog::GetInstance()->IsEnabled(); |
| + OcclusionTrackerImpl occlusion_tracker( |
| + active_tree_->root_layer()->render_surface()->content_rect(), |
| + record_metrics_for_frame); |
| + occlusion_tracker.set_minimum_tracking_size( |
| + settings_.minimumOcclusionTrackingSize); |
| + |
| + if (debug_state_.showOccludingRects) { |
| + occlusion_tracker.set_occluding_screen_space_rects_container( |
| + &frame->occluding_screen_space_rects); |
| + } |
| + if (debug_state_.showNonOccludingRects) { |
| + occlusion_tracker.set_non_occluding_screen_space_rects_container( |
| + &frame->non_occluding_screen_space_rects); |
| + } |
| + |
| + // Add quads to the Render passes in FrontToBack order to allow for testing |
| + // occlusion and performing culling during the tree walk. |
| + typedef LayerIterator<LayerImpl, |
| + std::vector<LayerImpl*>, |
| + RenderSurfaceImpl, |
| + LayerIteratorActions::FrontToBack> LayerIteratorType; |
| + |
| + // Typically when we are missing a texture and use a checkerboard quad, we |
| + // still draw the frame. However when the layer being checkerboarded is moving |
| + // due to an impl-animation, we drop the frame to avoid flashing due to the |
| + // texture suddenly appearing in the future. |
| + bool draw_frame = true; |
| + |
| + LayerIteratorType end = |
| + LayerIteratorType::end(frame->render_surface_layer_list); |
| + for (LayerIteratorType it = |
| + LayerIteratorType::begin(frame->render_surface_layer_list); |
| + it != end; |
| + ++it) { |
| + RenderPass::Id target_render_pass_id = |
| + it.targetRenderSurfaceLayer()->render_surface()->RenderPassId(); |
| + RenderPass* target_render_pass = |
| + frame->render_passes_by_id[target_render_pass_id]; |
| + |
| + occlusion_tracker.EnterLayer(it); |
| + |
| + AppendQuadsData append_quads_data(target_render_pass->id); |
| + |
| + if (it.representsContributingRenderSurface()) { |
| + RenderPass::Id contributing_render_pass_id = |
| + it->render_surface()->RenderPassId(); |
| + RenderPass* contributing_render_pass = |
| + frame->render_passes_by_id[contributing_render_pass_id]; |
| + AppendQuadsForRenderSurfaceLayer(target_render_pass, |
| + *it, |
| + contributing_render_pass, |
| + occlusion_tracker, |
| + &append_quads_data); |
| + } else if (it.representsItself() && !it->visible_content_rect().IsEmpty()) { |
| + bool has_occlusion_from_outside_target_surface; |
| + bool impl_draw_transform_is_unknown = false; |
| + if (occlusion_tracker.Occluded( |
| + it->render_target(), |
| + it->visible_content_rect(), |
| + it->draw_transform(), |
| + impl_draw_transform_is_unknown, |
| + it->is_clipped(), |
| + it->clip_rect(), |
| + &has_occlusion_from_outside_target_surface)) { |
| + append_quads_data.hadOcclusionFromOutsideTargetSurface |= |
| + has_occlusion_from_outside_target_surface; |
| + } else { |
| + DCHECK_EQ(active_tree_, it->layer_tree_impl()); |
| + it->WillDraw(resource_provider_.get()); |
| + frame->will_draw_layers.push_back(*it); |
| + |
| + if (it->HasContributingDelegatedRenderPasses()) { |
| + RenderPass::Id contributing_render_pass_id = |
| + it->FirstContributingRenderPassId(); |
| + while (frame->render_passes_by_id.find(contributing_render_pass_id) != |
| + frame->render_passes_by_id.end()) { |
| + RenderPass* render_pass = |
| + frame->render_passes_by_id[contributing_render_pass_id]; |
| + |
| + AppendQuadsData append_quads_data(render_pass->id); |
| + AppendQuadsForLayer(render_pass, |
| + *it, |
| + occlusion_tracker, |
| + &append_quads_data); |
| + |
| + contributing_render_pass_id = |
| + it->NextContributingRenderPassId(contributing_render_pass_id); |
| + } |
| } |
| - if (appendQuadsData.hadIncompleteTile) |
| - frame.containsIncompleteTile = true; |
| + AppendQuadsForLayer(target_render_pass, |
| + *it, |
| + occlusion_tracker, |
| + &append_quads_data); |
| + } |
| - occlusionTracker.LeaveLayer(it); |
| + ++cumulative_num_layers_drawn_; |
| } |
| -#ifndef NDEBUG |
| - for (size_t i = 0; i < frame.renderPasses.size(); ++i) { |
| - for (size_t j = 0; j < frame.renderPasses[i]->quad_list.size(); ++j) |
| - DCHECK(frame.renderPasses[i]->quad_list[j]->shared_quad_state); |
| - DCHECK(frame.renderPassesById.find(frame.renderPasses[i]->id) |
| - != frame.renderPassesById.end()); |
| - } |
| -#endif |
| - DCHECK(frame.renderPasses.back()->output_rect.origin().IsOrigin()); |
| + if (append_quads_data.hadOcclusionFromOutsideTargetSurface) |
| + target_render_pass->has_occlusion_from_outside_target_surface = true; |
| - if (!activeTree()->has_transparent_background()) { |
| - frame.renderPasses.back()->has_transparent_background = false; |
| - appendQuadsToFillScreen(frame.renderPasses.back(), rootLayer(), activeTree()->background_color(), occlusionTracker); |
| + if (append_quads_data.numMissingTiles) { |
| + cumulative_num_missing_tiles_ += append_quads_data.numMissingTiles; |
| + bool layer_has_animating_transform = |
| + it->screen_space_transform_is_animating() || |
| + it->draw_transform_is_animating(); |
| + if (layer_has_animating_transform) |
| + draw_frame = false; |
| } |
| - if (drawFrame) |
| - occlusionTracker.overdraw_metrics()->RecordMetrics(this); |
| - |
| - removeRenderPasses(CullRenderPassesWithNoQuads(), frame); |
| - m_renderer->DecideRenderPassAllocationsForFrame(frame.renderPasses); |
| - removeRenderPasses(CullRenderPassesWithCachedTextures(*m_renderer), frame); |
| - |
| - return drawFrame; |
| -} |
| - |
| -void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled) |
| -{ |
| - // Lazily create the timeSource adapter so that we can vary the interval for testing. |
| - if (!m_timeSourceClientAdapter) |
| - m_timeSourceClientAdapter = LayerTreeHostImplTimeSourceAdapter::Create(this, DelayBasedTimeSource::create(lowFrequencyAnimationInterval(), m_proxy->CurrentThread())); |
| - |
| - m_timeSourceClientAdapter->setActive(enabled); |
| -} |
| - |
| -static inline RenderPass* findRenderPassById(RenderPass::Id renderPassId, const LayerTreeHostImpl::FrameData& frame) |
| -{ |
| - RenderPassIdHashMap::const_iterator it = frame.renderPassesById.find(renderPassId); |
| - return it != frame.renderPassesById.end() ? it->second : NULL; |
| -} |
| - |
| -static void removeRenderPassesRecursive(RenderPass::Id removeRenderPassId, LayerTreeHostImpl::FrameData& frame) |
| -{ |
| - RenderPass* removeRenderPass = findRenderPassById(removeRenderPassId, frame); |
| - // The pass was already removed by another quad - probably the original, and we are the replica. |
| - if (!removeRenderPass) |
| - return; |
| - RenderPassList& renderPasses = frame.renderPasses; |
| - RenderPassList::iterator toRemove = std::find(renderPasses.begin(), renderPasses.end(), removeRenderPass); |
| - |
| - DCHECK(toRemove != renderPasses.end()); |
| + if (append_quads_data.hadIncompleteTile) |
| + frame->contains_incomplete_tile = true; |
| - scoped_ptr<RenderPass> removedPass = renderPasses.take(toRemove); |
| - frame.renderPasses.erase(toRemove); |
| - frame.renderPassesById.erase(removeRenderPassId); |
| + occlusion_tracker.LeaveLayer(it); |
| + } |
| - // Now follow up for all RenderPass quads and remove their RenderPasses recursively. |
| - const QuadList& quadList = removedPass->quad_list; |
| - QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); |
| - for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) { |
| - DrawQuad* currentQuad = (*quadListIterator); |
| - if (currentQuad->material != DrawQuad::RENDER_PASS) |
| - continue; |
| - |
| - RenderPass::Id nextRemoveRenderPassId = RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id; |
| - removeRenderPassesRecursive(nextRemoveRenderPassId, frame); |
| - } |
| -} |
| - |
| -bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData&) const |
| -{ |
| - if (!quad.contents_changed_since_last_frame.IsEmpty()) { |
| - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage"); |
| - return false; |
| - } else if (!m_renderer.HaveCachedResourcesForRenderPassId(quad.render_pass_id)) { |
| - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture"); |
| - return false; |
| - } |
| - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!"); |
| - return true; |
| +#ifndef NDEBUG |
| + for (size_t i = 0; i < frame->render_passes.size(); ++i) { |
| + for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j) |
| + DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state); |
| + DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id) |
| + != frame->render_passes_by_id.end()); |
| + } |
| +#endif |
| + DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin()); |
| + |
| + if (!active_tree_->has_transparent_background()) { |
| + frame->render_passes.back()->has_transparent_background = false; |
| + AppendQuadsToFillScreen(frame->render_passes.back(), |
| + active_tree_->root_layer(), |
| + active_tree_->background_color(), |
| + occlusion_tracker); |
| + } |
| + |
| + if (draw_frame) |
| + occlusion_tracker.overdraw_metrics()->RecordMetrics(this); |
| + |
| + RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); |
| + renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); |
| + RemoveRenderPasses(CullRenderPassesWithCachedTextures(*renderer_), frame); |
| + |
| + return draw_frame; |
| +} |
| + |
| +void LayerTreeHostImpl::SetBackgroundTickingEnabled(bool enabled) { |
| + // Lazily create the time_source adapter so that we can vary the interval for |
| + // testing. |
| + if (!time_source_client_adapter_) |
|
enne (OOO)
2013/03/13 05:22:05
{}
danakj
2013/03/13 15:49:11
Done.
|
| + time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create( |
| + this, |
| + DelayBasedTimeSource::create(LowFrequencyAnimationInterval(), |
| + proxy_->CurrentThread())); |
| + |
| + time_source_client_adapter_->SetActive(enabled); |
| +} |
| + |
| +static inline RenderPass* FindRenderPassById( |
| + RenderPass::Id render_pass_id, |
| + const LayerTreeHostImpl::FrameData& frame) { |
| + RenderPassIdHashMap::const_iterator it = |
| + frame.render_passes_by_id.find(render_pass_id); |
| + return it != frame.render_passes_by_id.end() ? it->second : NULL; |
| +} |
| + |
| +static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, |
| + LayerTreeHostImpl::FrameData* frame) { |
| + RenderPass* remove_render_pass = |
| + FindRenderPassById(remove_render_pass_id, *frame); |
| + // The pass was already removed by another quad - probably the original, and |
| + // we are the replica. |
| + if (!remove_render_pass) |
| + return; |
| + RenderPassList& render_passes = frame->render_passes; |
| + RenderPassList::iterator to_remove = std::find(render_passes.begin(), |
| + render_passes.end(), |
| + remove_render_pass); |
| + |
| + DCHECK(to_remove != render_passes.end()); |
| + |
| + scoped_ptr<RenderPass> removed_pass = render_passes.take(to_remove); |
| + frame->render_passes.erase(to_remove); |
| + frame->render_passes_by_id.erase(remove_render_pass_id); |
| + |
| + // Now follow up for all RenderPass quads and remove their RenderPasses |
| + // recursively. |
| + const QuadList& quad_list = removed_pass->quad_list; |
| + QuadList::constBackToFrontIterator quad_list_iterator = |
| + quad_list.backToFrontBegin(); |
| + for (; quad_list_iterator != quad_list.backToFrontEnd(); |
| + ++quad_list_iterator) { |
| + DrawQuad* current_quad = (*quad_list_iterator); |
| + if (current_quad->material != DrawQuad::RENDER_PASS) |
| + continue; |
| + |
| + RenderPass::Id next_remove_render_pass_id = |
| + RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id; |
| + RemoveRenderPassesRecursive(next_remove_render_pass_id, frame); |
| + } |
| +} |
| + |
| +bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures:: |
| + ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, |
| + const FrameData& frame) const { |
| + bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty(); |
| + bool quad_has_cached_resource = |
| + renderer_.HaveCachedResourcesForRenderPassId(quad.render_pass_id); |
| + if (quad_has_damage) { |
| + TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage"); |
| + return false; |
| + } else if (!quad_has_cached_resource) { |
| + TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture"); |
| + return false; |
| + } |
| + TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!"); |
| + return true; |
| } |
| -bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData& frame) const |
| -{ |
| - const RenderPass* renderPass = findRenderPassById(quad.render_pass_id, frame); |
| - if (!renderPass) |
| - return false; |
| +bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( |
| + const RenderPassDrawQuad& quad, const FrameData& frame) const { |
| + const RenderPass* render_pass = |
| + FindRenderPassById(quad.render_pass_id, frame); |
| + if (!render_pass) |
| + return false; |
| - // If any quad or RenderPass draws into this RenderPass, then keep it. |
| - const QuadList& quadList = renderPass->quad_list; |
| - for (QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) { |
| - DrawQuad* currentQuad = *quadListIterator; |
| + // If any quad or RenderPass draws into this RenderPass, then keep it. |
| + const QuadList& quad_list = render_pass->quad_list; |
| + for (QuadList::constBackToFrontIterator quad_list_iterator = |
| + quad_list.backToFrontBegin(); |
| + quad_list_iterator != quad_list.backToFrontEnd(); |
| + ++quad_list_iterator) { |
| + DrawQuad* current_quad = *quad_list_iterator; |
| - if (currentQuad->material != DrawQuad::RENDER_PASS) |
| - return false; |
| + if (current_quad->material != DrawQuad::RENDER_PASS) |
| + return false; |
| - const RenderPass* contributingPass = findRenderPassById(RenderPassDrawQuad::MaterialCast(currentQuad)->render_pass_id, frame); |
| - if (contributingPass) |
| - return false; |
| - } |
| - return true; |
| + const RenderPass* contributing_pass = FindRenderPassById( |
| + RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id, frame); |
| + if (contributing_pass) |
| + return false; |
| + } |
| + return true; |
| } |
| // Defined for linking tests. |
| -template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithCachedTextures>(CullRenderPassesWithCachedTextures, FrameData&); |
| -template CC_EXPORT void LayerTreeHostImpl::removeRenderPasses<LayerTreeHostImpl::CullRenderPassesWithNoQuads>(CullRenderPassesWithNoQuads, FrameData&); |
| +template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< |
| + LayerTreeHostImpl::CullRenderPassesWithCachedTextures>( |
| + CullRenderPassesWithCachedTextures culler, FrameData* frame); |
| +template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< |
| + LayerTreeHostImpl::CullRenderPassesWithNoQuads>( |
| + CullRenderPassesWithNoQuads culler, FrameData*); |
| // static |
| -template<typename RenderPassCuller> |
| -void LayerTreeHostImpl::removeRenderPasses(RenderPassCuller culler, FrameData& frame) |
| -{ |
| - for (size_t it = culler.renderPassListBegin(frame.renderPasses); it != culler.renderPassListEnd(frame.renderPasses); it = culler.renderPassListNext(it)) { |
| - const RenderPass* currentPass = frame.renderPasses[it]; |
| - const QuadList& quadList = currentPass->quad_list; |
| - QuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); |
| - |
| - for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) { |
| - DrawQuad* currentQuad = *quadListIterator; |
| - |
| - if (currentQuad->material != DrawQuad::RENDER_PASS) |
| - continue; |
| - |
| - RenderPassDrawQuad* renderPassQuad = static_cast<RenderPassDrawQuad*>(currentQuad); |
| - if (!culler.shouldRemoveRenderPass(*renderPassQuad, frame)) |
| - continue; |
| - |
| - // We are changing the vector in the middle of iteration. Because we |
| - // delete render passes that draw into the current pass, we are |
| - // guaranteed that any data from the iterator to the end will not |
| - // change. So, capture the iterator position from the end of the |
| - // list, and restore it after the change. |
| - int positionFromEnd = frame.renderPasses.size() - it; |
| - removeRenderPassesRecursive(renderPassQuad->render_pass_id, frame); |
| - it = frame.renderPasses.size() - positionFromEnd; |
| - DCHECK(frame.renderPasses.size() >= static_cast<size_t>(positionFromEnd)); |
| - } |
| - } |
| -} |
| - |
| -bool LayerTreeHostImpl::prepareToDraw(FrameData& frame) |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw"); |
| - |
| - activeTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW); |
| - |
| - frame.renderSurfaceLayerList = &activeTree()->RenderSurfaceLayerList(); |
| - frame.renderPasses.clear(); |
| - frame.renderPassesById.clear(); |
| - frame.willDrawLayers.clear(); |
| - |
| - if (!calculateRenderPasses(frame)) |
| - return false; |
| - |
| - // If we return true, then we expect drawLayers() to be called before this function is called again. |
| - return true; |
| -} |
| - |
| -void LayerTreeHostImpl::EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) |
| -{ |
| - bool evictedResources = m_client->reduceContentsTextureMemoryOnImplThread( |
| - m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible, |
| - ManagedMemoryPolicy::priorityCutoffToValue( |
| - m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible)); |
| - if (evictedResources) { |
| - activeTree()->SetContentsTexturesPurged(); |
| - if (pendingTree()) |
| - pendingTree()->SetContentsTexturesPurged(); |
| - m_client->setNeedsCommitOnImplThread(); |
| - m_client->onCanDrawStateChanged(canDraw()); |
| - m_client->renewTreePriority(); |
| - } |
| - m_client->sendManagedMemoryStats(); |
| - |
| - if (m_tileManager) { |
| - GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState()); |
| - new_state.memory_limit_in_bytes = m_visible ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible; |
| - new_state.memory_limit_policy = ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy( |
| - m_visible ? policy.priorityCutoffWhenVisible : policy.priorityCutoffWhenNotVisible); |
| - m_tileManager->SetGlobalState(new_state); |
| - } |
| -} |
| - |
| -bool LayerTreeHostImpl::HasImplThread() const |
| -{ |
| - return m_proxy->HasImplThread(); |
| -} |
| - |
| -void LayerTreeHostImpl::ScheduleManageTiles() |
| -{ |
| - if (m_client) |
| - m_client->setNeedsManageTilesOnImplThread(); |
| -} |
| - |
| -void LayerTreeHostImpl::DidUploadVisibleHighResolutionTile() |
| -{ |
| - if (m_client) |
| - m_client->didUploadVisibleHighResolutionTileOnImplThread(); |
| -} |
| - |
| -bool LayerTreeHostImpl::ShouldClearRootRenderPass() const |
| -{ |
| - return m_settings.shouldClearRootRenderPass; |
| -} |
| - |
| -void LayerTreeHostImpl::SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) |
| -{ |
| - if (m_managedMemoryPolicy == policy) |
| - return; |
| - |
| - m_managedMemoryPolicy = policy; |
| - if (!m_proxy->HasImplThread()) { |
| - // FIXME: In single-thread mode, this can be called on the main thread |
| - // by GLRenderer::onMemoryAllocationChanged. |
| - DebugScopedSetImplThread implThread(m_proxy); |
| - EnforceManagedMemoryPolicy(m_managedMemoryPolicy); |
| - } else { |
| - DCHECK(m_proxy->IsImplThread()); |
| - EnforceManagedMemoryPolicy(m_managedMemoryPolicy); |
| +template <typename RenderPassCuller> |
| +void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler, |
| + FrameData* frame) { |
| + for (size_t it = culler.RenderPassListBegin(frame->render_passes); |
| + it != culler.RenderPassListEnd(frame->render_passes); |
| + it = culler.RenderPassListNext(it)) { |
| + const RenderPass* current_pass = frame->render_passes[it]; |
| + const QuadList& quad_list = current_pass->quad_list; |
| + QuadList::constBackToFrontIterator quad_list_iterator = |
| + quad_list.backToFrontBegin(); |
| + |
| + for (; quad_list_iterator != quad_list.backToFrontEnd(); |
| + ++quad_list_iterator) { |
| + DrawQuad* current_quad = *quad_list_iterator; |
| + |
| + if (current_quad->material != DrawQuad::RENDER_PASS) |
| + continue; |
| + |
| + const RenderPassDrawQuad* render_pass_quad = |
| + RenderPassDrawQuad::MaterialCast(current_quad); |
| + if (!culler.ShouldRemoveRenderPass(*render_pass_quad, *frame)) |
| + continue; |
| + |
| + // We are changing the vector in the middle of iteration. Because we |
| + // delete render passes that draw into the current pass, we are |
| + // guaranteed that any data from the iterator to the end will not |
| + // change. So, capture the iterator position from the end of the |
| + // list, and restore it after the change. |
| + size_t position_from_end = frame->render_passes.size() - it; |
| + RemoveRenderPassesRecursive(render_pass_quad->render_pass_id, frame); |
| + it = frame->render_passes.size() - position_from_end; |
| + DCHECK_GE(frame->render_passes.size(), position_from_end); |
| } |
| - // We always need to commit after changing the memory policy because the new |
| - // limit can result in more or less content having texture allocated for it. |
| - m_client->setNeedsCommitOnImplThread(); |
| + } |
| } |
| -void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval) |
| -{ |
| - m_client->onVSyncParametersChanged(timebase, interval); |
| -} |
| +bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw"); |
|
enne (OOO)
2013/03/13 05:22:05
PrepareToDraw
danakj
2013/03/13 15:49:11
Done.
|
| -void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack) |
| -{ |
| - if (!m_renderer) |
| - return; |
| + active_tree_->UpdateDrawProperties( |
| + LayerTreeImpl::UPDATE_ACTIVE_TREE_FOR_DRAW); |
| - // TODO(piman): We may need to do some validation on this ack before processing it. |
| - m_renderer->ReceiveCompositorFrameAck(ack); |
| -} |
| + frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList(); |
| + frame->render_passes.clear(); |
| + frame->render_passes_by_id.clear(); |
| + frame->will_draw_layers.clear(); |
| -void LayerTreeHostImpl::OnCanDrawStateChangedForTree(LayerTreeImpl*) |
| -{ |
| - m_client->onCanDrawStateChanged(canDraw()); |
| -} |
| - |
| -CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const |
| -{ |
| - CompositorFrameMetadata metadata; |
| - metadata.device_scale_factor = m_deviceScaleFactor; |
| - metadata.page_scale_factor = activeTree()->total_page_scale_factor(); |
| - metadata.viewport_size = activeTree()->ScrollableViewportSize(); |
| - metadata.root_layer_size = activeTree()->ScrollableSize(); |
| - metadata.min_page_scale_factor = activeTree()->min_page_scale_factor(); |
| - metadata.max_page_scale_factor = activeTree()->max_page_scale_factor(); |
| - if (m_topControlsManager) { |
| - metadata.location_bar_offset = gfx::Vector2dF(0.f, m_topControlsManager->controls_top_offset()); |
| - metadata.location_bar_content_translation = gfx::Vector2dF(0.f, m_topControlsManager->content_top_offset()); |
| - } |
| + if (!CalculateRenderPasses(frame)) |
| + return false; |
| - if (!rootScrollLayer()) |
| - return metadata; |
| + // If we return true, then we expect DrawLayers() to be called before this |
| + // function is called again. |
| + return true; |
| +} |
| + |
| +void LayerTreeHostImpl::EnforceManagedMemoryPolicy( |
| + const ManagedMemoryPolicy& policy) { |
| + bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread( |
| + visible_ ? policy.bytesLimitWhenVisible : policy.bytesLimitWhenNotVisible, |
| + ManagedMemoryPolicy::priorityCutoffToValue( |
| + visible_ ? |
| + policy.priorityCutoffWhenVisible : |
| + policy.priorityCutoffWhenNotVisible)); |
| + if (evicted_resources) { |
| + active_tree_->SetContentsTexturesPurged(); |
| + if (pending_tree_) |
| + pending_tree_->SetContentsTexturesPurged(); |
| + client_->SetNeedsCommitOnImplThread(); |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| + client_->RenewTreePriority(); |
| + } |
| + client_->SendManagedMemoryStats(); |
| + |
| + if (tile_manager_) { |
| + GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState()); |
| + new_state.memory_limit_in_bytes = visible_ ? |
| + policy.bytesLimitWhenVisible : |
| + policy.bytesLimitWhenNotVisible; |
| + new_state.memory_limit_policy = |
| + ManagedMemoryPolicy::priorityCutoffToTileMemoryLimitPolicy( |
| + visible_ ? |
| + policy.priorityCutoffWhenVisible : |
| + policy.priorityCutoffWhenNotVisible); |
| + tile_manager_->SetGlobalState(new_state); |
| + } |
| +} |
| + |
| +bool LayerTreeHostImpl::HasImplThread() const { |
| + return proxy_->HasImplThread(); |
| +} |
| + |
| +void LayerTreeHostImpl::ScheduleManageTiles() { |
| + if (client_) |
| + client_->SetNeedsManageTilesOnImplThread(); |
| +} |
| + |
| +void LayerTreeHostImpl::DidUploadVisibleHighResolutionTile() { |
| + if (client_) |
| + client_->DidUploadVisibleHighResolutionTileOnImplThread(); |
| +} |
| + |
| +bool LayerTreeHostImpl::ShouldClearRootRenderPass() const { |
| + return settings_.shouldClearRootRenderPass; |
| +} |
| + |
| +void LayerTreeHostImpl::SetManagedMemoryPolicy( |
| + const ManagedMemoryPolicy& policy) { |
| + if (managed_memory_policy_ == policy) |
| + return; |
| + |
| + managed_memory_policy_ = policy; |
| + if (!proxy_->HasImplThread()) { |
| + // TODO(ccameron): In single-thread mode, this can be called on the main |
| + // thread by GLRenderer::OnMemoryAllocationChanged. |
| + DebugScopedSetImplThread impl_thread(proxy_); |
| + EnforceManagedMemoryPolicy(managed_memory_policy_); |
| + } else { |
| + DCHECK(proxy_->IsImplThread()); |
| + EnforceManagedMemoryPolicy(managed_memory_policy_); |
| + } |
| + // We always need to commit after changing the memory policy because the new |
| + // limit can result in more or less content having texture allocated for it. |
| + client_->SetNeedsCommitOnImplThread(); |
| +} |
| + |
| +void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase, |
| + base::TimeDelta interval) { |
| + client_->OnVSyncParametersChanged(timebase, interval); |
| +} |
| + |
| +void LayerTreeHostImpl::OnSendFrameToParentCompositorAck( |
| + const CompositorFrameAck& ack) { |
| + if (!renderer_) |
| + return; |
| + |
| + // TODO(piman): We may need to do some validation on this ack before |
| + // processing it. |
| + renderer_->ReceiveCompositorFrameAck(ack); |
| +} |
| + |
| +void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| +} |
| + |
| +CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { |
| + CompositorFrameMetadata metadata; |
| + metadata.device_scale_factor = device_scale_factor_; |
| + metadata.page_scale_factor = active_tree_->total_page_scale_factor(); |
| + metadata.viewport_size = active_tree_->ScrollableViewportSize(); |
| + metadata.root_layer_size = active_tree_->ScrollableSize(); |
| + metadata.min_page_scale_factor = active_tree_->min_page_scale_factor(); |
| + metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); |
| + if (top_controls_manager_) { |
| + metadata.location_bar_offset = |
| + gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset()); |
| + metadata.location_bar_content_translation = |
| + gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset()); |
| + } |
| + |
| + if (!RootScrollLayer()) |
| + return metadata; |
| - metadata.root_scroll_offset = rootScrollLayer()->scroll_offset() + rootScrollLayer()->scroll_delta(); |
| + metadata.root_scroll_offset = RootScrollLayer()->scroll_offset() + |
| + RootScrollLayer()->scroll_delta(); |
| - return metadata; |
| + return metadata; |
| } |
| -void LayerTreeHostImpl::drawLayers(FrameData& frame) |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::drawLayers"); |
| - DCHECK(canDraw()); |
| - DCHECK(!frame.renderPasses.empty()); |
| +void LayerTreeHostImpl::DrawLayers(FrameData* frame) { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::drawLayers"); |
|
enne (OOO)
2013/03/13 05:22:05
DrawLayers
danakj
2013/03/13 15:49:11
Done.
|
| + DCHECK(CanDraw()); |
| + DCHECK(!frame->render_passes.empty()); |
| - // FIXME: use the frame begin time from the overall compositor scheduler. |
| - // This value is currently inaccessible because it is up in Chromium's |
| - // RenderWidget. |
| - m_fpsCounter->saveTimeStamp(base::TimeTicks::Now()); |
| + // FIXME: use the frame begin time from the overall compositor scheduler. |
| + // This value is currently inaccessible because it is up in Chromium's |
| + // RenderWidget. |
| + fps_counter_->saveTimeStamp(base::TimeTicks::Now()); |
| - if (m_tileManager) { |
| - m_memoryHistory->SaveEntry( |
| - m_tileManager->memory_stats_from_last_assign()); |
| - } |
| + if (tile_manager_) { |
| + memory_history_->SaveEntry( |
| + tile_manager_->memory_stats_from_last_assign()); |
| + } |
| - if (m_debugState.showHudRects()) |
| - m_debugRectHistory->saveDebugRectsForCurrentFrame(rootLayer(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, frame.nonOccludingScreenSpaceRects, m_debugState); |
| + if (debug_state_.showHudRects()) { |
| + debug_rect_history_->saveDebugRectsForCurrentFrame( |
| + active_tree_->root_layer(), |
| + *frame->render_surface_layer_list, |
| + frame->occluding_screen_space_rects, |
| + frame->non_occluding_screen_space_rects, |
| + debug_state_); |
| + } |
| - if (m_debugState.traceAllRenderedFrames) { |
| - TRACE_EVENT_INSTANT1("cc.debug", "Frame", |
| - "frame", ValueToString(frameStateAsValue())); |
| - } |
| + if (debug_state_.traceAllRenderedFrames) { |
| + TRACE_EVENT_INSTANT1("cc.debug", "Frame", |
| + "frame", ValueToString(FrameStateAsValue())); |
| + } |
| - // Because the contents of the HUD depend on everything else in the frame, the contents |
| - // of its texture are updated as the last thing before the frame is drawn. |
| - if (m_activeTree->hud_layer()) |
| - m_activeTree->hud_layer()->updateHudTexture(m_resourceProvider.get()); |
| + // Because the contents of the HUD depend on everything else in the frame, the |
| + // contents of its texture are updated as the last thing before the frame is |
| + // drawn. |
| + if (active_tree_->hud_layer()) |
| + active_tree_->hud_layer()->updateHudTexture(resource_provider_.get()); |
| - m_renderer->DrawFrame(frame.renderPasses); |
| - // The render passes should be consumed by the renderer. |
| - DCHECK(frame.renderPasses.empty()); |
| - frame.renderPassesById.clear(); |
| + renderer_->DrawFrame(frame->render_passes); |
| + // The render passes should be consumed by the renderer. |
| + DCHECK(frame->render_passes.empty()); |
| + frame->render_passes_by_id.clear(); |
| - // The next frame should start by assuming nothing has changed, and changes are noted as they occur. |
| - for (unsigned int i = 0; i < frame.renderSurfaceLayerList->size(); i++) |
| - (*frame.renderSurfaceLayerList)[i]->render_surface()->damage_tracker()->DidDrawDamagedArea(); |
| - rootLayer()->ResetAllChangeTrackingForSubtree(); |
| - updateAnimationState(); |
| + // The next frame should start by assuming nothing has changed, and changes |
| + // are noted as they occur. |
| + for (unsigned int i = 0; i < frame->render_surface_layer_list->size(); i++) { |
| + (*frame->render_surface_layer_list)[i]->render_surface()->damage_tracker()-> |
| + DidDrawDamagedArea(); |
| + } |
| + active_tree_->root_layer()->ResetAllChangeTrackingForSubtree(); |
| + UpdateAnimationState(); |
| } |
| -void LayerTreeHostImpl::didDrawAllLayers(const FrameData& frame) |
| -{ |
| - for (size_t i = 0; i < frame.willDrawLayers.size(); ++i) |
| - frame.willDrawLayers[i]->DidDraw(m_resourceProvider.get()); |
| +void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) { |
| + for (size_t i = 0; i < frame.will_draw_layers.size(); ++i) |
| + frame.will_draw_layers[i]->DidDraw(resource_provider_.get()); |
| - // Once all layers have been drawn, pending texture uploads should no |
| - // longer block future uploads. |
| - m_resourceProvider->MarkPendingUploadsAsNonBlocking(); |
| + // Once all layers have been drawn, pending texture uploads should no |
| + // longer block future uploads. |
| + resource_provider_->MarkPendingUploadsAsNonBlocking(); |
| } |
| -void LayerTreeHostImpl::finishAllRendering() |
| -{ |
| - if (m_renderer) |
| - m_renderer->Finish(); |
| +void LayerTreeHostImpl::FinishAllRendering() { |
| + if (renderer_) |
| + renderer_->Finish(); |
| } |
| -bool LayerTreeHostImpl::isContextLost() |
| -{ |
| - DCHECK(m_proxy->IsImplThread()); |
| - return m_renderer && m_renderer->IsContextLost(); |
| +bool LayerTreeHostImpl::IsContextLost() { |
| + DCHECK(proxy_->IsImplThread()); |
| + return renderer_ && renderer_->IsContextLost(); |
| } |
| -const RendererCapabilities& LayerTreeHostImpl::rendererCapabilities() const |
| -{ |
| - return m_renderer->Capabilities(); |
| +const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const { |
| + return renderer_->Capabilities(); |
| } |
| -bool LayerTreeHostImpl::swapBuffers() |
| -{ |
| - if (m_tileManager) |
| - m_tileManager->DidCompleteFrame(); |
| - return m_renderer->SwapBuffers(); |
| +bool LayerTreeHostImpl::SwapBuffers() { |
| + if (tile_manager_) |
| + tile_manager_->DidCompleteFrame(); |
| + return renderer_->SwapBuffers(); |
| } |
| -gfx::Size LayerTreeHostImpl::DeviceViewportSize() const |
| -{ |
| - return m_deviceViewportSize; |
| +gfx::Size LayerTreeHostImpl::DeviceViewportSize() const { |
| + return device_viewport_size(); |
| } |
| -const LayerTreeSettings& LayerTreeHostImpl::Settings() const |
| -{ |
| - return m_settings; |
| +const LayerTreeSettings& LayerTreeHostImpl::Settings() const { |
| + return settings(); |
| } |
| -void LayerTreeHostImpl::DidLoseOutputSurface() |
| -{ |
| - m_client->didLoseOutputSurfaceOnImplThread(); |
| +void LayerTreeHostImpl::DidLoseOutputSurface() { |
| + client_->DidLoseOutputSurfaceOnImplThread(); |
| } |
| -void LayerTreeHostImpl::OnSwapBuffersComplete() |
| -{ |
| - m_client->onSwapBuffersCompleteOnImplThread(); |
| +void LayerTreeHostImpl::OnSwapBuffersComplete() { |
| + client_->OnSwapBuffersCompleteOnImplThread(); |
| } |
| -void LayerTreeHostImpl::readback(void* pixels, |
| - gfx::Rect rect_in_device_viewport) |
| -{ |
| - DCHECK(m_renderer); |
| - m_renderer->GetFramebufferPixels(pixels, rect_in_device_viewport); |
| +void LayerTreeHostImpl::Readback(void* pixels, |
| + gfx::Rect rect_in_device_viewport) { |
| + DCHECK(renderer_); |
| + renderer_->GetFramebufferPixels(pixels, rect_in_device_viewport); |
| } |
| bool LayerTreeHostImpl::haveRootScrollLayer() const { |
| - return rootScrollLayer(); |
| + return RootScrollLayer(); |
| } |
| float LayerTreeHostImpl::rootScrollLayerTotalScrollY() const { |
| - if (LayerImpl* layer = rootScrollLayer()) |
| + if (LayerImpl* layer = RootScrollLayer()) |
| return layer->scroll_offset().y() + layer->scroll_delta().y(); |
| return 0.0f; |
| } |
| -LayerImpl* LayerTreeHostImpl::rootLayer() const |
| -{ |
| - return m_activeTree->RootLayer(); |
| +LayerImpl* LayerTreeHostImpl::RootLayer() const { |
| + return active_tree_->root_layer(); |
| } |
| -LayerImpl* LayerTreeHostImpl::rootScrollLayer() const |
| -{ |
| - return m_activeTree->RootScrollLayer(); |
| +LayerImpl* LayerTreeHostImpl::RootScrollLayer() const { |
| + return active_tree_->RootScrollLayer(); |
| } |
| -LayerImpl* LayerTreeHostImpl::currentlyScrollingLayer() const |
| -{ |
| - return m_activeTree->CurrentlyScrollingLayer(); |
| +LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { |
| + return active_tree_->CurrentlyScrollingLayer(); |
| } |
| // Content layers can be either directly scrollable or contained in an outer |
| // scrolling layer which applies the scroll transform. Given a content layer, |
| // this function returns the associated scroll layer if any. |
| -static LayerImpl* findScrollLayerForContentLayer(LayerImpl* layerImpl) |
| -{ |
| - if (!layerImpl) |
| - return 0; |
| +static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) { |
| + if (!layer_impl) |
| + return 0; |
| - if (layerImpl->scrollable()) |
| - return layerImpl; |
| + if (layer_impl->scrollable()) |
| + return layer_impl; |
| - if (layerImpl->DrawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable()) |
| - return layerImpl->parent(); |
| + if (layer_impl->DrawsContent() && |
| + layer_impl->parent() && |
| + layer_impl->parent()->scrollable()) |
| + return layer_impl->parent(); |
| - return 0; |
| + return 0; |
| } |
| -void LayerTreeHostImpl::createPendingTree() |
| -{ |
| - CHECK(!m_pendingTree); |
| - if (m_recycleTree) |
| - m_recycleTree.swap(m_pendingTree); |
| - else |
| - m_pendingTree = LayerTreeImpl::create(this); |
| - m_client->onCanDrawStateChanged(canDraw()); |
| - m_client->onHasPendingTreeStateChanged(pendingTree()); |
| - TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", m_pendingTree.get()); |
| - TRACE_EVENT_ASYNC_STEP0("cc", |
| - "PendingTree", m_pendingTree.get(), "waiting"); |
| -} |
| - |
| -void LayerTreeHostImpl::checkForCompletedTileUploads() |
| -{ |
| - DCHECK(!m_client->isInsideDraw()) << "Checking for completed uploads within a draw may trigger spurious redraws."; |
| - if (m_tileManager) |
| - m_tileManager->CheckForCompletedTileUploads(); |
| -} |
| - |
| -bool LayerTreeHostImpl::activatePendingTreeIfNeeded() |
| -{ |
| - if (!pendingTree()) |
| - return false; |
| - |
| - CHECK(m_tileManager); |
| - |
| - pendingTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE); |
| - |
| - TRACE_EVENT_ASYNC_STEP1("cc", |
| - "PendingTree", m_pendingTree.get(), "activate", |
| - "state", ValueToString(activationStateAsValue())); |
| - |
| - // It's always fine to activate to an empty tree. Otherwise, only |
| - // activate once all visible resources in pending tree are ready |
| - // or tile manager has no work scheduled for pending tree. |
| - if (activeTree()->RootLayer() && |
| - !pendingTree()->AreVisibleResourcesReady()) { |
| - // In smoothness takes priority mode, the pending tree's priorities are |
| - // ignored, so the tile manager may not have work for it even though it |
| - // is simultaneously not ready to be activated. |
| - if (m_tileManager->GlobalState().tree_priority == |
| - SMOOTHNESS_TAKES_PRIORITY || |
| - m_tileManager->HasPendingWorkScheduled(PENDING_TREE)) { |
| - TRACE_EVENT_ASYNC_STEP0("cc", |
| - "PendingTree", |
| - m_pendingTree.get(), |
| - "waiting"); |
| - return false; |
| - } |
| - } |
| - |
| - activatePendingTree(); |
| - return true; |
| +void LayerTreeHostImpl::CreatePendingTree() { |
| + CHECK(!pending_tree_); |
| + if (recycle_tree_) |
| + recycle_tree_.swap(pending_tree_); |
| + else |
| + pending_tree_ = LayerTreeImpl::create(this); |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| + client_->OnHasPendingTreeStateChanged(pending_tree_); |
| + TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get()); |
| + TRACE_EVENT_ASYNC_STEP0("cc", |
| + "PendingTree", pending_tree_.get(), "waiting"); |
| } |
| -void LayerTreeHostImpl::activatePendingTree() |
| -{ |
| - CHECK(m_pendingTree); |
| - TRACE_EVENT_ASYNC_END0("cc", "PendingTree", m_pendingTree.get()); |
| - |
| - m_activeTree->PushPersistedState(m_pendingTree.get()); |
| - if (m_pendingTree->needs_full_tree_sync()) |
| - m_activeTree->SetRootLayer(TreeSynchronizer::synchronizeTrees(m_pendingTree->RootLayer(), m_activeTree->DetachLayerTree(), m_activeTree.get())); |
| - TreeSynchronizer::pushProperties(m_pendingTree->RootLayer(), m_activeTree->RootLayer()); |
| - DCHECK(!m_recycleTree); |
| - |
| - m_pendingTree->PushPropertiesTo(m_activeTree.get()); |
| - |
| - // Now that we've synced everything from the pending tree to the active |
| - // tree, rename the pending tree the recycle tree so we can reuse it on the |
| - // next sync. |
| - m_pendingTree.swap(m_recycleTree); |
| - m_recycleTree->ClearRenderSurfaces(); |
| - |
| - m_activeTree->DidBecomeActive(); |
| - |
| - // Reduce wasted memory now that unlinked resources are guaranteed not |
| - // to be used. |
| - m_client->reduceWastedContentsTextureMemoryOnImplThread(); |
| +void LayerTreeHostImpl::CheckForCompletedTileUploads() { |
| + DCHECK(!client_->IsInsideDraw()) << |
| + "Checking for completed uploads within a draw may trigger " |
| + "spurious redraws."; |
| + if (tile_manager_) |
| + tile_manager_->CheckForCompletedTileUploads(); |
| +} |
| - m_client->onCanDrawStateChanged(canDraw()); |
| - m_client->onHasPendingTreeStateChanged(pendingTree()); |
| - m_client->setNeedsRedrawOnImplThread(); |
| - m_client->renewTreePriority(); |
| +bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() { |
| + if (!pending_tree_) |
| + return false; |
| - if (m_tileManager && m_debugState.continuousPainting) { |
| - RenderingStats stats; |
| - m_tileManager->GetRenderingStats(&stats); |
| - m_paintTimeCounter->SaveRasterizeTime(stats.totalRasterizeTimeForNowBinsOnPendingTree, m_activeTree->source_frame_number()); |
| + CHECK(tile_manager_); |
| + |
| + pending_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_PENDING_TREE); |
| + |
| + TRACE_EVENT_ASYNC_STEP1("cc", |
| + "PendingTree", pending_tree_.get(), "activate", |
| + "state", ValueToString(ActivationStateAsValue())); |
| + |
| + // It's always fine to activate to an empty tree. Otherwise, only |
| + // activate once all visible resources in pending tree are ready |
| + // or tile manager has no work scheduled for pending tree. |
| + if (active_tree_->root_layer() && |
| + !pending_tree_->AreVisibleResourcesReady()) { |
| + // In smoothness takes priority mode, the pending tree's priorities are |
| + // ignored, so the tile manager may not have work for it even though it |
| + // is simultaneously not ready to be activated. |
| + if (tile_manager_->GlobalState().tree_priority == |
| + SMOOTHNESS_TAKES_PRIORITY || |
| + tile_manager_->HasPendingWorkScheduled(PENDING_TREE)) { |
| + TRACE_EVENT_ASYNC_STEP0("cc", |
| + "PendingTree", |
| + pending_tree_.get(), |
| + "waiting"); |
| + return false; |
| } |
| -} |
| + } |
| + |
| + ActivatePendingTree(); |
| + return true; |
| +} |
| + |
| +void LayerTreeHostImpl::ActivatePendingTree() { |
| + CHECK(pending_tree_); |
| + TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get()); |
| + |
| + active_tree_->PushPersistedState(pending_tree_.get()); |
| + if (pending_tree_->needs_full_tree_sync()) { |
| + active_tree_->SetRootLayer( |
| + TreeSynchronizer::synchronizeTrees(pending_tree_->root_layer(), |
| + active_tree_->DetachLayerTree(), |
| + active_tree_.get())); |
| + } |
| + TreeSynchronizer::pushProperties(pending_tree_->root_layer(), |
| + active_tree_->root_layer()); |
| + DCHECK(!recycle_tree_); |
| + |
| + pending_tree_->PushPropertiesTo(active_tree_.get()); |
| + |
| + // Now that we've synced everything from the pending tree to the active |
| + // tree, rename the pending tree the recycle tree so we can reuse it on the |
| + // next sync. |
| + pending_tree_.swap(recycle_tree_); |
| + recycle_tree_->ClearRenderSurfaces(); |
| + |
| + active_tree_->DidBecomeActive(); |
| + |
| + // Reduce wasted memory now that unlinked resources are guaranteed not |
| + // to be used. |
| + client_->ReduceWastedContentsTextureMemoryOnImplThread(); |
| + |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| + client_->OnHasPendingTreeStateChanged(pending_tree_); |
| + client_->SetNeedsRedrawOnImplThread(); |
| + client_->RenewTreePriority(); |
| + |
| + if (tile_manager_ && debug_state_.continuousPainting) { |
| + RenderingStats stats; |
| + tile_manager_->GetRenderingStats(&stats); |
| + paint_time_counter_->SaveRasterizeTime( |
| + stats.totalRasterizeTimeForNowBinsOnPendingTree, |
| + active_tree_->source_frame_number()); |
| + } |
| +} |
| + |
| +void LayerTreeHostImpl::SetVisible(bool visible) { |
| + DCHECK(proxy_->IsImplThread()); |
| + |
| + if (visible_ == visible) |
| + return; |
| + visible_ = visible; |
| + DidVisibilityChange(this, visible_); |
| + EnforceManagedMemoryPolicy(managed_memory_policy_); |
| + |
| + if (!renderer_) |
| + return; |
| + |
| + renderer_->SetVisible(visible); |
| + |
| + SetBackgroundTickingEnabled( |
| + !visible_ && |
| + !animation_registrar_->active_animation_controllers().empty()); |
| +} |
| + |
| +bool LayerTreeHostImpl::InitializeRenderer( |
| + scoped_ptr<OutputSurface> output_surface) { |
| + // Since we will create a new resource provider, we cannot continue to use |
| + // the old resources (i.e. render_surfaces and texture IDs). Clear them |
| + // before we destroy the old resource provider. |
| + if (active_tree_->root_layer()) |
| + ClearRenderSurfaces(); |
| + if (active_tree_->root_layer()) |
| + SendDidLoseOutputSurfaceRecursive(active_tree_->root_layer()); |
| + if (pending_tree_ && pending_tree_->root_layer()) |
| + SendDidLoseOutputSurfaceRecursive(pending_tree_->root_layer()); |
| + if (recycle_tree_ && recycle_tree_->root_layer()) |
| + SendDidLoseOutputSurfaceRecursive(recycle_tree_->root_layer()); |
| + |
| + // Note: order is important here. |
| + renderer_.reset(); |
| + tile_manager_.reset(); |
| + resource_provider_.reset(); |
| + output_surface_.reset(); |
| + |
| + if (!output_surface->BindToClient(this)) |
| + return false; |
| -void LayerTreeHostImpl::setVisible(bool visible) |
| -{ |
| - DCHECK(m_proxy->IsImplThread()); |
| - |
| - if (m_visible == visible) |
| - return; |
| - m_visible = visible; |
| - didVisibilityChange(this, m_visible); |
| - EnforceManagedMemoryPolicy(m_managedMemoryPolicy); |
| - |
| - if (!m_renderer) |
| - return; |
| - |
| - m_renderer->SetVisible(visible); |
| - |
| - setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty()); |
| -} |
| - |
| -bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface) |
| -{ |
| - // Since we will create a new resource provider, we cannot continue to use |
| - // the old resources (i.e. renderSurfaces and texture IDs). Clear them |
| - // before we destroy the old resource provider. |
| - if (rootLayer()) |
| - clearRenderSurfaces(); |
| - if (activeTree()->RootLayer()) |
| - sendDidLoseOutputSurfaceRecursive(activeTree()->RootLayer()); |
| - if (pendingTree() && pendingTree()->RootLayer()) |
| - sendDidLoseOutputSurfaceRecursive(pendingTree()->RootLayer()); |
| - if (m_recycleTree && m_recycleTree->RootLayer()) |
| - sendDidLoseOutputSurfaceRecursive(m_recycleTree->RootLayer()); |
| - |
| - // Note: order is important here. |
| - m_renderer.reset(); |
| - m_tileManager.reset(); |
| - m_resourceProvider.reset(); |
| - m_outputSurface.reset(); |
| - |
| - if (!outputSurface->BindToClient(this)) |
| - return false; |
| - |
| - scoped_ptr<ResourceProvider> resourceProvider = ResourceProvider::Create(outputSurface.get()); |
| - if (!resourceProvider) |
| - return false; |
| - |
| - if (m_settings.implSidePainting) { |
| - m_tileManager.reset(new TileManager(this, |
| - resourceProvider.get(), |
| - m_settings.numRasterThreads, |
| - m_settings.useCheapnessEstimator, |
| - m_settings.useColorEstimator, |
| - m_settings.predictionBenchmarking)); |
| - m_tileManager->SetRecordRenderingStats(m_debugState.recordRenderingStats()); |
| - } |
| + scoped_ptr<ResourceProvider> resource_provider = |
| + ResourceProvider::Create(output_surface.get()); |
| + if (!resource_provider) |
| + return false; |
| - if (outputSurface->capabilities().has_parent_compositor) |
| - m_renderer = DelegatingRenderer::Create(this, outputSurface.get(), resourceProvider.get()); |
| - else if (outputSurface->context3d()) |
| - m_renderer = GLRenderer::create(this, outputSurface.get(), resourceProvider.get()); |
| - else if (outputSurface->software_device()) |
| - m_renderer = SoftwareRenderer::Create(this, outputSurface.get(), resourceProvider.get()); |
| - if (!m_renderer) |
| - return false; |
| + if (settings_.implSidePainting) { |
| + tile_manager_.reset(new TileManager(this, |
| + resource_provider.get(), |
| + settings_.numRasterThreads, |
| + settings_.useCheapnessEstimator, |
| + settings_.useColorEstimator, |
| + settings_.predictionBenchmarking)); |
| + tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats()); |
| + } |
| + |
| + if (output_surface->capabilities().has_parent_compositor) { |
| + renderer_ = DelegatingRenderer::Create(this, |
| + output_surface.get(), |
| + resource_provider.get()); |
| + } else if (output_surface->context3d()) { |
| + renderer_ = GLRenderer::create(this, |
| + output_surface.get(), |
| + resource_provider.get()); |
| + } else if (output_surface->software_device()) { |
| + renderer_ = SoftwareRenderer::Create(this, |
| + output_surface.get(), |
| + resource_provider.get()); |
| + } |
| + if (!renderer_) |
| + return false; |
| - m_resourceProvider = resourceProvider.Pass(); |
| - m_outputSurface = outputSurface.Pass(); |
| + resource_provider_ = resource_provider.Pass(); |
| + output_surface_ = output_surface.Pass(); |
| - if (!m_visible) |
| - m_renderer->SetVisible(m_visible); |
| + if (!visible_) |
| + renderer_->SetVisible(visible_); |
| - m_client->onCanDrawStateChanged(canDraw()); |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| - // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs |
| - // to be initialized to get max texture size. |
| - activeTree()->set_needs_update_draw_properties(); |
| - if (pendingTree()) |
| - pendingTree()->set_needs_update_draw_properties(); |
| + // See note in LayerTreeImpl::UpdateDrawProperties. Renderer needs |
| + // to be initialized to get max texture size. |
| + active_tree_->set_needs_update_draw_properties(); |
| + if (pending_tree_) |
| + pending_tree_->set_needs_update_draw_properties(); |
| - return true; |
| + return true; |
| } |
| -void LayerTreeHostImpl::setViewportSize(const gfx::Size& layoutViewportSize, const gfx::Size& deviceViewportSize) |
| -{ |
| - if (layoutViewportSize == m_layoutViewportSize && deviceViewportSize == m_deviceViewportSize) |
| - return; |
| +void LayerTreeHostImpl::SetViewportSize(gfx::Size layout_viewport_size, |
| + gfx::Size device_viewport_size) { |
| + if (layout_viewport_size == layout_viewport_size_ && |
| + device_viewport_size == device_viewport_size_) |
| + return; |
| - if (pendingTree() && m_deviceViewportSize != deviceViewportSize) |
| - activeTree()->SetViewportSizeInvalid(); |
| + if (pending_tree_ && device_viewport_size_ != device_viewport_size) |
| + active_tree_->SetViewportSizeInvalid(); |
| - m_layoutViewportSize = layoutViewportSize; |
| - m_deviceViewportSize = deviceViewportSize; |
| + layout_viewport_size_ = layout_viewport_size; |
| + device_viewport_size_ = device_viewport_size; |
| - updateMaxScrollOffset(); |
| + UpdateMaxScrollOffset(); |
| - if (m_renderer) |
| - m_renderer->ViewportChanged(); |
| + if (renderer_) |
| + renderer_->ViewportChanged(); |
| - m_client->onCanDrawStateChanged(canDraw()); |
| + client_->OnCanDrawStateChanged(CanDraw()); |
| } |
| -static void adjustScrollsForPageScaleChange(LayerImpl* layerImpl, float pageScaleChange) |
| -{ |
| - if (!layerImpl) |
| - return; |
| +static void AdjustScrollsForPageScaleChange(LayerImpl* layer_impl, |
| + float page_scale_change) { |
| + if (!layer_impl) |
| + return; |
| - if (layerImpl->scrollable()) { |
| - // We need to convert impl-side scroll deltas to pageScale space. |
| - gfx::Vector2dF scrollDelta = layerImpl->scroll_delta(); |
| - scrollDelta.Scale(pageScaleChange); |
| - layerImpl->SetScrollDelta(scrollDelta); |
| - } |
| + if (layer_impl->scrollable()) { |
| + // We need to convert impl-side scroll deltas to page_scale space. |
| + gfx::Vector2dF scroll_delta = layer_impl->scroll_delta(); |
| + scroll_delta.Scale(page_scale_change); |
| + layer_impl->SetScrollDelta(scroll_delta); |
| + } |
| - for (size_t i = 0; i < layerImpl->children().size(); ++i) |
| - adjustScrollsForPageScaleChange(layerImpl->children()[i], pageScaleChange); |
| + for (size_t i = 0; i < layer_impl->children().size(); ++i) |
| + AdjustScrollsForPageScaleChange(layer_impl->children()[i], |
| + page_scale_change); |
| } |
| -void LayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor) |
| -{ |
| - if (deviceScaleFactor == m_deviceScaleFactor) |
| - return; |
| - m_deviceScaleFactor = deviceScaleFactor; |
| +void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { |
| + if (device_scale_factor == device_scale_factor_) |
| + return; |
| + device_scale_factor_ = device_scale_factor; |
| - updateMaxScrollOffset(); |
| + UpdateMaxScrollOffset(); |
| } |
| -void LayerTreeHostImpl::updateMaxScrollOffset() |
| -{ |
| - activeTree()->UpdateMaxScrollOffset(); |
| +void LayerTreeHostImpl::UpdateMaxScrollOffset() { |
| + active_tree_->UpdateMaxScrollOffset(); |
| } |
| -void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() |
| -{ |
| - activeTree()->set_needs_update_draw_properties(); |
| +void LayerTreeHostImpl::setActiveTreeNeedsUpdateDrawProperties() { |
| + active_tree_->set_needs_update_draw_properties(); |
| } |
| -void LayerTreeHostImpl::setNeedsRedraw() |
| -{ |
| - m_client->setNeedsRedrawOnImplThread(); |
| +void LayerTreeHostImpl::setNeedsRedraw() { |
| + client_->SetNeedsRedrawOnImplThread(); |
| } |
| -bool LayerTreeHostImpl::ensureRenderSurfaceLayerList() |
| -{ |
| - activeTree()->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE); |
| - return activeTree()->RenderSurfaceLayerList().size(); |
| +bool LayerTreeHostImpl::EnsureRenderSurfaceLayerList() { |
| + active_tree_->UpdateDrawProperties(LayerTreeImpl::UPDATE_ACTIVE_TREE); |
| + return active_tree_->RenderSurfaceLayerList().size(); |
| } |
| -InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewportPoint, InputHandlerClient::ScrollInputType type) |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin"); |
| - |
| - if (m_topControlsManager) |
| - m_topControlsManager->ScrollBegin(); |
| +InputHandlerClient::ScrollStatus LayerTreeHostImpl::ScrollBegin( |
| + gfx::Point viewport_point, InputHandlerClient::ScrollInputType type) { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin"); |
| - DCHECK(!currentlyScrollingLayer()); |
| - clearCurrentlyScrollingLayer(); |
| + if (top_controls_manager_) |
| + top_controls_manager_->ScrollBegin(); |
| - if (!ensureRenderSurfaceLayerList()) |
| - return ScrollIgnored; |
| + DCHECK(!CurrentlyScrollingLayer()); |
| + ClearCurrentlyScrollingLayer(); |
| - gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceScaleFactor); |
| + if (!EnsureRenderSurfaceLayerList()) |
| + return ScrollIgnored; |
| - // First find out which layer was hit from the saved list of visible layers |
| - // in the most recent frame. |
| - LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(deviceViewportPoint, activeTree()->RenderSurfaceLayerList()); |
| + gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, |
| + device_scale_factor_); |
| + |
| + // First find out which layer was hit from the saved list of visible layers |
| + // in the most recent frame. |
| + LayerImpl* layer_impl = LayerTreeHostCommon::findLayerThatIsHitByPoint( |
| + device_viewport_point, active_tree_->RenderSurfaceLayerList()); |
| + |
| + // Walk up the hierarchy and look for a scrollable layer. |
| + LayerImpl* potentially_scrolling_layer_impl = 0; |
| + for (; layer_impl; layer_impl = layer_impl->parent()) { |
| + // The content layer can also block attempts to scroll outside the main |
| + // thread. |
| + ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); |
| + if (status == ScrollOnMainThread) { |
| + num_main_thread_scrolls_++; |
| + UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); |
| + return ScrollOnMainThread; |
| + } |
| - // Walk up the hierarchy and look for a scrollable layer. |
| - LayerImpl* potentiallyScrollingLayerImpl = 0; |
| - for (; layerImpl; layerImpl = layerImpl->parent()) { |
| - // The content layer can also block attempts to scroll outside the main thread. |
| - if (layerImpl->TryScroll(deviceViewportPoint, type) == ScrollOnMainThread) { |
| - m_numMainThreadScrolls++; |
| - UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); |
| - return ScrollOnMainThread; |
| - } |
| + LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl); |
| + if (!scroll_layer_impl) |
| + continue; |
| - LayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl); |
| - if (!scrollLayerImpl) |
| - continue; |
| + status = scroll_layer_impl->TryScroll(device_viewport_point, type); |
| - ScrollStatus status = scrollLayerImpl->TryScroll(deviceViewportPoint, type); |
| + // If any layer wants to divert the scroll event to the main thread, abort. |
| + if (status == ScrollOnMainThread) { |
| + num_main_thread_scrolls_++; |
| + UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); |
| + return ScrollOnMainThread; |
| + } |
| - // If any layer wants to divert the scroll event to the main thread, abort. |
| - if (status == ScrollOnMainThread) { |
| - m_numMainThreadScrolls++; |
| - UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true); |
| - return ScrollOnMainThread; |
| - } |
| + if (status == ScrollStarted && !potentially_scrolling_layer_impl) |
| + potentially_scrolling_layer_impl = scroll_layer_impl; |
| + } |
| + |
| + // When hiding top controls is enabled and the controls are hidden or |
| + // overlaying the content, force scrolls to be enabled on the root layer to |
| + // allow bringing the top controls back into view. |
| + if (!potentially_scrolling_layer_impl && top_controls_manager_ && |
| + top_controls_manager_->content_top_offset() != |
| + settings_.topControlsHeight) { |
| + potentially_scrolling_layer_impl = RootScrollLayer(); |
| + } |
| + |
| + if (potentially_scrolling_layer_impl) { |
| + active_tree_->set_currently_scrolling_layer( |
| + potentially_scrolling_layer_impl); |
| + should_bubble_scrolls_ = (type != NonBubblingGesture); |
| + wheel_scrolling_ = (type == Wheel); |
| + num_impl_thread_scrolls_++; |
| + client_->RenewTreePriority(); |
| + UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); |
| + return ScrollStarted; |
| + } |
| + return ScrollIgnored; |
| +} |
| + |
| +gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta( |
| + LayerImpl* layer_impl, |
| + float scale_from_viewport_to_screen_space, |
| + gfx::PointF viewport_point, |
| + gfx::Vector2dF viewport_delta) { |
| + // Layers with non-invertible screen space transforms should not have passed |
| + // the scroll hit test in the first place. |
| + DCHECK(layer_impl->screen_space_transform().IsInvertible()); |
| + gfx::Transform inverse_screen_space_transform( |
| + gfx::Transform::kSkipInitialization); |
| + bool did_invert = layer_impl->screen_space_transform().GetInverse( |
| + &inverse_screen_space_transform); |
| + // TODO: With the advent of impl-side crolling for non-root layers, we may |
| + // need to explicitly handle uninvertible transforms here. |
| + DCHECK(did_invert); |
| + |
| + gfx::PointF screen_space_point = |
| + gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space); |
| + |
| + gfx::Vector2dF screen_space_delta = viewport_delta; |
| + screen_space_delta.Scale(scale_from_viewport_to_screen_space); |
| + |
| + // First project the scroll start and end points to local layer space to find |
| + // the scroll delta in layer coordinates. |
| + bool start_clipped, end_clipped; |
| + gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta; |
| + gfx::PointF local_start_point = |
| + MathUtil::projectPoint(inverse_screen_space_transform, |
| + screen_space_point, |
| + start_clipped); |
| + gfx::PointF local_end_point = |
| + MathUtil::projectPoint(inverse_screen_space_transform, |
| + screen_space_end_point, |
| + end_clipped); |
| + |
| + // In general scroll point coordinates should not get clipped. |
| + DCHECK(!start_clipped); |
| + DCHECK(!end_clipped); |
| + if (start_clipped || end_clipped) |
| + return gfx::Vector2dF(); |
| + |
| + // local_start_point and local_end_point are in content space but we want to |
| + // move them to layer space for scrolling. |
| + float width_scale = 1.f / layer_impl->contents_scale_x(); |
| + float height_scale = 1.f / layer_impl->contents_scale_y(); |
| + local_start_point.Scale(width_scale, height_scale); |
| + local_end_point.Scale(width_scale, height_scale); |
| + |
| + // Apply the scroll delta. |
| + gfx::Vector2dF previous_delta = layer_impl->scroll_delta(); |
| + layer_impl->ScrollBy(local_end_point - local_start_point); |
| + |
| + // Get the end point in the layer's content space so we can apply its |
| + // screenSpaceTransform. |
| + gfx::PointF actual_local_end_point = local_start_point + |
| + layer_impl->scroll_delta() - |
| + previous_delta; |
| + gfx::PointF actual_local_content_end_point = |
| + gfx::ScalePoint(actual_local_end_point, |
| + 1.f / width_scale, |
| + 1.f / height_scale); |
| + |
| + // Calculate the applied scroll delta in viewport space coordinates. |
| + gfx::PointF actual_screen_space_end_point = |
| + MathUtil::mapPoint(layer_impl->screen_space_transform(), |
| + actual_local_content_end_point, |
| + end_clipped); |
| + DCHECK(!end_clipped); |
| + if (end_clipped) |
| + return gfx::Vector2dF(); |
| + gfx::PointF actual_viewport_end_point = |
| + gfx::ScalePoint(actual_screen_space_end_point, |
| + 1.f / scale_from_viewport_to_screen_space); |
| + return actual_viewport_end_point - viewport_point; |
| +} |
| + |
| +static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, |
| + gfx::Vector2dF localDelta) { |
| + gfx::Vector2dF previous_delta(layer_impl->scroll_delta()); |
| + layer_impl->ScrollBy(localDelta); |
| + return layer_impl->scroll_delta() - previous_delta; |
| +} |
| + |
| +bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
| + gfx::Vector2dF scroll_delta) { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); |
| + if (!CurrentlyScrollingLayer()) |
| + return false; |
| - if (status == ScrollStarted && !potentiallyScrollingLayerImpl) |
| - potentiallyScrollingLayerImpl = scrollLayerImpl; |
| + gfx::Vector2dF pending_delta = scroll_delta; |
| + bool did_scroll = false; |
| + |
| + for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); |
| + layer_impl; |
| + layer_impl = layer_impl->parent()) { |
| + if (!layer_impl->scrollable()) |
| + continue; |
| + |
| + gfx::Vector2dF applied_delta; |
| + if (top_controls_manager_ && layer_impl == RootScrollLayer()) |
| + pending_delta = top_controls_manager_->ScrollBy(pending_delta); |
| + |
| + // Gesture events need to be transformed from viewport coordinates to local |
| + // layer coordinates so that the scrolling contents exactly follow the |
| + // user's finger. In contrast, wheel events represent a fixed amount of |
| + // scrolling so we can just apply them directly. |
| + if (!wheel_scrolling_) { |
| + float scale_from_viewport_to_screen_space = device_scale_factor_; |
| + applied_delta = |
| + ScrollLayerWithViewportSpaceDelta(layer_impl, |
| + scale_from_viewport_to_screen_space, |
| + viewport_point, pending_delta); |
| + } else |
|
enne (OOO)
2013/03/13 05:22:05
{}
danakj
2013/03/13 15:49:11
Done.
|
| + applied_delta = ScrollLayerWithLocalDelta(layer_impl, pending_delta); |
| + |
| + // If the layer wasn't able to move, try the next one in the hierarchy. |
| + float move_threshold_squared = 0.1f * 0.1f; |
| + if (applied_delta.LengthSquared() < move_threshold_squared) { |
| + if (should_bubble_scrolls_ || !did_lock_scrolling_layer_) |
| + continue; |
| + else |
| + break; |
| } |
| - |
| - // When hiding top controls is enabled and the controls are hidden or |
| - // overlaying the content, force scrolls to be enabled on the root layer to |
| - // allow bringing the top controls back into view. |
| - if (!potentiallyScrollingLayerImpl && m_topControlsManager && |
| - m_topControlsManager->content_top_offset() != m_settings.topControlsHeight) { |
| - potentiallyScrollingLayerImpl = rootScrollLayer(); |
| + did_scroll = true; |
| + did_lock_scrolling_layer_ = true; |
| + if (!should_bubble_scrolls_) { |
| + active_tree_->set_currently_scrolling_layer(layer_impl); |
| + break; |
| } |
| - if (potentiallyScrollingLayerImpl) { |
| - m_activeTree->set_currently_scrolling_layer(potentiallyScrollingLayerImpl); |
| - m_shouldBubbleScrolls = (type != NonBubblingGesture); |
| - m_wheelScrolling = (type == Wheel); |
| - m_numImplThreadScrolls++; |
| - m_client->renewTreePriority(); |
| - UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); |
| - return ScrollStarted; |
| + // If the applied delta is within 45 degrees of the input delta, bail out to |
| + // make it easier to scroll just one layer in one direction without |
| + // affecting any of its parents. |
| + float angle_threshold = 45; |
| + if (MathUtil::smallestAngleBetweenVectors( |
| + applied_delta, pending_delta) < angle_threshold) { |
| + pending_delta = gfx::Vector2d(); |
| + break; |
| } |
| - return ScrollIgnored; |
| -} |
| -gfx::Vector2dF LayerTreeHostImpl::scrollLayerWithViewportSpaceDelta(LayerImpl* layerImpl, float scaleFromViewportToScreenSpace, gfx::PointF viewportPoint, gfx::Vector2dF viewportDelta) |
| -{ |
| - // Layers with non-invertible screen space transforms should not have passed the scroll hit |
| - // test in the first place. |
| - DCHECK(layerImpl->screen_space_transform().IsInvertible()); |
| - gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitialization); |
| - bool didInvert = layerImpl->screen_space_transform().GetInverse(&inverseScreenSpaceTransform); |
| - // TODO: With the advent of impl-side crolling for non-root layers, we may |
| - // need to explicitly handle uninvertible transforms here. |
| - DCHECK(didInvert); |
| - |
| - gfx::PointF screenSpacePoint = gfx::ScalePoint(viewportPoint, scaleFromViewportToScreenSpace); |
| - |
| - gfx::Vector2dF screenSpaceDelta = viewportDelta; |
| - screenSpaceDelta.Scale(scaleFromViewportToScreenSpace); |
| - |
| - // First project the scroll start and end points to local layer space to find the scroll delta |
| - // in layer coordinates. |
| - bool startClipped, endClipped; |
| - gfx::PointF screenSpaceEndPoint = screenSpacePoint + screenSpaceDelta; |
| - gfx::PointF localStartPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpacePoint, startClipped); |
| - gfx::PointF localEndPoint = MathUtil::projectPoint(inverseScreenSpaceTransform, screenSpaceEndPoint, endClipped); |
| - |
| - // In general scroll point coordinates should not get clipped. |
| - DCHECK(!startClipped); |
| - DCHECK(!endClipped); |
| - if (startClipped || endClipped) |
| - return gfx::Vector2dF(); |
| - |
| - // localStartPoint and localEndPoint are in content space but we want to move them to layer space for scrolling. |
| - float widthScale = 1.f / layerImpl->contents_scale_x(); |
| - float heightScale = 1.f / layerImpl->contents_scale_y(); |
| - localStartPoint.Scale(widthScale, heightScale); |
| - localEndPoint.Scale(widthScale, heightScale); |
| - |
| - // Apply the scroll delta. |
| - gfx::Vector2dF previousDelta = layerImpl->scroll_delta(); |
| - layerImpl->ScrollBy(localEndPoint - localStartPoint); |
| - |
| - // Get the end point in the layer's content space so we can apply its screenSpaceTransform. |
| - gfx::PointF actualLocalEndPoint = localStartPoint + layerImpl->scroll_delta() - previousDelta; |
| - gfx::PointF actualLocalContentEndPoint = gfx::ScalePoint(actualLocalEndPoint, 1 / widthScale, 1 / heightScale); |
| - |
| - // Calculate the applied scroll delta in viewport space coordinates. |
| - gfx::PointF actualScreenSpaceEndPoint = MathUtil::mapPoint(layerImpl->screen_space_transform(), actualLocalContentEndPoint, endClipped); |
| - DCHECK(!endClipped); |
| - if (endClipped) |
| - return gfx::Vector2dF(); |
| - gfx::PointF actualViewportEndPoint = gfx::ScalePoint(actualScreenSpaceEndPoint, 1 / scaleFromViewportToScreenSpace); |
| - return actualViewportEndPoint - viewportPoint; |
| -} |
| - |
| -static gfx::Vector2dF scrollLayerWithLocalDelta(LayerImpl& layerImpl, gfx::Vector2dF localDelta) |
| -{ |
| - gfx::Vector2dF previousDelta(layerImpl.scroll_delta()); |
| - layerImpl.ScrollBy(localDelta); |
| - return layerImpl.scroll_delta() - previousDelta; |
| -} |
| - |
| -bool LayerTreeHostImpl::scrollBy(const gfx::Point& viewportPoint, |
| - const gfx::Vector2dF& scrollDelta) |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBy"); |
| - if (!currentlyScrollingLayer()) |
| - return false; |
| - |
| - gfx::Vector2dF pendingDelta = scrollDelta; |
| - bool didScroll = false; |
| - |
| - for (LayerImpl* layerImpl = currentlyScrollingLayer(); layerImpl; layerImpl = layerImpl->parent()) { |
| - if (!layerImpl->scrollable()) |
| - continue; |
| - |
| - gfx::Vector2dF appliedDelta; |
| - if (m_topControlsManager && layerImpl == rootScrollLayer()) |
| - pendingDelta = m_topControlsManager->ScrollBy(pendingDelta); |
| - |
| - // Gesture events need to be transformed from viewport coordinates to local layer coordinates |
| - // so that the scrolling contents exactly follow the user's finger. In contrast, wheel |
| - // events represent a fixed amount of scrolling so we can just apply them directly. |
| - if (!m_wheelScrolling) { |
| - float scaleFromViewportToScreenSpace = m_deviceScaleFactor; |
| - appliedDelta = scrollLayerWithViewportSpaceDelta(layerImpl, scaleFromViewportToScreenSpace, viewportPoint, pendingDelta); |
| - } else |
| - appliedDelta = scrollLayerWithLocalDelta(*layerImpl, pendingDelta); |
| - |
| - // If the layer wasn't able to move, try the next one in the hierarchy. |
| - float moveThresholdSquared = 0.1f * 0.1f; |
| - if (appliedDelta.LengthSquared() < moveThresholdSquared) { |
| - if (m_shouldBubbleScrolls || !m_didLockScrollingLayer) |
| - continue; |
| - else |
| - break; |
| - } |
| - didScroll = true; |
| - m_didLockScrollingLayer = true; |
| - if (!m_shouldBubbleScrolls) { |
| - m_activeTree->set_currently_scrolling_layer(layerImpl); |
| - break; |
| - } |
| - |
| - // If the applied delta is within 45 degrees of the input delta, bail out to make it easier |
| - // to scroll just one layer in one direction without affecting any of its parents. |
| - float angleThreshold = 45; |
| - if (MathUtil::smallestAngleBetweenVectors(appliedDelta, pendingDelta) < angleThreshold) { |
| - pendingDelta = gfx::Vector2d(); |
| - break; |
| - } |
| - |
| - // Allow further movement only on an axis perpendicular to the direction in which the layer |
| - // moved. |
| - gfx::Vector2dF perpendicularAxis(-appliedDelta.y(), appliedDelta.x()); |
| - pendingDelta = MathUtil::projectVector(pendingDelta, perpendicularAxis); |
| + // Allow further movement only on an axis perpendicular to the direction in |
| + // which the layer moved. |
| + gfx::Vector2dF perpendicularAxis(-applied_delta.y(), applied_delta.x()); |
|
enne (OOO)
2013/03/13 05:22:05
perpendicular_axis
danakj
2013/03/13 15:49:11
Done.
|
| + pending_delta = MathUtil::projectVector(pending_delta, perpendicularAxis); |
| - if (gfx::ToFlooredVector2d(pendingDelta).IsZero()) |
| - break; |
| - } |
| + if (gfx::ToFlooredVector2d(pending_delta).IsZero()) |
| + break; |
| + } |
| - if (didScroll) { |
| - m_client->setNeedsCommitOnImplThread(); |
| - m_client->setNeedsRedrawOnImplThread(); |
| - m_client->renewTreePriority(); |
| - } |
| - return didScroll; |
| + if (did_scroll) { |
| + client_->SetNeedsCommitOnImplThread(); |
| + client_->SetNeedsRedrawOnImplThread(); |
| + client_->RenewTreePriority(); |
| + } |
| + return did_scroll; |
| } |
| -void LayerTreeHostImpl::clearCurrentlyScrollingLayer() |
| -{ |
| - m_activeTree->ClearCurrentlyScrollingLayer(); |
| - m_didLockScrollingLayer = false; |
| +void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { |
| + active_tree_->ClearCurrentlyScrollingLayer(); |
| + did_lock_scrolling_layer_ = false; |
| } |
| -void LayerTreeHostImpl::scrollEnd() |
| -{ |
| - if (m_topControlsManager) |
| - m_topControlsManager->ScrollEnd(); |
| - clearCurrentlyScrollingLayer(); |
| +void LayerTreeHostImpl::ScrollEnd() { |
| + if (top_controls_manager_) |
| + top_controls_manager_->ScrollEnd(); |
| + ClearCurrentlyScrollingLayer(); |
| } |
| -void LayerTreeHostImpl::pinchGestureBegin() |
| -{ |
| - m_pinchGestureActive = true; |
| - m_previousPinchAnchor = gfx::Point(); |
| - m_client->renewTreePriority(); |
| +void LayerTreeHostImpl::PinchGestureBegin() { |
| + pinch_gesture_active_ = true; |
| + previous_pinch_anchor_ = gfx::Point(); |
| + client_->RenewTreePriority(); |
| } |
| -void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor) |
| -{ |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::pinchGestureUpdate"); |
| +void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, |
| + gfx::Point anchor) { |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::pinchGestureUpdate"); |
|
enne (OOO)
2013/03/13 05:22:05
PinchGestureUpdate
danakj
2013/03/13 15:49:11
Done.
|
| - if (!rootScrollLayer()) |
| - return; |
| + if (!RootScrollLayer()) |
| + return; |
| - // Keep the center-of-pinch anchor specified by (x, y) in a stable |
| - // position over the course of the magnify. |
| - float pageScaleDelta = activeTree()->page_scale_delta(); |
| - gfx::PointF previousScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta); |
| - activeTree()->SetPageScaleDelta(pageScaleDelta * magnifyDelta); |
| - pageScaleDelta = activeTree()->page_scale_delta(); |
| - gfx::PointF newScaleAnchor = gfx::ScalePoint(anchor, 1 / pageScaleDelta); |
| - gfx::Vector2dF move = previousScaleAnchor - newScaleAnchor; |
| + // Keep the center-of-pinch anchor specified by (x, y) in a stable |
| + // position over the course of the magnify. |
| + float page_scale_delta = active_tree_->page_scale_delta(); |
| + gfx::PointF previous_scale_anchor = |
| + gfx::ScalePoint(anchor, 1 / page_scale_delta); |
| + active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta); |
| + page_scale_delta = active_tree_->page_scale_delta(); |
| + gfx::PointF new_scale_anchor = |
| + gfx::ScalePoint(anchor, 1 / page_scale_delta); |
| + gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor; |
| - m_previousPinchAnchor = anchor; |
| + previous_pinch_anchor_ = anchor; |
| - move.Scale(1 / activeTree()->page_scale_factor()); |
| + move.Scale(1 / active_tree_->page_scale_factor()); |
| - rootScrollLayer()->ScrollBy(move); |
| + RootScrollLayer()->ScrollBy(move); |
| - if (rootScrollLayer()->scrollbar_animation_controller()) |
| - rootScrollLayer()->scrollbar_animation_controller()->didPinchGestureUpdate(base::TimeTicks::Now()); |
| + if (RootScrollLayer()->scrollbar_animation_controller()) { |
| + RootScrollLayer()->scrollbar_animation_controller()-> |
| + didPinchGestureUpdate(base::TimeTicks::Now()); |
| + } |
| - m_client->setNeedsCommitOnImplThread(); |
| - m_client->setNeedsRedrawOnImplThread(); |
| - m_client->renewTreePriority(); |
| + client_->SetNeedsCommitOnImplThread(); |
| + client_->SetNeedsRedrawOnImplThread(); |
| + client_->RenewTreePriority(); |
| } |
| -void LayerTreeHostImpl::pinchGestureEnd() |
| -{ |
| - m_pinchGestureActive = false; |
| +void LayerTreeHostImpl::PinchGestureEnd() { |
| + pinch_gesture_active_ = false; |
| - if (rootScrollLayer() && rootScrollLayer()->scrollbar_animation_controller()) |
| - rootScrollLayer()->scrollbar_animation_controller()->didPinchGestureEnd(base::TimeTicks::Now()); |
| + if (RootScrollLayer() && |
| + RootScrollLayer()->scrollbar_animation_controller()) { |
| + RootScrollLayer()->scrollbar_animation_controller()-> |
| + didPinchGestureEnd(base::TimeTicks::Now()); |
| + } |
| - m_client->setNeedsCommitOnImplThread(); |
| + client_->SetNeedsCommitOnImplThread(); |
| } |
| -static void collectScrollDeltas(ScrollAndScaleSet* scrollInfo, LayerImpl* layerImpl) |
| -{ |
| - if (!layerImpl) |
| - return; |
| +static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, |
| + LayerImpl* layer_impl) { |
| + if (!layer_impl) |
| + return; |
| - gfx::Vector2d scrollDelta = gfx::ToFlooredVector2d(layerImpl->scroll_delta()); |
| - if (!scrollDelta.IsZero()) { |
| - LayerTreeHostCommon::ScrollUpdateInfo scroll; |
| - scroll.layerId = layerImpl->id(); |
| - scroll.scrollDelta = scrollDelta; |
| - scrollInfo->scrolls.push_back(scroll); |
| - layerImpl->SetSentScrollDelta(scrollDelta); |
| - } |
| + gfx::Vector2d scroll_delta = |
| + gfx::ToFlooredVector2d(layer_impl->scroll_delta()); |
| + if (!scroll_delta.IsZero()) { |
| + LayerTreeHostCommon::ScrollUpdateInfo scroll; |
| + scroll.layerId = layer_impl->id(); |
| + scroll.scrollDelta = scroll_delta; |
| + scroll_info->scrolls.push_back(scroll); |
| + layer_impl->SetSentScrollDelta(scroll_delta); |
| + } |
| - for (size_t i = 0; i < layerImpl->children().size(); ++i) |
| - collectScrollDeltas(scrollInfo, layerImpl->children()[i]); |
| + for (size_t i = 0; i < layer_impl->children().size(); ++i) |
| + CollectScrollDeltas(scroll_info, layer_impl->children()[i]); |
| } |
| -scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::processScrollDeltas() |
| -{ |
| - scoped_ptr<ScrollAndScaleSet> scrollInfo(new ScrollAndScaleSet()); |
| +scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { |
| + scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); |
| - collectScrollDeltas(scrollInfo.get(), rootLayer()); |
| - scrollInfo->pageScaleDelta = activeTree()->page_scale_delta(); |
| - activeTree()->set_sent_page_scale_delta(scrollInfo->pageScaleDelta); |
| + CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); |
| + scroll_info->pageScaleDelta = active_tree_->page_scale_delta(); |
| + active_tree_->set_sent_page_scale_delta(scroll_info->pageScaleDelta); |
| - return scrollInfo.Pass(); |
| + return scroll_info.Pass(); |
| } |
| -void LayerTreeHostImpl::SetFullRootLayerDamage() |
| -{ |
| - if (rootLayer()) { |
| - RenderSurfaceImpl* renderSurface = rootLayer()->render_surface(); |
| - if (renderSurface) |
| - renderSurface->damage_tracker()->ForceFullDamageNextUpdate(); |
| - } |
| +void LayerTreeHostImpl::SetFullRootLayerDamage() { |
| + if (active_tree_->root_layer()) { |
| + RenderSurfaceImpl* render_surface = |
| + active_tree_->root_layer()->render_surface(); |
| + if (render_surface) |
| + render_surface->damage_tracker()->ForceFullDamageNextUpdate(); |
| + } |
| } |
| -void LayerTreeHostImpl::animatePageScale(base::TimeTicks time) |
| -{ |
| - if (!m_pageScaleAnimation || !rootScrollLayer()) |
| - return; |
| +void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
| + if (!page_scale_animation_ || !RootScrollLayer()) |
| + return; |
| - double monotonicTime = (time - base::TimeTicks()).InSecondsF(); |
| - gfx::Vector2dF scrollTotal = rootScrollLayer()->scroll_offset() + rootScrollLayer()->scroll_delta(); |
| + double monotonic_time = (time - base::TimeTicks()).InSecondsF(); |
| + gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() + |
| + RootScrollLayer()->scroll_delta(); |
| - activeTree()->SetPageScaleDelta(m_pageScaleAnimation->PageScaleFactorAtTime(monotonicTime) / activeTree()->page_scale_factor()); |
| - gfx::Vector2dF nextScroll = m_pageScaleAnimation->ScrollOffsetAtTime(monotonicTime); |
| + active_tree_->SetPageScaleDelta( |
| + page_scale_animation_->PageScaleFactorAtTime(monotonic_time) / |
| + active_tree_->page_scale_factor()); |
| + gfx::Vector2dF next_scroll = |
| + page_scale_animation_->ScrollOffsetAtTime(monotonic_time); |
| - rootScrollLayer()->ScrollBy(nextScroll - scrollTotal); |
| - m_client->setNeedsRedrawOnImplThread(); |
| - |
| - if (m_pageScaleAnimation->IsAnimationCompleteAtTime(monotonicTime)) { |
| - m_pageScaleAnimation.reset(); |
| - m_client->setNeedsCommitOnImplThread(); |
| - m_client->renewTreePriority(); |
| - } |
| + RootScrollLayer()->ScrollBy(next_scroll - scroll_total); |
| + client_->SetNeedsRedrawOnImplThread(); |
| + |
| + if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { |
| + page_scale_animation_.reset(); |
| + client_->SetNeedsCommitOnImplThread(); |
| + client_->RenewTreePriority(); |
| + } |
| } |
| -void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime) |
| -{ |
| - if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty() || !rootLayer()) |
| - return; |
| +void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, |
| + base::Time wall_clock_time) { |
| + if (!settings_.acceleratedAnimationEnabled || |
| + animation_registrar_->active_animation_controllers().empty() || |
| + !active_tree_->root_layer()) |
| + return; |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); |
|
enne (OOO)
2013/03/13 05:22:05
AnimateLayers
danakj
2013/03/13 15:49:11
Done.
|
| - m_lastAnimationTime = wallClockTime; |
| - double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF(); |
| + last_animation_time_ = wall_clock_time; |
| + double monotonic_seconds = (monotonic_time - base::TimeTicks()).InSecondsF(); |
| - AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers(); |
| - for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter) |
| - (*iter).second->Animate(monotonicSeconds); |
| + AnimationRegistrar::AnimationControllerMap copy = |
| + animation_registrar_->active_animation_controllers(); |
| + for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); |
| + iter != copy.end(); |
| + ++iter) |
| + (*iter).second->Animate(monotonic_seconds); |
| - m_client->setNeedsRedrawOnImplThread(); |
| - setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty()); |
| + client_->SetNeedsRedrawOnImplThread(); |
| + SetBackgroundTickingEnabled( |
| + !visible_ && |
| + !animation_registrar_->active_animation_controllers().empty()); |
| } |
| -void LayerTreeHostImpl::updateAnimationState() |
| -{ |
| - if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().empty() || !rootLayer()) |
| - return; |
| - |
| - TRACE_EVENT0("cc", "LayerTreeHostImpl::updateAnimationState"); |
| - scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); |
| - AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers(); |
| - for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter) |
| - (*iter).second->UpdateState(events.get()); |
| - |
| - if (!events->empty()) |
| - m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), m_lastAnimationTime); |
| +void LayerTreeHostImpl::UpdateAnimationState() { |
| + if (!settings_.acceleratedAnimationEnabled || |
| + animation_registrar_->active_animation_controllers().empty() || |
| + !active_tree_->root_layer()) |
| + return; |
| + |
| + TRACE_EVENT0("cc", "LayerTreeHostImpl::updateAnimationState"); |
|
enne (OOO)
2013/03/13 05:22:05
UpdateAnimationState
danakj
2013/03/13 15:49:11
Done.
|
| + scoped_ptr<AnimationEventsVector> events = |
| + make_scoped_ptr(new AnimationEventsVector); |
| + AnimationRegistrar::AnimationControllerMap copy = |
| + animation_registrar_->active_animation_controllers(); |
| + for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); |
| + iter != copy.end(); |
| + ++iter) |
| + (*iter).second->UpdateState(events.get()); |
| + |
| + if (!events->empty()) { |
| + client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass(), |
| + last_animation_time_); |
| + } |
| +} |
| + |
| +base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const { |
| + return base::TimeDelta::FromSeconds(1); |
| +} |
| + |
| +void LayerTreeHostImpl::SendDidLoseOutputSurfaceRecursive(LayerImpl* current) { |
| + DCHECK(current); |
| + current->DidLoseOutputSurface(); |
| + if (current->mask_layer()) |
| + SendDidLoseOutputSurfaceRecursive(current->mask_layer()); |
| + if (current->replica_layer()) |
| + SendDidLoseOutputSurfaceRecursive(current->replica_layer()); |
| + for (size_t i = 0; i < current->children().size(); ++i) |
| + SendDidLoseOutputSurfaceRecursive(current->children()[i]); |
| +} |
| + |
| +void LayerTreeHostImpl::ClearRenderSurfaces() { |
| + active_tree_->ClearRenderSurfaces(); |
| + if (pending_tree_) |
| + pending_tree_->ClearRenderSurfaces(); |
| +} |
| + |
| +std::string LayerTreeHostImpl::LayerTreeAsText() const { |
| + std::string str; |
| + if (active_tree_->root_layer()) { |
| + str = active_tree_->root_layer()->LayerTreeAsText(); |
| + str += "RenderSurfaces:\n"; |
| + DumpRenderSurfaces(&str, 1, active_tree_->root_layer()); |
| + } |
| + return str; |
| } |
| -base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const |
| -{ |
| - return base::TimeDelta::FromSeconds(1); |
| +std::string LayerTreeHostImpl::LayerTreeAsJson() const { |
| + std::string str; |
| + if (active_tree_->root_layer()) { |
| + scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson()); |
| + base::JSONWriter::WriteWithOptions( |
| + json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str); |
| + } |
| + return str; |
| } |
| -void LayerTreeHostImpl::sendDidLoseOutputSurfaceRecursive(LayerImpl* current) |
| -{ |
| - DCHECK(current); |
| - current->DidLoseOutputSurface(); |
| - if (current->mask_layer()) |
| - sendDidLoseOutputSurfaceRecursive(current->mask_layer()); |
| - if (current->replica_layer()) |
| - sendDidLoseOutputSurfaceRecursive(current->replica_layer()); |
| - for (size_t i = 0; i < current->children().size(); ++i) |
| - sendDidLoseOutputSurfaceRecursive(current->children()[i]); |
| +void LayerTreeHostImpl::DumpRenderSurfaces(std::string* str, |
| + int indent, |
| + const LayerImpl* layer) const { |
| + if (layer->render_surface()) |
| + layer->render_surface()->DumpSurface(str, indent); |
| + |
| + for (size_t i = 0; i < layer->children().size(); ++i) |
| + DumpRenderSurfaces(str, indent, layer->children()[i]); |
| } |
| -void LayerTreeHostImpl::clearRenderSurfaces() |
| -{ |
| - activeTree()->ClearRenderSurfaces(); |
| - if (pendingTree()) |
| - pendingTree()->ClearRenderSurfaces(); |
| +int LayerTreeHostImpl::SourceAnimationFrameNumber() const { |
| + return fps_counter_->currentFrameNumber(); |
| } |
| -std::string LayerTreeHostImpl::layerTreeAsText() const |
| -{ |
| - std::string str; |
| - if (rootLayer()) { |
| - str = rootLayer()->LayerTreeAsText(); |
| - str += "RenderSurfaces:\n"; |
| - dumpRenderSurfaces(&str, 1, rootLayer()); |
| - } |
| - return str; |
| +void LayerTreeHostImpl::CollectRenderingStats(RenderingStats* stats) const { |
| + stats->numFramesSentToScreen = fps_counter_->currentFrameNumber(); |
| + stats->droppedFrameCount = fps_counter_->droppedFrameCount(); |
| + stats->numImplThreadScrolls = num_impl_thread_scrolls_; |
| + stats->numMainThreadScrolls = num_main_thread_scrolls_; |
| + stats->numLayersDrawn = cumulative_num_layers_drawn_; |
| + stats->numMissingTiles = cumulative_num_missing_tiles_; |
| + |
| + if (tile_manager_) |
| + tile_manager_->GetRenderingStats(stats); |
| } |
| -std::string LayerTreeHostImpl::layerTreeAsJson() const |
| -{ |
| - std::string str; |
| - if (rootLayer()) { |
| - scoped_ptr<base::Value> json(rootLayer()->LayerTreeAsJson()); |
| - base::JSONWriter::WriteWithOptions( |
| - json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str); |
| - } |
| - return str; |
| -} |
| - |
| -void LayerTreeHostImpl::dumpRenderSurfaces(std::string* str, int indent, const LayerImpl* layer) const |
| -{ |
| - if (layer->render_surface()) |
| - layer->render_surface()->DumpSurface(str, indent); |
| - |
| - for (size_t i = 0; i < layer->children().size(); ++i) |
| - dumpRenderSurfaces(str, indent, layer->children()[i]); |
| -} |
| - |
| -int LayerTreeHostImpl::sourceAnimationFrameNumber() const |
| -{ |
| - return fpsCounter()->currentFrameNumber(); |
| -} |
| - |
| -void LayerTreeHostImpl::renderingStats(RenderingStats* stats) const |
| -{ |
| - stats->numFramesSentToScreen = fpsCounter()->currentFrameNumber(); |
| - stats->droppedFrameCount = fpsCounter()->droppedFrameCount(); |
| - stats->numImplThreadScrolls = m_numImplThreadScrolls; |
| - stats->numMainThreadScrolls = m_numMainThreadScrolls; |
| - stats->numLayersDrawn = m_cumulativeNumLayersDrawn; |
| - stats->numMissingTiles = m_cumulativeNumMissingTiles; |
| - |
| - if (m_tileManager) |
| - m_tileManager->GetRenderingStats(stats); |
| -} |
| - |
| -void LayerTreeHostImpl::sendManagedMemoryStats( |
| - size_t memoryVisibleBytes, |
| - size_t memoryVisibleAndNearbyBytes, |
| - size_t memoryUseBytes) |
| -{ |
| - if (!renderer()) |
| - return; |
| - |
| - // Round the numbers being sent up to the next 8MB, to throttle the rate |
| - // at which we spam the GPU process. |
| - static const size_t roundingStep = 8 * 1024 * 1024; |
| - memoryVisibleBytes = RoundUp(memoryVisibleBytes, roundingStep); |
| - memoryVisibleAndNearbyBytes = RoundUp(memoryVisibleAndNearbyBytes, roundingStep); |
| - memoryUseBytes = RoundUp(memoryUseBytes, roundingStep); |
| - if (m_lastSentMemoryVisibleBytes == memoryVisibleBytes && |
| - m_lastSentMemoryVisibleAndNearbyBytes == memoryVisibleAndNearbyBytes && |
| - m_lastSentMemoryUseBytes == memoryUseBytes) { |
| - return; |
| - } |
| - m_lastSentMemoryVisibleBytes = memoryVisibleBytes; |
| - m_lastSentMemoryVisibleAndNearbyBytes = memoryVisibleAndNearbyBytes; |
| - m_lastSentMemoryUseBytes = memoryUseBytes; |
| +void LayerTreeHostImpl::SendManagedMemoryStats( |
| + size_t memory_visible_bytes, |
| + size_t memory_visible_and_nearby_bytes, |
| + size_t memoryUseBytes) { |
|
enne (OOO)
2013/03/13 05:22:05
memory_use_bytes
danakj
2013/03/13 15:49:11
Done.
|
| + if (!renderer_) |
| + return; |
| - renderer()->SendManagedMemoryStats(m_lastSentMemoryVisibleBytes, |
| - m_lastSentMemoryVisibleAndNearbyBytes, |
| - m_lastSentMemoryUseBytes); |
| + // Round the numbers being sent up to the next 8MB, to throttle the rate |
| + // at which we spam the GPU process. |
| + static const size_t rounding_step = 8 * 1024 * 1024; |
| + memory_visible_bytes = RoundUp(memory_visible_bytes, rounding_step); |
| + memory_visible_and_nearby_bytes = RoundUp(memory_visible_and_nearby_bytes, |
| + rounding_step); |
| + memoryUseBytes = RoundUp(memoryUseBytes, rounding_step); |
| + if (last_sent_memory_visible_bytes_ == memory_visible_bytes && |
| + last_sent_memory_visible_and_nearby_bytes_ == |
| + memory_visible_and_nearby_bytes && |
| + last_sent_memory_use_bytes_ == memoryUseBytes) { |
| + return; |
| + } |
| + last_sent_memory_visible_bytes_ = memory_visible_bytes; |
| + last_sent_memory_visible_and_nearby_bytes_ = memory_visible_and_nearby_bytes; |
| + last_sent_memory_use_bytes_ = memoryUseBytes; |
| + |
| + renderer_->SendManagedMemoryStats(last_sent_memory_visible_bytes_, |
| + last_sent_memory_visible_and_nearby_bytes_, |
| + last_sent_memory_use_bytes_); |
| } |
| -void LayerTreeHostImpl::animateScrollbars(base::TimeTicks time) |
| -{ |
| - animateScrollbarsRecursive(rootLayer(), time); |
| +void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) { |
| + AnimateScrollbarsRecursive(active_tree_->root_layer(), time); |
| } |
| -void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeTicks time) |
| -{ |
| - if (!layer) |
| - return; |
| +void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer, |
| + base::TimeTicks time) { |
| + if (!layer) |
| + return; |
| - ScrollbarAnimationController* scrollbarController = layer->scrollbar_animation_controller(); |
| - if (scrollbarController && scrollbarController->animate(time)) |
| - m_client->setNeedsRedrawOnImplThread(); |
| + ScrollbarAnimationController* scrollbar_controller = |
| + layer->scrollbar_animation_controller(); |
| + if (scrollbar_controller && scrollbar_controller->animate(time)) |
| + client_->SetNeedsRedrawOnImplThread(); |
| - for (size_t i = 0; i < layer->children().size(); ++i) |
| - animateScrollbarsRecursive(layer->children()[i], time); |
| + for (size_t i = 0; i < layer->children().size(); ++i) |
| + AnimateScrollbarsRecursive(layer->children()[i], time); |
| } |
| -void LayerTreeHostImpl::setTreePriority(TreePriority priority) |
| -{ |
| - if (!m_tileManager) |
| - return; |
| +void LayerTreeHostImpl::SetTreePriority(TreePriority priority) { |
| + if (!tile_manager_) |
| + return; |
| - GlobalStateThatImpactsTilePriority new_state(m_tileManager->GlobalState()); |
| - if (new_state.tree_priority == priority) |
| - return; |
| + GlobalStateThatImpactsTilePriority new_state(tile_manager_->GlobalState()); |
| + if (new_state.tree_priority == priority) |
| + return; |
| - new_state.tree_priority = priority; |
| - m_tileManager->SetGlobalState(new_state); |
| + new_state.tree_priority = priority; |
| + tile_manager_->SetGlobalState(new_state); |
| } |
| -void LayerTreeHostImpl::beginNextFrame() |
| -{ |
| - m_currentFrameTime = base::TimeTicks(); |
| +void LayerTreeHostImpl::BeginNextFrame() { |
| + current_frame_time_ = base::TimeTicks(); |
| } |
| -base::TimeTicks LayerTreeHostImpl::currentFrameTime() |
| -{ |
| - if (m_currentFrameTime.is_null()) |
| - m_currentFrameTime = base::TimeTicks::Now(); |
| - return m_currentFrameTime; |
| +base::TimeTicks LayerTreeHostImpl::CurrentFrameTime() { |
| + if (current_frame_time_.is_null()) |
| + current_frame_time_ = base::TimeTicks::Now(); |
| + return current_frame_time_; |
| } |
| -scoped_ptr<base::Value> LayerTreeHostImpl::asValue() const |
| -{ |
| - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| - state->Set("activation_state", activationStateAsValue().release()); |
| - state->Set("frame_state", frameStateAsValue().release()); |
| - return state.PassAs<base::Value>(); |
| +scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const { |
| + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| + state->Set("activation_state", ActivationStateAsValue().release()); |
| + state->Set("frame_state", FrameStateAsValue().release()); |
| + return state.PassAs<base::Value>(); |
| } |
| -scoped_ptr<base::Value> LayerTreeHostImpl::activationStateAsValue() const |
| -{ |
| - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| - state->SetString("lthi_id", StringPrintf("%p", this)); |
| - state->SetBoolean("visible_resources_ready", pendingTree()->AreVisibleResourcesReady()); |
| - state->Set("tile_manager", m_tileManager->BasicStateAsValue().release()); |
| - return state.PassAs<base::Value>(); |
| +scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const { |
| + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| + state->SetString("lthi_id", StringPrintf("%p", this)); |
| + state->SetBoolean("visible_resources_ready", |
| + pending_tree_->AreVisibleResourcesReady()); |
| + state->Set("tile_manager", tile_manager_->BasicStateAsValue().release()); |
| + return state.PassAs<base::Value>(); |
| } |
| -scoped_ptr<base::Value> LayerTreeHostImpl::frameStateAsValue() const |
| -{ |
| - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| - state->SetString("lthi_id", StringPrintf("%p", this)); |
| - state->Set("device_viewport_size", MathUtil::asValue(m_deviceViewportSize).release()); |
| - if (m_tileManager) |
| - state->Set("tiles", m_tileManager->AllTilesAsValue().release()); |
| - state->Set("active_tree", activeTree()->AsValue().release()); |
| - return state.PassAs<base::Value>(); |
| +scoped_ptr<base::Value> LayerTreeHostImpl::FrameStateAsValue() const { |
| + scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| + state->SetString("lthi_id", StringPrintf("%p", this)); |
| + state->Set("device_viewport_size", |
| + MathUtil::asValue(device_viewport_size_).release()); |
| + if (tile_manager_) |
| + state->Set("tiles", tile_manager_->AllTilesAsValue().release()); |
| + state->Set("active_tree", active_tree_->AsValue().release()); |
| + return state.PassAs<base::Value>(); |
| } |
| // static |
| -LayerImpl* LayerTreeHostImpl::getNonCompositedContentLayerRecursive(LayerImpl* layer) |
| -{ |
| - if (!layer) |
| - return NULL; |
| - |
| - if (layer->DrawsContent()) |
| - return layer; |
| - |
| - for (LayerImpl::LayerList::const_iterator it = layer->children().begin(); |
| - it != layer->children().end(); ++it) { |
| - LayerImpl* nccr = getNonCompositedContentLayerRecursive(*it); |
| - if (nccr) |
| - return nccr; |
| - } |
| - |
| +LayerImpl* LayerTreeHostImpl::GetNonCompositedContentLayerRecursive( |
| + LayerImpl* layer) { |
| + if (!layer) |
| return NULL; |
| + |
| + if (layer->DrawsContent()) |
| + return layer; |
| + |
| + for (LayerImpl::LayerList::const_iterator it = layer->children().begin(); |
| + it != layer->children().end(); ++it) { |
| + LayerImpl* nccr = GetNonCompositedContentLayerRecursive(*it); |
| + if (nccr) |
| + return nccr; |
| + } |
| + |
| + return NULL; |
| } |
| -skia::RefPtr<SkPicture> LayerTreeHostImpl::capturePicture() |
| -{ |
| - LayerTreeImpl* tree = pendingTree() ? pendingTree() : activeTree(); |
| - LayerImpl* layer = getNonCompositedContentLayerRecursive(tree->RootLayer()); |
| - return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>(); |
| +skia::RefPtr<SkPicture> LayerTreeHostImpl::CapturePicture() { |
| + LayerTreeImpl* tree = |
| + pending_tree_ ? pending_tree_.get() : active_tree_.get(); |
| + LayerImpl* layer = GetNonCompositedContentLayerRecursive(tree->root_layer()); |
| + return layer ? layer->GetPicture() : skia::RefPtr<SkPicture>(); |
| } |
| -void LayerTreeHostImpl::setDebugState(const LayerTreeDebugState& debugState) |
| -{ |
| - if (m_debugState.continuousPainting != debugState.continuousPainting) |
| - m_paintTimeCounter->ClearHistory(); |
| +void LayerTreeHostImpl::SetDebugState(const LayerTreeDebugState& debug_state) { |
| + if (debug_state_.continuousPainting != debug_state.continuousPainting) |
| + paint_time_counter_->ClearHistory(); |
| - m_debugState = debugState; |
| + debug_state_ = debug_state; |
| - if (m_tileManager) |
| - m_tileManager->SetRecordRenderingStats(m_debugState.recordRenderingStats()); |
| + if (tile_manager_) |
| + tile_manager_->SetRecordRenderingStats(debug_state_.recordRenderingStats()); |
| } |
| -void LayerTreeHostImpl::savePaintTime(const base::TimeDelta& totalPaintTime, int commitNumber) |
| -{ |
| - DCHECK(m_debugState.continuousPainting); |
| - m_paintTimeCounter->SavePaintTime(totalPaintTime, commitNumber); |
| +void LayerTreeHostImpl::SavePaintTime(const base::TimeDelta& total_paint_time, |
| + int commit_number) { |
| + DCHECK(debug_state_.continuousPainting); |
| + paint_time_counter_->SavePaintTime(total_paint_time, commit_number); |
| } |
| } // namespace cc |