Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Unified Diff: cc/CCLayerTreeHostImpl.cpp

Issue 11122003: [cc] Rename all cc/ filenames to Chromium style (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/CCLayerTreeHostImpl.h ('k') | cc/CCMathUtil.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/CCLayerTreeHostImpl.cpp
diff --git a/cc/CCLayerTreeHostImpl.cpp b/cc/CCLayerTreeHostImpl.cpp
deleted file mode 100644
index bc50697ad25a5f7b5d0e779fd95870c62ba3aba1..0000000000000000000000000000000000000000
--- a/cc/CCLayerTreeHostImpl.cpp
+++ /dev/null
@@ -1,1462 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "config.h"
-
-#include "CCLayerTreeHostImpl.h"
-
-#include "base/basictypes.h"
-#include "CCAppendQuadsData.h"
-#include "CCDamageTracker.h"
-#include "CCDebugRectHistory.h"
-#include "CCDelayBasedTimeSource.h"
-#include "CCFontAtlas.h"
-#include "CCFrameRateCounter.h"
-#include "CCHeadsUpDisplayLayerImpl.h"
-#include "CCLayerIterator.h"
-#include "CCLayerTreeHost.h"
-#include "CCLayerTreeHostCommon.h"
-#include "CCMathUtil.h"
-#include "CCOverdrawMetrics.h"
-#include "CCPageScaleAnimation.h"
-#include "CCPrioritizedTextureManager.h"
-#include "CCRenderPassDrawQuad.h"
-#include "CCRendererGL.h"
-#include "CCRendererSoftware.h"
-#include "CCRenderingStats.h"
-#include "CCScrollbarAnimationController.h"
-#include "CCScrollbarLayerImpl.h"
-#include "CCSettings.h"
-#include "CCSingleThreadProxy.h"
-#include "TextureUploader.h"
-#include "TraceEvent.h"
-#include <wtf/CurrentTime.h>
-#include <algorithm>
-
-using WebKit::WebTransformationMatrix;
-
-namespace {
-
-void didVisibilityChange(cc::CCLayerTreeHostImpl* id, bool visible)
-{
- if (visible) {
- TRACE_EVENT_ASYNC_BEGIN1("webkit", "CCLayerTreeHostImpl::setVisible", id, "CCLayerTreeHostImpl", id);
- return;
- }
-
- TRACE_EVENT_ASYNC_END0("webkit", "CCLayerTreeHostImpl::setVisible", id);
-}
-
-} // namespace
-
-namespace cc {
-
-CCPinchZoomViewport::CCPinchZoomViewport()
- : m_pageScaleFactor(1)
- , m_pageScaleDelta(1)
- , m_sentPageScaleDelta(1)
- , m_minPageScaleFactor(0)
- , m_maxPageScaleFactor(0)
-{
-}
-
-float CCPinchZoomViewport::totalPageScaleFactor() const
-{
- return m_pageScaleFactor * m_pageScaleDelta;
-}
-
-void CCPinchZoomViewport::setPageScaleDelta(float delta)
-{
- // Clamp to the current min/max limits.
- float totalPageScaleFactor = m_pageScaleFactor * delta;
- if (m_minPageScaleFactor && totalPageScaleFactor < m_minPageScaleFactor)
- delta = m_minPageScaleFactor / m_pageScaleFactor;
- else if (m_maxPageScaleFactor && totalPageScaleFactor > m_maxPageScaleFactor)
- delta = m_maxPageScaleFactor / m_pageScaleFactor;
-
- if (delta == m_pageScaleDelta)
- return;
-
- m_pageScaleDelta = delta;
-}
-
-bool CCPinchZoomViewport::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
-{
- ASSERT(pageScaleFactor);
-
- if (m_sentPageScaleDelta == 1 && pageScaleFactor == m_pageScaleFactor && minPageScaleFactor == m_minPageScaleFactor && maxPageScaleFactor == m_maxPageScaleFactor)
- return false;
-
- m_minPageScaleFactor = minPageScaleFactor;
- m_maxPageScaleFactor = maxPageScaleFactor;
-
- m_pageScaleFactor = pageScaleFactor;
- return true;
-}
-
-FloatRect CCPinchZoomViewport::bounds() const
-{
- FloatSize scaledViewportSize = m_layoutViewportSize;
- scaledViewportSize.scale(1 / totalPageScaleFactor());
-
- FloatRect bounds(FloatPoint(0, 0), scaledViewportSize);
- bounds.setLocation(m_pinchViewportScrollDelta);
-
- return bounds;
-}
-
-FloatSize CCPinchZoomViewport::applyScroll(FloatSize& delta)
-{
- FloatSize overflow;
- FloatRect pinchedBounds = bounds();
-
- pinchedBounds.move(delta);
- if (pinchedBounds.x() < 0) {
- overflow.setWidth(pinchedBounds.x());
- pinchedBounds.setX(0);
- }
-
- if (pinchedBounds.y() < 0) {
- overflow.setHeight(pinchedBounds.y());
- pinchedBounds.setY(0);
- }
-
- if (pinchedBounds.maxX() > m_layoutViewportSize.width()) {
- overflow.setWidth(
- pinchedBounds.maxX() - m_layoutViewportSize.width());
- pinchedBounds.move(
- m_layoutViewportSize.width() - pinchedBounds.maxX(), 0);
- }
-
- if (pinchedBounds.maxY() > m_layoutViewportSize.height()) {
- overflow.setHeight(
- pinchedBounds.maxY() - m_layoutViewportSize.height());
- pinchedBounds.move(
- 0, m_layoutViewportSize.height() - pinchedBounds.maxY());
- }
- m_pinchViewportScrollDelta = pinchedBounds.location();
-
- return overflow;
-}
-
-WebTransformationMatrix CCPinchZoomViewport::implTransform() const
-{
- WebTransformationMatrix transform;
- transform.scale(m_pageScaleDelta);
-
- // If the pinch state is applied in the impl, then push it to the
- // impl transform, otherwise the scale is handled by WebCore.
- if (CCSettings::pageScalePinchZoomEnabled()) {
- transform.scale(m_pageScaleFactor);
- transform.translate(-m_pinchViewportScrollDelta.x(),
- -m_pinchViewportScrollDelta.y());
- }
-
- return transform;
-}
-
-class CCLayerTreeHostImplTimeSourceAdapter : public CCTimeSourceClient {
-public:
- static PassOwnPtr<CCLayerTreeHostImplTimeSourceAdapter> create(CCLayerTreeHostImpl* layerTreeHostImpl, PassRefPtr<CCDelayBasedTimeSource> timeSource)
- {
- return adoptPtr(new CCLayerTreeHostImplTimeSourceAdapter(layerTreeHostImpl, timeSource));
- }
- virtual ~CCLayerTreeHostImplTimeSourceAdapter()
- {
- m_timeSource->setClient(0);
- m_timeSource->setActive(false);
- }
-
- virtual void onTimerTick() OVERRIDE
- {
- // FIXME: We require that animate be called on the impl thread. This
- // avoids asserts in single threaded mode. Ideally background ticking
- // would be handled by the proxy/scheduler and this could be removed.
- DebugScopedSetImplThread impl;
-
- m_layerTreeHostImpl->animate(monotonicallyIncreasingTime(), currentTime());
- }
-
- void setActive(bool active)
- {
- if (active != m_timeSource->active())
- m_timeSource->setActive(active);
- }
-
-private:
- CCLayerTreeHostImplTimeSourceAdapter(CCLayerTreeHostImpl* layerTreeHostImpl, PassRefPtr<CCDelayBasedTimeSource> timeSource)
- : m_layerTreeHostImpl(layerTreeHostImpl)
- , m_timeSource(timeSource)
- {
- m_timeSource->setClient(this);
- }
-
- CCLayerTreeHostImpl* m_layerTreeHostImpl;
- RefPtr<CCDelayBasedTimeSource> m_timeSource;
-
- DISALLOW_COPY_AND_ASSIGN(CCLayerTreeHostImplTimeSourceAdapter);
-};
-
-CCLayerTreeHostImpl::FrameData::FrameData()
-{
-}
-
-CCLayerTreeHostImpl::FrameData::~FrameData()
-{
-}
-
-scoped_ptr<CCLayerTreeHostImpl> CCLayerTreeHostImpl::create(const CCLayerTreeSettings& settings, CCLayerTreeHostImplClient* client)
-{
- return make_scoped_ptr(new CCLayerTreeHostImpl(settings, client));
-}
-
-CCLayerTreeHostImpl::CCLayerTreeHostImpl(const CCLayerTreeSettings& settings, CCLayerTreeHostImplClient* client)
- : m_client(client)
- , m_sourceFrameNumber(-1)
- , m_rootScrollLayerImpl(0)
- , m_currentlyScrollingLayerImpl(0)
- , m_hudLayerImpl(0)
- , m_scrollingLayerIdFromPreviousTree(-1)
- , m_scrollDeltaIsInScreenSpace(false)
- , m_settings(settings)
- , m_deviceScaleFactor(1)
- , m_visible(true)
- , m_contentsTexturesPurged(false)
- , m_memoryAllocationLimitBytes(CCPrioritizedTextureManager::defaultMemoryAllocationLimit())
- , m_backgroundColor(0)
- , m_hasTransparentBackground(false)
- , m_needsAnimateLayers(false)
- , m_pinchGestureActive(false)
- , m_fpsCounter(CCFrameRateCounter::create())
- , m_debugRectHistory(CCDebugRectHistory::create())
- , m_numImplThreadScrolls(0)
- , m_numMainThreadScrolls(0)
-{
- ASSERT(CCProxy::isImplThread());
- didVisibilityChange(this, m_visible);
-}
-
-CCLayerTreeHostImpl::~CCLayerTreeHostImpl()
-{
- ASSERT(CCProxy::isImplThread());
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::~CCLayerTreeHostImpl()");
-
- if (m_rootLayerImpl)
- clearRenderSurfaces();
-}
-
-void CCLayerTreeHostImpl::beginCommit()
-{
-}
-
-void CCLayerTreeHostImpl::commitComplete()
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::commitComplete");
- // Recompute max scroll position; must be after layer content bounds are
- // updated.
- updateMaxScrollPosition();
-}
-
-bool CCLayerTreeHostImpl::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 (!m_rootLayerImpl) {
- TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw no root layer");
- return false;
- }
- if (deviceViewportSize().isEmpty()) {
- TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw empty viewport");
- return false;
- }
- if (!m_renderer) {
- TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw no renderer");
- return false;
- }
- if (m_contentsTexturesPurged) {
- TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw contents textures purged");
- return false;
- }
- return true;
-}
-
-CCGraphicsContext* CCLayerTreeHostImpl::context() const
-{
- return m_context.get();
-}
-
-void CCLayerTreeHostImpl::animate(double monotonicTime, double wallClockTime)
-{
- animatePageScale(monotonicTime);
- animateLayers(monotonicTime, wallClockTime);
- animateScrollbars(monotonicTime);
-}
-
-void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTime, double duration)
-{
- if (!m_rootScrollLayerImpl)
- return;
-
- IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta());
- scrollTotal.scale(m_pinchZoomViewport.pageScaleDelta());
- float scaleTotal = m_pinchZoomViewport.totalPageScaleFactor();
- IntSize scaledContentSize = contentSize();
- scaledContentSize.scale(m_pinchZoomViewport.pageScaleDelta());
-
- m_pageScaleAnimation = CCPageScaleAnimation::create(scrollTotal, scaleTotal, m_deviceViewportSize, scaledContentSize, startTime);
-
- if (anchorPoint) {
- IntSize windowAnchor(targetPosition);
- windowAnchor.scale(scaleTotal / pageScale);
- windowAnchor -= scrollTotal;
- m_pageScaleAnimation->zoomWithAnchor(windowAnchor, pageScale, duration);
- } else
- m_pageScaleAnimation->zoomTo(targetPosition, pageScale, duration);
-
- m_client->setNeedsRedrawOnImplThread();
- m_client->setNeedsCommitOnImplThread();
-}
-
-void CCLayerTreeHostImpl::scheduleAnimation()
-{
- m_client->setNeedsRedrawOnImplThread();
-}
-
-void CCLayerTreeHostImpl::trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& 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) {
- CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
- CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
- ASSERT(renderSurface);
- renderSurface->damageTracker()->updateDamageTrackingState(renderSurface->layerList(), renderSurfaceLayer->id(), renderSurface->surfacePropertyChangedOnlyFromDescendant(), renderSurface->contentRect(), renderSurfaceLayer->maskLayer(), renderSurfaceLayer->filters());
- }
-}
-
-void CCLayerTreeHostImpl::updateRootScrollLayerImplTransform()
-{
- if (m_rootScrollLayerImpl) {
- m_rootScrollLayerImpl->setImplTransform(implTransform());
- }
-}
-
-void CCLayerTreeHostImpl::calculateRenderSurfaceLayerList(CCLayerList& renderSurfaceLayerList)
-{
- ASSERT(renderSurfaceLayerList.empty());
- ASSERT(m_rootLayerImpl);
- ASSERT(m_renderer); // For maxTextureSize.
-
- {
- updateRootScrollLayerImplTransform();
-
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::calcDrawEtc");
- CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), deviceViewportSize(), m_deviceScaleFactor, &m_layerSorter, rendererCapabilities().maxTextureSize, renderSurfaceLayerList);
-
- trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
- }
-}
-
-void CCLayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<CCRenderPass> renderPass)
-{
- CCRenderPass* pass = renderPass.get();
- renderPasses.push_back(pass);
- renderPassesById.set(pass->id(), renderPass.Pass());
-}
-
-bool CCLayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
-{
- ASSERT(frame.renderPasses.empty());
-
- calculateRenderSurfaceLayerList(*frame.renderSurfaceLayerList);
-
- TRACE_EVENT1("cc", "CCLayerTreeHostImpl::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) {
- CCLayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceIndex];
- renderSurfaceLayer->renderSurface()->appendRenderPasses(frame);
- }
-
- bool recordMetricsForFrame = true; // FIXME: In the future, disable this when about:tracing is off.
- CCOcclusionTrackerImpl occlusionTracker(m_rootLayerImpl->renderSurface()->contentRect(), recordMetricsForFrame);
- occlusionTracker.setMinimumTrackingSize(m_settings.minimumOcclusionTrackingSize);
-
- if (settings().showOccludingRects)
- occlusionTracker.setOccludingScreenSpaceRectsContainer(&frame.occludingScreenSpaceRects);
-
- // Add quads to the Render passes in FrontToBack order to allow for testing occlusion and performing culling during the tree walk.
- typedef CCLayerIterator<CCLayerImpl, std::vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
-
- // 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;
-
- CCLayerIteratorType end = CCLayerIteratorType::end(frame.renderSurfaceLayerList);
- for (CCLayerIteratorType it = CCLayerIteratorType::begin(frame.renderSurfaceLayerList); it != end; ++it) {
- CCRenderPass::Id targetRenderPassId = it.targetRenderSurfaceLayer()->renderSurface()->renderPassId();
- CCRenderPass* targetRenderPass = frame.renderPassesById.get(targetRenderPassId);
-
- occlusionTracker.enterLayer(it);
-
- CCAppendQuadsData appendQuadsData(targetRenderPass->id());
-
- if (it.representsContributingRenderSurface()) {
- CCRenderPass::Id contributingRenderPassId = it->renderSurface()->renderPassId();
- CCRenderPass* contributingRenderPass = frame.renderPassesById.get(contributingRenderPassId);
- targetRenderPass->appendQuadsForRenderSurfaceLayer(*it, contributingRenderPass, &occlusionTracker, appendQuadsData);
- } else if (it.representsItself() && !it->visibleContentRect().isEmpty()) {
- bool hasOcclusionFromOutsideTargetSurface;
- if (occlusionTracker.occluded(*it, it->visibleContentRect(), &hasOcclusionFromOutsideTargetSurface))
- appendQuadsData.hadOcclusionFromOutsideTargetSurface |= hasOcclusionFromOutsideTargetSurface;
- else {
- it->willDraw(m_resourceProvider.get());
- frame.willDrawLayers.push_back(*it);
-
- if (it->hasContributingDelegatedRenderPasses()) {
- CCRenderPass::Id contributingRenderPassId = it->firstContributingRenderPassId();
- while (frame.renderPassesById.contains(contributingRenderPassId)) {
- CCRenderPass* renderPass = frame.renderPassesById.get(contributingRenderPassId);
-
- CCAppendQuadsData appendQuadsData(renderPass->id());
- renderPass->appendQuadsForLayer(*it, &occlusionTracker, appendQuadsData);
-
- contributingRenderPassId = it->nextContributingRenderPassId(contributingRenderPassId);
- }
- }
-
- targetRenderPass->appendQuadsForLayer(*it, &occlusionTracker, appendQuadsData);
- }
- }
-
- if (appendQuadsData.hadOcclusionFromOutsideTargetSurface)
- targetRenderPass->setHasOcclusionFromOutsideTargetSurface(true);
-
- if (appendQuadsData.hadMissingTiles) {
- bool layerHasAnimatingTransform = it->screenSpaceTransformIsAnimating() || it->drawTransformIsAnimating();
- if (layerHasAnimatingTransform || CCSettings::jankInsteadOfCheckerboard())
- drawFrame = false;
- }
-
- occlusionTracker.leaveLayer(it);
- }
-
-#if !ASSERT_DISABLED
- for (size_t i = 0; i < frame.renderPasses.size(); ++i) {
- for (size_t j = 0; j < frame.renderPasses[i]->quadList().size(); ++j)
- ASSERT(frame.renderPasses[i]->quadList()[j]->sharedQuadStateId() >= 0);
- ASSERT(frame.renderPassesById.contains(frame.renderPasses[i]->id()));
- }
-#endif
-
- if (!m_hasTransparentBackground) {
- frame.renderPasses.back()->setHasTransparentBackground(false);
- frame.renderPasses.back()->appendQuadsToFillScreen(m_rootLayerImpl.get(), m_backgroundColor, occlusionTracker);
- }
-
- if (drawFrame)
- occlusionTracker.overdrawMetrics().recordMetrics(this);
-
- removeRenderPasses(CullRenderPassesWithNoQuads(), frame);
- m_renderer->decideRenderPassAllocationsForFrame(frame.renderPasses);
- removeRenderPasses(CullRenderPassesWithCachedTextures(*m_renderer), frame);
-
- return drawFrame;
-}
-
-void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double monotonicTime, double wallClockTime, CCAnimationEventsVector* events, bool& didAnimate, bool& needsAnimateLayers)
-{
- bool subtreeNeedsAnimateLayers = false;
-
- CCLayerAnimationController* currentController = current->layerAnimationController();
-
- bool hadActiveAnimation = currentController->hasActiveAnimation();
- currentController->animate(monotonicTime, events);
- bool startedAnimation = events->size() > 0;
-
- // We animated if we either ticked a running animation, or started a new animation.
- if (hadActiveAnimation || startedAnimation)
- didAnimate = true;
-
- // If the current controller still has an active animation, we must continue animating layers.
- if (currentController->hasActiveAnimation())
- subtreeNeedsAnimateLayers = true;
-
- for (size_t i = 0; i < current->children().size(); ++i) {
- bool childNeedsAnimateLayers = false;
- animateLayersRecursive(current->children()[i], monotonicTime, wallClockTime, events, didAnimate, childNeedsAnimateLayers);
- if (childNeedsAnimateLayers)
- subtreeNeedsAnimateLayers = true;
- }
-
- needsAnimateLayers = subtreeNeedsAnimateLayers;
-}
-
-void CCLayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled)
-{
- // Lazily create the timeSource adapter so that we can vary the interval for testing.
- if (!m_timeSourceClientAdapter)
- m_timeSourceClientAdapter = CCLayerTreeHostImplTimeSourceAdapter::create(this, CCDelayBasedTimeSource::create(lowFrequencyAnimationInterval(), CCProxy::currentThread()));
-
- m_timeSourceClientAdapter->setActive(enabled);
-}
-
-IntSize CCLayerTreeHostImpl::contentSize() const
-{
- // TODO(aelias): Hardcoding the first child here is weird. Think of
- // a cleaner way to get the contentBounds on the Impl side.
- if (!m_rootScrollLayerImpl || m_rootScrollLayerImpl->children().isEmpty())
- return IntSize();
- return m_rootScrollLayerImpl->children()[0]->contentBounds();
-}
-
-static inline CCRenderPass* findRenderPassById(CCRenderPass::Id renderPassId, const CCLayerTreeHostImpl::FrameData& frame)
-{
- CCRenderPassIdHashMap::const_iterator it = frame.renderPassesById.find(renderPassId);
- ASSERT(it != frame.renderPassesById.end());
- return it->second;
-}
-
-static void removeRenderPassesRecursive(CCRenderPass::Id removeRenderPassId, CCLayerTreeHostImpl::FrameData& frame)
-{
- CCRenderPass* removeRenderPass = findRenderPassById(removeRenderPassId, frame);
- CCRenderPassList& renderPasses = frame.renderPasses;
- CCRenderPassList::iterator toRemove = std::find(renderPasses.begin(), renderPasses.end(), removeRenderPass);
-
- // The pass was already removed by another quad - probably the original, and we are the replica.
- if (toRemove == renderPasses.end())
- return;
-
- const CCRenderPass* removedPass = *toRemove;
- frame.renderPasses.erase(toRemove);
-
- // Now follow up for all RenderPass quads and remove their RenderPasses recursively.
- const CCQuadList& quadList = removedPass->quadList();
- CCQuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
- for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
- CCDrawQuad* currentQuad = (*quadListIterator);
- if (currentQuad->material() != CCDrawQuad::RenderPass)
- continue;
-
- CCRenderPass::Id nextRemoveRenderPassId = CCRenderPassDrawQuad::materialCast(currentQuad)->renderPassId();
- removeRenderPassesRecursive(nextRemoveRenderPassId, frame);
- }
-}
-
-bool CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass(const CCRenderPassDrawQuad& quad, const FrameData&) const
-{
- return quad.contentsChangedSinceLastFrame().isEmpty() && m_renderer.haveCachedResourcesForRenderPassId(quad.renderPassId());
-}
-
-bool CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(const CCRenderPassDrawQuad& quad, const FrameData& frame) const
-{
- const CCRenderPass* renderPass = findRenderPassById(quad.renderPassId(), frame);
- const CCRenderPassList& renderPasses = frame.renderPasses;
- CCRenderPassList::const_iterator foundPass = std::find(renderPasses.begin(), renderPasses.end(), renderPass);
-
- bool renderPassAlreadyRemoved = foundPass == renderPasses.end();
- if (renderPassAlreadyRemoved)
- return false;
-
- // If any quad or RenderPass draws into this RenderPass, then keep it.
- const CCQuadList& quadList = (*foundPass)->quadList();
- for (CCQuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
- CCDrawQuad* currentQuad = *quadListIterator;
-
- if (currentQuad->material() != CCDrawQuad::RenderPass)
- return false;
-
- const CCRenderPass* contributingPass = findRenderPassById(CCRenderPassDrawQuad::materialCast(currentQuad)->renderPassId(), frame);
- CCRenderPassList::const_iterator foundContributingPass = std::find(renderPasses.begin(), renderPasses.end(), contributingPass);
- if (foundContributingPass != renderPasses.end())
- return false;
- }
- return true;
-}
-
-// Defined for linking tests.
-template void CCLayerTreeHostImpl::removeRenderPasses<CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures>(CullRenderPassesWithCachedTextures, FrameData&);
-template void CCLayerTreeHostImpl::removeRenderPasses<CCLayerTreeHostImpl::CullRenderPassesWithNoQuads>(CullRenderPassesWithNoQuads, FrameData&);
-
-// static
-template<typename RenderPassCuller>
-void CCLayerTreeHostImpl::removeRenderPasses(RenderPassCuller culler, FrameData& frame)
-{
- for (size_t it = culler.renderPassListBegin(frame.renderPasses); it != culler.renderPassListEnd(frame.renderPasses); it = culler.renderPassListNext(it)) {
- const CCRenderPass* currentPass = frame.renderPasses[it];
- const CCQuadList& quadList = currentPass->quadList();
- CCQuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin();
-
- for (; quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) {
- CCDrawQuad* currentQuad = *quadListIterator;
-
- if (currentQuad->material() != CCDrawQuad::RenderPass)
- continue;
-
- CCRenderPassDrawQuad* renderPassQuad = static_cast<CCRenderPassDrawQuad*>(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->renderPassId(), frame);
- it = frame.renderPasses.size() - positionFromEnd;
- ASSERT(it >= 0);
- }
- }
-}
-
-bool CCLayerTreeHostImpl::prepareToDraw(FrameData& frame)
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::prepareToDraw");
- ASSERT(canDraw());
-
- frame.renderSurfaceLayerList = &m_renderSurfaceLayerList;
- frame.renderPasses.clear();
- frame.renderPassesById.clear();
- frame.renderSurfaceLayerList->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 CCLayerTreeHostImpl::releaseContentsTextures()
-{
- if (m_contentsTexturesPurged)
- return;
- m_client->releaseContentsTexturesOnImplThread();
- setContentsTexturesPurged();
- m_client->setNeedsCommitOnImplThread();
- m_client->onCanDrawStateChanged(canDraw());
-}
-
-void CCLayerTreeHostImpl::setMemoryAllocationLimitBytes(size_t bytes)
-{
- if (m_memoryAllocationLimitBytes == bytes)
- return;
- m_memoryAllocationLimitBytes = bytes;
-
- ASSERT(bytes);
- m_client->setNeedsCommitOnImplThread();
-}
-
-void CCLayerTreeHostImpl::onVSyncParametersChanged(double monotonicTimebase, double intervalInSeconds)
-{
- m_client->onVSyncParametersChanged(monotonicTimebase, intervalInSeconds);
-}
-
-void CCLayerTreeHostImpl::drawLayers(const FrameData& frame)
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::drawLayers");
- ASSERT(canDraw());
- ASSERT(!frame.renderPasses.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->markBeginningOfFrame(currentTime());
-
- if (m_settings.showDebugRects())
- m_debugRectHistory->saveDebugRectsForCurrentFrame(m_rootLayerImpl.get(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, settings());
-
- // 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_hudLayerImpl)
- m_hudLayerImpl->updateHudTexture(m_resourceProvider.get());
-
- m_renderer->drawFrame(frame.renderPasses, frame.renderPassesById);
-
- // Once a RenderPass has been drawn, its damage should be cleared in
- // case the RenderPass will be reused next frame.
- for (unsigned int i = 0; i < frame.renderPasses.size(); i++)
- frame.renderPasses[i]->setDamageRect(FloatRect());
-
- // 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]->renderSurface()->damageTracker()->didDrawDamagedArea();
- m_rootLayerImpl->resetAllChangeTrackingForSubtree();
-}
-
-void CCLayerTreeHostImpl::didDrawAllLayers(const FrameData& frame)
-{
- for (size_t i = 0; i < frame.willDrawLayers.size(); ++i)
- frame.willDrawLayers[i]->didDraw(m_resourceProvider.get());
-
- // Once all layers have been drawn, pending texture uploads should no
- // longer block future uploads.
- m_resourceProvider->textureUploader()->markPendingUploadsAsNonBlocking();
-}
-
-void CCLayerTreeHostImpl::finishAllRendering()
-{
- if (m_renderer)
- m_renderer->finish();
-}
-
-bool CCLayerTreeHostImpl::isContextLost()
-{
- return m_renderer && m_renderer->isContextLost();
-}
-
-const RendererCapabilities& CCLayerTreeHostImpl::rendererCapabilities() const
-{
- return m_renderer->capabilities();
-}
-
-bool CCLayerTreeHostImpl::swapBuffers()
-{
- ASSERT(m_renderer);
-
- m_fpsCounter->markEndOfFrame();
- return m_renderer->swapBuffers();
-}
-
-const IntSize& CCLayerTreeHostImpl::deviceViewportSize() const
-{
- return m_deviceViewportSize;
-}
-
-const CCLayerTreeSettings& CCLayerTreeHostImpl::settings() const
-{
- return m_settings;
-}
-
-void CCLayerTreeHostImpl::didLoseContext()
-{
- m_client->didLoseContextOnImplThread();
-}
-
-void CCLayerTreeHostImpl::onSwapBuffersComplete()
-{
- m_client->onSwapBuffersCompleteOnImplThread();
-}
-
-void CCLayerTreeHostImpl::readback(void* pixels, const IntRect& rect)
-{
- ASSERT(m_renderer);
- m_renderer->getFramebufferPixels(pixels, rect);
-}
-
-static CCLayerImpl* findRootScrollLayer(CCLayerImpl* layer)
-{
- if (!layer)
- return 0;
-
- if (layer->scrollable())
- return layer;
-
- for (size_t i = 0; i < layer->children().size(); ++i) {
- CCLayerImpl* found = findRootScrollLayer(layer->children()[i]);
- if (found)
- return found;
- }
-
- return 0;
-}
-
-// 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 CCLayerImpl* findScrollLayerForContentLayer(CCLayerImpl* layerImpl)
-{
- if (!layerImpl)
- return 0;
-
- if (layerImpl->scrollable())
- return layerImpl;
-
- if (layerImpl->drawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable())
- return layerImpl->parent();
-
- return 0;
-}
-
-void CCLayerTreeHostImpl::setRootLayer(scoped_ptr<CCLayerImpl> layer)
-{
- m_rootLayerImpl = layer.Pass();
- m_rootScrollLayerImpl = findRootScrollLayer(m_rootLayerImpl.get());
- m_currentlyScrollingLayerImpl = 0;
-
- if (m_rootLayerImpl && m_scrollingLayerIdFromPreviousTree != -1)
- m_currentlyScrollingLayerImpl = CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayerImpl.get(), m_scrollingLayerIdFromPreviousTree);
-
- m_scrollingLayerIdFromPreviousTree = -1;
-
- m_client->onCanDrawStateChanged(canDraw());
-}
-
-scoped_ptr<CCLayerImpl> CCLayerTreeHostImpl::detachLayerTree()
-{
- // Clear all data structures that have direct references to the layer tree.
- m_scrollingLayerIdFromPreviousTree = m_currentlyScrollingLayerImpl ? m_currentlyScrollingLayerImpl->id() : -1;
- m_currentlyScrollingLayerImpl = 0;
- m_renderSurfaceLayerList.clear();
-
- return m_rootLayerImpl.Pass();
-}
-
-void CCLayerTreeHostImpl::setVisible(bool visible)
-{
- ASSERT(CCProxy::isImplThread());
-
- if (m_visible == visible)
- return;
- m_visible = visible;
- didVisibilityChange(this, m_visible);
-
- if (!m_renderer)
- return;
-
- m_renderer->setVisible(visible);
-
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
-}
-
-bool CCLayerTreeHostImpl::initializeRenderer(scoped_ptr<CCGraphicsContext> context)
-{
- // 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 (m_rootLayerImpl) {
- clearRenderSurfaces();
- sendDidLoseContextRecursive(m_rootLayerImpl.get());
- }
- // Note: order is important here.
- m_renderer.clear();
- m_resourceProvider.clear();
- m_context.reset();
-
- if (!context->bindToClient(this))
- return false;
-
- OwnPtr<CCResourceProvider> resourceProvider = CCResourceProvider::create(context.get());
- if (!resourceProvider)
- return false;
-
- if (context->context3D())
- m_renderer = CCRendererGL::create(this, resourceProvider.get());
- else if (context->softwareDevice())
- m_renderer = CCRendererSoftware::create(this, resourceProvider.get(), context->softwareDevice());
- if (!m_renderer)
- return false;
-
- m_resourceProvider = resourceProvider.release();
- m_context = context.Pass();
-
- if (!m_visible)
- m_renderer->setVisible(m_visible);
-
- m_client->onCanDrawStateChanged(canDraw());
-
- return true;
-}
-
-void CCLayerTreeHostImpl::setContentsTexturesPurged()
-{
- m_contentsTexturesPurged = true;
- m_client->onCanDrawStateChanged(canDraw());
-}
-
-void CCLayerTreeHostImpl::resetContentsTexturesPurged()
-{
- m_contentsTexturesPurged = false;
- m_client->onCanDrawStateChanged(canDraw());
-}
-
-void CCLayerTreeHostImpl::setViewportSize(const IntSize& layoutViewportSize, const IntSize& deviceViewportSize)
-{
- if (layoutViewportSize == m_layoutViewportSize && deviceViewportSize == m_deviceViewportSize)
- return;
-
- m_layoutViewportSize = layoutViewportSize;
- m_deviceViewportSize = deviceViewportSize;
-
- m_pinchZoomViewport.setLayoutViewportSize(FloatSize(layoutViewportSize));
-
- updateMaxScrollPosition();
-
- if (m_renderer)
- m_renderer->viewportChanged();
-
- m_client->onCanDrawStateChanged(canDraw());
-}
-
-static void adjustScrollsForPageScaleChange(CCLayerImpl* layerImpl, float pageScaleChange)
-{
- if (!layerImpl)
- return;
-
- if (layerImpl->scrollable()) {
- // We need to convert impl-side scroll deltas to pageScale space.
- FloatSize scrollDelta = layerImpl->scrollDelta();
- scrollDelta.scale(pageScaleChange);
- layerImpl->setScrollDelta(scrollDelta);
- }
-
- for (size_t i = 0; i < layerImpl->children().size(); ++i)
- adjustScrollsForPageScaleChange(layerImpl->children()[i], pageScaleChange);
-}
-
-void CCLayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor)
-{
- if (deviceScaleFactor == m_deviceScaleFactor)
- return;
- m_deviceScaleFactor = deviceScaleFactor;
-
- updateMaxScrollPosition();
-}
-
-float CCLayerTreeHostImpl::pageScaleFactor() const
-{
- return m_pinchZoomViewport.pageScaleFactor();
-}
-
-void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor)
-{
- if (!pageScaleFactor)
- return;
-
- float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.pageScaleFactor();
- m_pinchZoomViewport.setPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor);
-
- if (!CCSettings::pageScalePinchZoomEnabled()) {
- if (pageScaleChange != 1)
- adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange);
- }
-
- // Clamp delta to limits and refresh display matrix.
- setPageScaleDelta(m_pinchZoomViewport.pageScaleDelta() / m_pinchZoomViewport.sentPageScaleDelta());
- m_pinchZoomViewport.setSentPageScaleDelta(1);
-}
-
-void CCLayerTreeHostImpl::setPageScaleDelta(float delta)
-{
- m_pinchZoomViewport.setPageScaleDelta(delta);
-
- updateMaxScrollPosition();
-}
-
-void CCLayerTreeHostImpl::updateMaxScrollPosition()
-{
- if (!m_rootScrollLayerImpl || !m_rootScrollLayerImpl->children().size())
- return;
-
- FloatSize viewBounds = m_deviceViewportSize;
- if (CCLayerImpl* clipLayer = m_rootScrollLayerImpl->parent()) {
- // Compensate for non-overlay scrollbars.
- if (clipLayer->masksToBounds()) {
- viewBounds = clipLayer->bounds();
- viewBounds.scale(m_deviceScaleFactor);
- }
- }
-
- IntSize contentBounds = contentSize();
- if (CCSettings::pageScalePinchZoomEnabled()) {
- // Pinch with pageScale scrolls entirely in layout space. contentSize
- // returns the bounds including the page scale factor, so calculate the
- // pre page-scale layout size here.
- float pageScaleFactor = m_pinchZoomViewport.pageScaleFactor();
- contentBounds.setWidth(contentBounds.width() / pageScaleFactor);
- contentBounds.setHeight(contentBounds.height() / pageScaleFactor);
- } else {
- viewBounds.scale(1 / m_pinchZoomViewport.pageScaleDelta());
- }
-
- IntSize maxScroll = contentBounds - expandedIntSize(viewBounds);
- maxScroll.scale(1 / m_deviceScaleFactor);
-
- // The viewport may be larger than the contents in some cases, such as
- // having a vertical scrollbar but no horizontal overflow.
- maxScroll.clampNegativeToZero();
-
- m_rootScrollLayerImpl->setMaxScrollPosition(maxScroll);
-}
-
-void CCLayerTreeHostImpl::setNeedsRedraw()
-{
- m_client->setNeedsRedrawOnImplThread();
-}
-
-bool CCLayerTreeHostImpl::ensureRenderSurfaceLayerList()
-{
- if (!m_rootLayerImpl)
- return false;
- if (!m_renderer)
- return false;
-
- // We need both a non-empty render surface layer list and a root render
- // surface to be able to iterate over the visible layers.
- if (m_renderSurfaceLayerList.size() && m_rootLayerImpl->renderSurface())
- return true;
-
- // If we are called after setRootLayer() but before prepareToDraw(), we need
- // to recalculate the visible layers. This prevents being unable to scroll
- // during part of a commit.
- m_renderSurfaceLayerList.clear();
- calculateRenderSurfaceLayerList(m_renderSurfaceLayerList);
-
- return m_renderSurfaceLayerList.size();
-}
-
-CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type)
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::scrollBegin");
-
- ASSERT(!m_currentlyScrollingLayerImpl);
- clearCurrentlyScrollingLayer();
-
- if (!ensureRenderSurfaceLayerList())
- return ScrollIgnored;
-
- IntPoint deviceViewportPoint = viewportPoint;
- deviceViewportPoint.scale(m_deviceScaleFactor, m_deviceScaleFactor);
-
- // First find out which layer was hit from the saved list of visible layers
- // in the most recent frame.
- CCLayerImpl* layerImpl = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(viewportPoint, m_renderSurfaceLayerList);
-
- // Walk up the hierarchy and look for a scrollable layer.
- CCLayerImpl* 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++;
- return ScrollOnMainThread;
- }
-
- CCLayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl);
- if (!scrollLayerImpl)
- continue;
-
- ScrollStatus status = scrollLayerImpl->tryScroll(viewportPoint, type);
-
- // If any layer wants to divert the scroll event to the main thread, abort.
- if (status == ScrollOnMainThread) {
- m_numMainThreadScrolls++;
- return ScrollOnMainThread;
- }
-
- if (status == ScrollStarted && !potentiallyScrollingLayerImpl)
- potentiallyScrollingLayerImpl = scrollLayerImpl;
- }
-
- if (potentiallyScrollingLayerImpl) {
- m_currentlyScrollingLayerImpl = potentiallyScrollingLayerImpl;
- // Gesture events need to be transformed from screen coordinates to local layer coordinates
- // so that the scrolling contents exactly follow the user's finger. In contrast, wheel
- // events are already in local layer coordinates so we can just apply them directly.
- m_scrollDeltaIsInScreenSpace = (type == Gesture);
- m_numImplThreadScrolls++;
- return ScrollStarted;
- }
- return ScrollIgnored;
-}
-
-static FloatSize scrollLayerWithScreenSpaceDelta(CCPinchZoomViewport* viewport, CCLayerImpl& layerImpl, const FloatPoint& screenSpacePoint, const FloatSize& screenSpaceDelta)
-{
- // Layers with non-invertible screen space transforms should not have passed the scroll hit
- // test in the first place.
- ASSERT(layerImpl.screenSpaceTransform().isInvertible());
- WebTransformationMatrix inverseScreenSpaceTransform = layerImpl.screenSpaceTransform().inverse();
-
- // First project the scroll start and end points to local layer space to find the scroll delta
- // in layer coordinates.
- bool startClipped, endClipped;
- FloatPoint screenSpaceEndPoint = screenSpacePoint + screenSpaceDelta;
- FloatPoint localStartPoint = CCMathUtil::projectPoint(inverseScreenSpaceTransform, screenSpacePoint, startClipped);
- FloatPoint localEndPoint = CCMathUtil::projectPoint(inverseScreenSpaceTransform, screenSpaceEndPoint, endClipped);
-
- // In general scroll point coordinates should not get clipped.
- ASSERT(!startClipped);
- ASSERT(!endClipped);
- if (startClipped || endClipped)
- return FloatSize();
-
- // Apply the scroll delta.
- FloatSize previousDelta(layerImpl.scrollDelta());
- FloatSize unscrolled = layerImpl.scrollBy(localEndPoint - localStartPoint);
-
- if (viewport)
- viewport->applyScroll(unscrolled);
-
- // Calculate the applied scroll delta in screen space coordinates.
- FloatPoint actualLocalEndPoint = localStartPoint + layerImpl.scrollDelta() - previousDelta;
- FloatPoint actualScreenSpaceEndPoint = CCMathUtil::mapPoint(layerImpl.screenSpaceTransform(), actualLocalEndPoint, endClipped);
- ASSERT(!endClipped);
- if (endClipped)
- return FloatSize();
- return actualScreenSpaceEndPoint - screenSpacePoint;
-}
-
-static FloatSize scrollLayerWithLocalDelta(CCLayerImpl& layerImpl, const FloatSize& localDelta)
-{
- FloatSize previousDelta(layerImpl.scrollDelta());
- layerImpl.scrollBy(localDelta);
- return layerImpl.scrollDelta() - previousDelta;
-}
-
-void CCLayerTreeHostImpl::scrollBy(const IntPoint& viewportPoint, const IntSize& scrollDelta)
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::scrollBy");
- if (!m_currentlyScrollingLayerImpl)
- return;
-
- FloatSize pendingDelta(scrollDelta);
-
- pendingDelta.scale(m_deviceScaleFactor);
-
- for (CCLayerImpl* layerImpl = m_currentlyScrollingLayerImpl; layerImpl; layerImpl = layerImpl->parent()) {
- if (!layerImpl->scrollable())
- continue;
-
- CCPinchZoomViewport* viewport = layerImpl == m_rootScrollLayerImpl ? &m_pinchZoomViewport : 0;
- FloatSize appliedDelta;
- if (m_scrollDeltaIsInScreenSpace)
- appliedDelta = scrollLayerWithScreenSpaceDelta(viewport, *layerImpl, 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.diagonalLengthSquared() < moveThresholdSquared)
- continue;
-
- // 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 (CCMathUtil::smallestAngleBetweenVectors(appliedDelta, pendingDelta) < angleThreshold) {
- pendingDelta = FloatSize();
- break;
- }
-
- // Allow further movement only on an axis perpendicular to the direction in which the layer
- // moved.
- FloatSize perpendicularAxis(-appliedDelta.height(), appliedDelta.width());
- pendingDelta = CCMathUtil::projectVector(pendingDelta, perpendicularAxis);
-
- if (flooredIntSize(pendingDelta).isZero())
- break;
- }
-
- if (!scrollDelta.isZero() && flooredIntSize(pendingDelta).isEmpty()) {
- m_client->setNeedsCommitOnImplThread();
- m_client->setNeedsRedrawOnImplThread();
- }
-}
-
-void CCLayerTreeHostImpl::clearCurrentlyScrollingLayer()
-{
- m_currentlyScrollingLayerImpl = 0;
- m_scrollingLayerIdFromPreviousTree = -1;
-}
-
-void CCLayerTreeHostImpl::scrollEnd()
-{
- clearCurrentlyScrollingLayer();
-}
-
-void CCLayerTreeHostImpl::pinchGestureBegin()
-{
- m_pinchGestureActive = true;
- m_previousPinchAnchor = IntPoint();
-
- if (m_rootScrollLayerImpl && m_rootScrollLayerImpl->scrollbarAnimationController())
- m_rootScrollLayerImpl->scrollbarAnimationController()->didPinchGestureBegin();
-}
-
-void CCLayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta,
- const IntPoint& anchor)
-{
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::pinchGestureUpdate");
-
- if (!m_rootScrollLayerImpl)
- return;
-
- if (m_previousPinchAnchor == IntPoint::zero())
- m_previousPinchAnchor = anchor;
-
- // Keep the center-of-pinch anchor specified by (x, y) in a stable
- // position over the course of the magnify.
- float pageScaleDelta = m_pinchZoomViewport.pageScaleDelta();
- FloatPoint previousScaleAnchor(m_previousPinchAnchor.x() / pageScaleDelta,
- m_previousPinchAnchor.y() / pageScaleDelta);
- setPageScaleDelta(pageScaleDelta * magnifyDelta);
- pageScaleDelta = m_pinchZoomViewport.pageScaleDelta();
- FloatPoint newScaleAnchor(anchor.x() / pageScaleDelta, anchor.y() / pageScaleDelta);
- FloatSize move = previousScaleAnchor - newScaleAnchor;
-
- m_previousPinchAnchor = anchor;
-
- if (CCSettings::pageScalePinchZoomEnabled()) {
- // Compute the application of the delta with respect to the current page zoom of the page.
- move.scale(1 / (m_pinchZoomViewport.pageScaleFactor() * m_deviceScaleFactor));
- }
-
- FloatSize scrollOverflow = CCSettings::pageScalePinchZoomEnabled() ? m_pinchZoomViewport.applyScroll(move) : move;
- m_rootScrollLayerImpl->scrollBy(roundedIntSize(scrollOverflow));
-
- if (m_rootScrollLayerImpl->scrollbarAnimationController())
- m_rootScrollLayerImpl->scrollbarAnimationController()->didPinchGestureUpdate();
-
- m_client->setNeedsCommitOnImplThread();
- m_client->setNeedsRedrawOnImplThread();
-}
-
-void CCLayerTreeHostImpl::pinchGestureEnd()
-{
- m_pinchGestureActive = false;
-
- if (m_rootScrollLayerImpl && m_rootScrollLayerImpl->scrollbarAnimationController())
- m_rootScrollLayerImpl->scrollbarAnimationController()->didPinchGestureEnd();
-
- m_client->setNeedsCommitOnImplThread();
-}
-
-void CCLayerTreeHostImpl::computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo)
-{
- float pageScale = m_pageScaleAnimation->finalPageScale();
- IntSize scrollOffset = m_pageScaleAnimation->finalScrollOffset();
- scrollOffset.scale(m_pinchZoomViewport.pageScaleFactor() / pageScale);
- makeScrollAndScaleSet(scrollInfo, scrollOffset, pageScale);
-}
-
-void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo)
-{
- if (!m_rootScrollLayerImpl)
- return;
-
- // Only send fake scroll/zoom deltas if we're pinch zooming out by a
- // significant amount. This also ensures only one fake delta set will be
- // sent.
- const float pinchZoomOutSensitivity = 0.95f;
- if (m_pinchZoomViewport.pageScaleDelta() > pinchZoomOutSensitivity)
- return;
-
- // Compute where the scroll offset/page scale would be if fully pinch-zoomed
- // out from the anchor point.
- IntSize scrollBegin = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta());
- scrollBegin.scale(m_pinchZoomViewport.pageScaleDelta());
- float scaleBegin = m_pinchZoomViewport.totalPageScaleFactor();
- float pageScaleDeltaToSend = m_pinchZoomViewport.minPageScaleFactor() / m_pinchZoomViewport.pageScaleFactor();
- FloatSize scaledContentsSize = contentSize();
- scaledContentsSize.scale(pageScaleDeltaToSend);
-
- FloatSize anchor = toSize(m_previousPinchAnchor);
- FloatSize scrollEnd = scrollBegin + anchor;
- scrollEnd.scale(m_pinchZoomViewport.minPageScaleFactor() / scaleBegin);
- scrollEnd -= anchor;
- scrollEnd = scrollEnd.shrunkTo(roundedIntSize(scaledContentsSize - m_deviceViewportSize)).expandedTo(FloatSize(0, 0));
- scrollEnd.scale(1 / pageScaleDeltaToSend);
- scrollEnd.scale(m_deviceScaleFactor);
-
- makeScrollAndScaleSet(scrollInfo, roundedIntSize(scrollEnd), m_pinchZoomViewport.minPageScaleFactor());
-}
-
-void CCLayerTreeHostImpl::makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale)
-{
- if (!m_rootScrollLayerImpl)
- return;
-
- CCLayerTreeHostCommon::ScrollUpdateInfo scroll;
- scroll.layerId = m_rootScrollLayerImpl->id();
- scroll.scrollDelta = scrollOffset - toSize(m_rootScrollLayerImpl->scrollPosition());
- scrollInfo->scrolls.append(scroll);
- m_rootScrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);
- scrollInfo->pageScaleDelta = pageScale / m_pinchZoomViewport.pageScaleFactor();
- m_pinchZoomViewport.setSentPageScaleDelta(scrollInfo->pageScaleDelta);
-}
-
-static void collectScrollDeltas(CCScrollAndScaleSet* scrollInfo, CCLayerImpl* layerImpl)
-{
- if (!layerImpl)
- return;
-
- if (!layerImpl->scrollDelta().isZero()) {
- IntSize scrollDelta = flooredIntSize(layerImpl->scrollDelta());
- CCLayerTreeHostCommon::ScrollUpdateInfo scroll;
- scroll.layerId = layerImpl->id();
- scroll.scrollDelta = scrollDelta;
- scrollInfo->scrolls.append(scroll);
- layerImpl->setSentScrollDelta(scrollDelta);
- }
-
- for (size_t i = 0; i < layerImpl->children().size(); ++i)
- collectScrollDeltas(scrollInfo, layerImpl->children()[i]);
-}
-
-scoped_ptr<CCScrollAndScaleSet> CCLayerTreeHostImpl::processScrollDeltas()
-{
- scoped_ptr<CCScrollAndScaleSet> scrollInfo(new CCScrollAndScaleSet());
-
- if (m_pinchGestureActive || m_pageScaleAnimation) {
- scrollInfo->pageScaleDelta = 1;
- m_pinchZoomViewport.setSentPageScaleDelta(1);
- // FIXME(aelias): Make these painting optimizations compatible with
- // compositor-side scaling.
- if (!CCSettings::pageScalePinchZoomEnabled()) {
- if (m_pinchGestureActive)
- computePinchZoomDeltas(scrollInfo.get());
- else if (m_pageScaleAnimation.get())
- computeDoubleTapZoomDeltas(scrollInfo.get());
- }
- return scrollInfo.Pass();
- }
-
- collectScrollDeltas(scrollInfo.get(), m_rootLayerImpl.get());
- scrollInfo->pageScaleDelta = m_pinchZoomViewport.pageScaleDelta();
- m_pinchZoomViewport.setSentPageScaleDelta(scrollInfo->pageScaleDelta);
-
- return scrollInfo.Pass();
-}
-
-WebTransformationMatrix CCLayerTreeHostImpl::implTransform() const
-{
- return m_pinchZoomViewport.implTransform();
-}
-
-void CCLayerTreeHostImpl::setFullRootLayerDamage()
-{
- if (m_rootLayerImpl) {
- CCRenderSurface* renderSurface = m_rootLayerImpl->renderSurface();
- if (renderSurface)
- renderSurface->damageTracker()->forceFullDamageNextUpdate();
- }
-}
-
-void CCLayerTreeHostImpl::animatePageScale(double monotonicTime)
-{
- if (!m_pageScaleAnimation || !m_rootScrollLayerImpl)
- return;
-
- IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta());
-
- setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pinchZoomViewport.pageScaleFactor());
- IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime);
- nextScroll.scale(1 / m_pinchZoomViewport.pageScaleDelta());
- m_rootScrollLayerImpl->scrollBy(nextScroll - scrollTotal);
- m_client->setNeedsRedrawOnImplThread();
-
- if (m_pageScaleAnimation->isAnimationCompleteAtTime(monotonicTime)) {
- m_pageScaleAnimation.clear();
- m_client->setNeedsCommitOnImplThread();
- }
-}
-
-void CCLayerTreeHostImpl::animateLayers(double monotonicTime, double wallClockTime)
-{
- if (!CCSettings::acceleratedAnimationEnabled() || !m_needsAnimateLayers || !m_rootLayerImpl)
- return;
-
- TRACE_EVENT0("cc", "CCLayerTreeHostImpl::animateLayers");
-
- scoped_ptr<CCAnimationEventsVector> events(make_scoped_ptr(new CCAnimationEventsVector));
-
- bool didAnimate = false;
- animateLayersRecursive(m_rootLayerImpl.get(), monotonicTime, wallClockTime, events.get(), didAnimate, m_needsAnimateLayers);
-
- if (!events->empty())
- m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
-
- if (didAnimate)
- m_client->setNeedsRedrawOnImplThread();
-
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
-}
-
-base::TimeDelta CCLayerTreeHostImpl::lowFrequencyAnimationInterval() const
-{
- return base::TimeDelta::FromSeconds(1);
-}
-
-void CCLayerTreeHostImpl::sendDidLoseContextRecursive(CCLayerImpl* current)
-{
- ASSERT(current);
- current->didLoseContext();
- if (current->maskLayer())
- sendDidLoseContextRecursive(current->maskLayer());
- if (current->replicaLayer())
- sendDidLoseContextRecursive(current->replicaLayer());
- for (size_t i = 0; i < current->children().size(); ++i)
- sendDidLoseContextRecursive(current->children()[i]);
-}
-
-static void clearRenderSurfacesOnCCLayerImplRecursive(CCLayerImpl* current)
-{
- ASSERT(current);
- for (size_t i = 0; i < current->children().size(); ++i)
- clearRenderSurfacesOnCCLayerImplRecursive(current->children()[i]);
- current->clearRenderSurface();
-}
-
-void CCLayerTreeHostImpl::clearRenderSurfaces()
-{
- clearRenderSurfacesOnCCLayerImplRecursive(m_rootLayerImpl.get());
- m_renderSurfaceLayerList.clear();
-}
-
-std::string CCLayerTreeHostImpl::layerTreeAsText() const
-{
- std::string str;
- if (m_rootLayerImpl) {
- str = m_rootLayerImpl->layerTreeAsText();
- str += "RenderSurfaces:\n";
- dumpRenderSurfaces(&str, 1, m_rootLayerImpl.get());
- }
- return str;
-}
-
-void CCLayerTreeHostImpl::dumpRenderSurfaces(std::string* str, int indent, const CCLayerImpl* layer) const
-{
- if (layer->renderSurface())
- layer->renderSurface()->dumpSurface(str, indent);
-
- for (size_t i = 0; i < layer->children().size(); ++i)
- dumpRenderSurfaces(str, indent, layer->children()[i]);
-}
-
-int CCLayerTreeHostImpl::sourceAnimationFrameNumber() const
-{
- return fpsCounter()->currentFrameNumber();
-}
-
-void CCLayerTreeHostImpl::renderingStats(CCRenderingStats* stats) const
-{
- stats->numFramesSentToScreen = fpsCounter()->currentFrameNumber();
- stats->droppedFrameCount = fpsCounter()->droppedFrameCount();
- stats->numImplThreadScrolls = m_numImplThreadScrolls;
- stats->numMainThreadScrolls = m_numMainThreadScrolls;
-}
-
-void CCLayerTreeHostImpl::animateScrollbars(double monotonicTime)
-{
- animateScrollbarsRecursive(m_rootLayerImpl.get(), monotonicTime);
-}
-
-void CCLayerTreeHostImpl::animateScrollbarsRecursive(CCLayerImpl* layer, double monotonicTime)
-{
- if (!layer)
- return;
-
- CCScrollbarAnimationController* scrollbarController = layer->scrollbarAnimationController();
- if (scrollbarController && scrollbarController->animate(monotonicTime))
- m_client->setNeedsRedrawOnImplThread();
-
- for (size_t i = 0; i < layer->children().size(); ++i)
- animateScrollbarsRecursive(layer->children()[i], monotonicTime);
-}
-
-} // namespace cc
« no previous file with comments | « cc/CCLayerTreeHostImpl.h ('k') | cc/CCMathUtil.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698