| Index: cc/CCThreadProxy.cpp
|
| diff --git a/cc/CCThreadProxy.cpp b/cc/CCThreadProxy.cpp
|
| deleted file mode 100644
|
| index 1d3f2d3f09d468c23ad4a03c1dc7c23eacc3588b..0000000000000000000000000000000000000000
|
| --- a/cc/CCThreadProxy.cpp
|
| +++ /dev/null
|
| @@ -1,957 +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 "CCThreadProxy.h"
|
| -
|
| -#include "CCDelayBasedTimeSource.h"
|
| -#include "CCDrawQuad.h"
|
| -#include "CCFrameRateController.h"
|
| -#include "CCGraphicsContext.h"
|
| -#include "CCInputHandler.h"
|
| -#include "CCLayerTreeHost.h"
|
| -#include "CCScheduler.h"
|
| -#include "CCScopedThreadProxy.h"
|
| -#include "CCThreadTask.h"
|
| -#include "TraceEvent.h"
|
| -#include <public/WebSharedGraphicsContext3D.h>
|
| -#include <wtf/CurrentTime.h>
|
| -
|
| -using namespace WTF;
|
| -using WebKit::WebSharedGraphicsContext3D;
|
| -
|
| -namespace {
|
| -
|
| -// Measured in seconds.
|
| -const double contextRecreationTickRate = 0.03;
|
| -
|
| -} // namespace
|
| -
|
| -namespace cc {
|
| -
|
| -scoped_ptr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
|
| -{
|
| - return make_scoped_ptr(new CCThreadProxy(layerTreeHost)).PassAs<CCProxy>();
|
| -}
|
| -
|
| -CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
|
| - : m_animateRequested(false)
|
| - , m_commitRequested(false)
|
| - , m_commitRequestSentToImplThread(false)
|
| - , m_forcedCommitRequested(false)
|
| - , m_layerTreeHost(layerTreeHost)
|
| - , m_rendererInitialized(false)
|
| - , m_started(false)
|
| - , m_texturesAcquired(true)
|
| - , m_inCompositeAndReadback(false)
|
| - , m_mainThreadProxy(CCScopedThreadProxy::create(CCProxy::mainThread()))
|
| - , m_beginFrameCompletionEventOnImplThread(0)
|
| - , m_readbackRequestOnImplThread(0)
|
| - , m_commitCompletionEventOnImplThread(0)
|
| - , m_textureAcquisitionCompletionEventOnImplThread(0)
|
| - , m_resetContentsTexturesPurgedAfterCommitOnImplThread(false)
|
| - , m_nextFrameIsNewlyCommittedFrameOnImplThread(false)
|
| - , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled)
|
| - , m_totalCommitCount(0)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::CCThreadProxy");
|
| - ASSERT(isMainThread());
|
| -}
|
| -
|
| -CCThreadProxy::~CCThreadProxy()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::~CCThreadProxy");
|
| - ASSERT(isMainThread());
|
| - ASSERT(!m_started);
|
| -}
|
| -
|
| -bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadPRoxy::compositeAndReadback");
|
| - ASSERT(isMainThread());
|
| - ASSERT(m_layerTreeHost);
|
| -
|
| - if (!m_layerTreeHost->initializeRendererIfNeeded()) {
|
| - TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized");
|
| - return false;
|
| - }
|
| -
|
| -
|
| - // Perform a synchronous commit.
|
| - {
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent beginFrameCompletion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceBeginFrameOnImplThread, &beginFrameCompletion));
|
| - beginFrameCompletion.wait();
|
| - }
|
| - m_inCompositeAndReadback = true;
|
| - beginFrame();
|
| - m_inCompositeAndReadback = false;
|
| -
|
| - // Perform a synchronous readback.
|
| - ReadbackRequest request;
|
| - request.rect = rect;
|
| - request.pixels = pixels;
|
| - {
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestReadbackOnImplThread, &request));
|
| - request.completion.wait();
|
| - }
|
| - return request.success;
|
| -}
|
| -
|
| -void CCThreadProxy::requestReadbackOnImplThread(ReadbackRequest* request)
|
| -{
|
| - ASSERT(CCProxy::isImplThread());
|
| - ASSERT(!m_readbackRequestOnImplThread);
|
| - if (!m_layerTreeHostImpl.get()) {
|
| - request->success = false;
|
| - request->completion.signal();
|
| - return;
|
| - }
|
| -
|
| - m_readbackRequestOnImplThread = request;
|
| - m_schedulerOnImplThread->setNeedsRedraw();
|
| - m_schedulerOnImplThread->setNeedsForcedRedraw();
|
| -}
|
| -
|
| -void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
|
| -{
|
| - ASSERT(CCProxy::isMainThread());
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, duration));
|
| -}
|
| -
|
| -void CCThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double duration)
|
| -{
|
| - ASSERT(CCProxy::isImplThread());
|
| - if (m_layerTreeHostImpl.get())
|
| - m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
|
| -}
|
| -
|
| -void CCThreadProxy::finishAllRendering()
|
| -{
|
| - ASSERT(CCProxy::isMainThread());
|
| -
|
| - // Make sure all GL drawing is finished on the impl thread.
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::finishAllRenderingOnImplThread, &completion));
|
| - completion.wait();
|
| -}
|
| -
|
| -bool CCThreadProxy::isStarted() const
|
| -{
|
| - ASSERT(CCProxy::isMainThread());
|
| - return m_started;
|
| -}
|
| -
|
| -bool CCThreadProxy::initializeContext()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::initializeContext");
|
| - scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
|
| - if (!context.get())
|
| - return false;
|
| -
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeContextOnImplThread,
|
| - context.release()));
|
| - return true;
|
| -}
|
| -
|
| -void CCThreadProxy::setSurfaceReady()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReady");
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setSurfaceReadyOnImplThread));
|
| -}
|
| -
|
| -void CCThreadProxy::setSurfaceReadyOnImplThread()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReadyOnImplThread");
|
| - m_schedulerOnImplThread->setCanBeginFrame(true);
|
| -}
|
| -
|
| -void CCThreadProxy::setVisible(bool visible)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setVisible");
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setVisibleOnImplThread, &completion, visible));
|
| - completion.wait();
|
| -}
|
| -
|
| -void CCThreadProxy::setVisibleOnImplThread(CCCompletionEvent* completion, bool visible)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setVisibleOnImplThread");
|
| - m_layerTreeHostImpl->setVisible(visible);
|
| - m_schedulerOnImplThread->setVisible(visible);
|
| - completion->signal();
|
| -}
|
| -
|
| -bool CCThreadProxy::initializeRenderer()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::initializeRenderer");
|
| - // Make a blocking call to initializeRendererOnImplThread. The results of that call
|
| - // are pushed into the initializeSucceeded and capabilities local variables.
|
| - CCCompletionEvent completion;
|
| - bool initializeSucceeded = false;
|
| - RendererCapabilities capabilities;
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeRendererOnImplThread,
|
| - &completion,
|
| - &initializeSucceeded,
|
| - &capabilities));
|
| - completion.wait();
|
| -
|
| - if (initializeSucceeded) {
|
| - m_rendererInitialized = true;
|
| - m_RendererCapabilitiesMainThreadCopy = capabilities;
|
| - }
|
| - return initializeSucceeded;
|
| -}
|
| -
|
| -bool CCThreadProxy::recreateContext()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::recreateContext");
|
| - ASSERT(isMainThread());
|
| -
|
| - // Try to create the context.
|
| - scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext();
|
| - if (!context.get())
|
| - return false;
|
| - if (m_layerTreeHost->needsSharedContext())
|
| - if (!WebSharedGraphicsContext3D::createCompositorThreadContext())
|
| - return false;
|
| -
|
| - // Make a blocking call to recreateContextOnImplThread. The results of that
|
| - // call are pushed into the recreateSucceeded and capabilities local
|
| - // variables.
|
| - CCCompletionEvent completion;
|
| - bool recreateSucceeded = false;
|
| - RendererCapabilities capabilities;
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::recreateContextOnImplThread,
|
| - &completion,
|
| - context.release(),
|
| - &recreateSucceeded,
|
| - &capabilities));
|
| - completion.wait();
|
| -
|
| - if (recreateSucceeded)
|
| - m_RendererCapabilitiesMainThreadCopy = capabilities;
|
| - return recreateSucceeded;
|
| -}
|
| -
|
| -void CCThreadProxy::renderingStats(CCRenderingStats* stats)
|
| -{
|
| - ASSERT(isMainThread());
|
| -
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::renderingStatsOnImplThread,
|
| - &completion,
|
| - stats));
|
| - stats->totalCommitTimeInSeconds = m_totalCommitTime.InSecondsF();
|
| - stats->totalCommitCount = m_totalCommitCount;
|
| -
|
| - completion.wait();
|
| -}
|
| -
|
| -const RendererCapabilities& CCThreadProxy::rendererCapabilities() const
|
| -{
|
| - ASSERT(m_rendererInitialized);
|
| - return m_RendererCapabilitiesMainThreadCopy;
|
| -}
|
| -
|
| -void CCThreadProxy::loseContext()
|
| -{
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::didLoseContextOnImplThread));
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsAnimate()
|
| -{
|
| - ASSERT(isMainThread());
|
| - if (m_animateRequested)
|
| - return;
|
| -
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsAnimate");
|
| - m_animateRequested = true;
|
| -
|
| - if (m_commitRequestSentToImplThread)
|
| - return;
|
| - m_commitRequestSentToImplThread = true;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsCommit()
|
| -{
|
| - ASSERT(isMainThread());
|
| - if (m_commitRequested)
|
| - return;
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommit");
|
| - m_commitRequested = true;
|
| -
|
| - if (m_commitRequestSentToImplThread)
|
| - return;
|
| - m_commitRequestSentToImplThread = true;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
|
| -}
|
| -
|
| -void CCThreadProxy::didLoseContextOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread");
|
| - m_schedulerOnImplThread->didLoseContext();
|
| -}
|
| -
|
| -void CCThreadProxy::onSwapBuffersCompleteOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::onSwapBuffersCompleteOnImplThread");
|
| - m_schedulerOnImplThread->didSwapBuffersComplete();
|
| - m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didCompleteSwapBuffers));
|
| -}
|
| -
|
| -void CCThreadProxy::onVSyncParametersChanged(double monotonicTimebase, double intervalInSeconds)
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT2("cc", "CCThreadProxy::onVSyncParametersChanged", "monotonicTimebase", monotonicTimebase, "intervalInSeconds", intervalInSeconds);
|
| - base::TimeTicks timebase = base::TimeTicks::FromInternalValue(monotonicTimebase * base::Time::kMicrosecondsPerSecond);
|
| - base::TimeDelta interval = base::TimeDelta::FromMicroseconds(intervalInSeconds * base::Time::kMicrosecondsPerSecond);
|
| - m_schedulerOnImplThread->setTimebaseAndInterval(timebase, interval);
|
| -}
|
| -
|
| -void CCThreadProxy::onCanDrawStateChanged(bool canDraw)
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT1("cc", "CCThreadProxy::onCanDrawStateChanged", "canDraw", canDraw);
|
| - m_schedulerOnImplThread->setCanDraw(canDraw);
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsCommitOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommitOnImplThread");
|
| - m_schedulerOnImplThread->setNeedsCommit();
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsForcedCommitOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsForcedCommitOnImplThread");
|
| - m_schedulerOnImplThread->setNeedsCommit();
|
| - m_schedulerOnImplThread->setNeedsForcedCommit();
|
| -}
|
| -
|
| -void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector> events, double wallClockTime)
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::postAnimationEventsToMainThreadOnImplThread");
|
| - m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events.release(), wallClockTime));
|
| -}
|
| -
|
| -void CCThreadProxy::releaseContentsTexturesOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| -
|
| - m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider());
|
| -
|
| - // Make sure that we get a new commit before drawing again.
|
| - m_resetContentsTexturesPurgedAfterCommitOnImplThread = false;
|
| - // The texture upload queue may reference textures that were just purged, clear
|
| - // them from the queue.
|
| - if (m_currentTextureUpdateControllerOnImplThread.get() && m_layerTreeHost->evictedContentsTexturesBackingsExist())
|
| - m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedResources();
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsRedraw()
|
| -{
|
| - ASSERT(isMainThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedraw");
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setFullRootLayerDamageOnImplThread));
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnImplThread));
|
| -}
|
| -
|
| -bool CCThreadProxy::commitRequested() const
|
| -{
|
| - ASSERT(isMainThread());
|
| - return m_commitRequested;
|
| -}
|
| -
|
| -void CCThreadProxy::setNeedsRedrawOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedrawOnImplThread");
|
| - m_schedulerOnImplThread->setNeedsRedraw();
|
| -}
|
| -
|
| -void CCThreadProxy::start()
|
| -{
|
| - ASSERT(isMainThread());
|
| - ASSERT(CCProxy::implThread());
|
| - // Create LayerTreeHostImpl.
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - scoped_ptr<CCInputHandler> handler = m_layerTreeHost->createInputHandler();
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnImplThread, &completion, handler.release()));
|
| - completion.wait();
|
| -
|
| - m_started = true;
|
| -}
|
| -
|
| -void CCThreadProxy::stop()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::stop");
|
| - ASSERT(isMainThread());
|
| - ASSERT(m_started);
|
| -
|
| - // Synchronously deletes the impl.
|
| - {
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| -
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::layerTreeHostClosedOnImplThread, &completion));
|
| - completion.wait();
|
| - }
|
| -
|
| - m_mainThreadProxy->shutdown(); // Stop running tasks posted to us.
|
| -
|
| - ASSERT(!m_layerTreeHostImpl.get()); // verify that the impl deleted.
|
| - m_layerTreeHost = 0;
|
| - m_started = false;
|
| -}
|
| -
|
| -void CCThreadProxy::forceSerializeOnSwapBuffers()
|
| -{
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread, &completion));
|
| - completion.wait();
|
| -}
|
| -
|
| -void CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread(CCCompletionEvent* completion)
|
| -{
|
| - if (m_rendererInitialized)
|
| - m_layerTreeHostImpl->renderer()->doNoOp();
|
| - completion->signal();
|
| -}
|
| -
|
| -
|
| -void CCThreadProxy::finishAllRenderingOnImplThread(CCCompletionEvent* completion)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::finishAllRenderingOnImplThread");
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHostImpl->finishAllRendering();
|
| - completion->signal();
|
| -}
|
| -
|
| -void CCThreadProxy::forceBeginFrameOnImplThread(CCCompletionEvent* completion)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::forceBeginFrameOnImplThread");
|
| - ASSERT(!m_beginFrameCompletionEventOnImplThread);
|
| -
|
| - if (m_schedulerOnImplThread->commitPending()) {
|
| - completion->signal();
|
| - return;
|
| - }
|
| -
|
| - m_beginFrameCompletionEventOnImplThread = completion;
|
| - setNeedsForcedCommitOnImplThread();
|
| -}
|
| -
|
| -void CCThreadProxy::scheduledActionBeginFrame()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionBeginFrame");
|
| - ASSERT(!m_pendingBeginFrameRequest);
|
| - m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState());
|
| - m_pendingBeginFrameRequest->monotonicFrameBeginTime = monotonicallyIncreasingTime();
|
| - m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
|
| - m_pendingBeginFrameRequest->implTransform = m_layerTreeHostImpl->implTransform();
|
| - m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAllocationLimitBytes();
|
| - m_layerTreeHost->getEvictedContentTexturesBackings(m_pendingBeginFrameRequest->evictedContentsTexturesBackings);
|
| -
|
| - m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame));
|
| -
|
| - if (m_beginFrameCompletionEventOnImplThread) {
|
| - m_beginFrameCompletionEventOnImplThread->signal();
|
| - m_beginFrameCompletionEventOnImplThread = 0;
|
| - }
|
| -}
|
| -
|
| -void CCThreadProxy::beginFrame()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::beginFrame");
|
| - ASSERT(isMainThread());
|
| - if (!m_layerTreeHost)
|
| - return;
|
| -
|
| - if (!m_pendingBeginFrameRequest) {
|
| - TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
|
| - return;
|
| - }
|
| -
|
| - if (m_layerTreeHost->needsSharedContext() && !WebSharedGraphicsContext3D::haveCompositorThreadContext())
|
| - WebSharedGraphicsContext3D::createCompositorThreadContext();
|
| -
|
| - OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release());
|
| -
|
| - // Do not notify the impl thread of commit requests that occur during
|
| - // the apply/animate/layout part of the beginFrameAndCommit process since
|
| - // those commit requests will get painted immediately. Once we have done
|
| - // the paint, m_commitRequested will be set to false to allow new commit
|
| - // requests to be scheduled.
|
| - m_commitRequested = true;
|
| - m_commitRequestSentToImplThread = true;
|
| -
|
| - // On the other hand, the animationRequested flag needs to be cleared
|
| - // here so that any animation requests generated by the apply or animate
|
| - // callbacks will trigger another frame.
|
| - m_animateRequested = false;
|
| -
|
| - // FIXME: technically, scroll deltas need to be applied for dropped commits as well.
|
| - // Re-do the commit flow so that we don't send the scrollInfo on the BFAC message.
|
| - m_layerTreeHost->applyScrollAndScale(*request->scrollInfo);
|
| - m_layerTreeHost->setImplTransform(request->implTransform);
|
| -
|
| - if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) {
|
| - m_commitRequested = false;
|
| - m_commitRequestSentToImplThread = false;
|
| - m_forcedCommitRequested = false;
|
| -
|
| - TRACE_EVENT0("cc", "EarlyOut_NotVisible");
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameAbortedOnImplThread));
|
| - return;
|
| - }
|
| -
|
| - m_layerTreeHost->willBeginFrame();
|
| -
|
| - m_layerTreeHost->updateAnimations(request->monotonicFrameBeginTime);
|
| - m_layerTreeHost->layout();
|
| -
|
| - // Clear the commit flag after updating animations and layout here --- objects that only
|
| - // layout when painted will trigger another setNeedsCommit inside
|
| - // updateLayers.
|
| - m_commitRequested = false;
|
| - m_commitRequestSentToImplThread = false;
|
| - m_forcedCommitRequested = false;
|
| -
|
| - if (!m_layerTreeHost->initializeRendererIfNeeded()) {
|
| - TRACE_EVENT0("cc", "EarlyOut_InitializeFailed");
|
| - return;
|
| - }
|
| -
|
| - m_layerTreeHost->unlinkEvictedContentTexturesBackings(request->evictedContentsTexturesBackings);
|
| -
|
| - OwnPtr<CCTextureUpdateQueue> queue = adoptPtr(new CCTextureUpdateQueue);
|
| - m_layerTreeHost->updateLayers(*(queue.get()), request->memoryAllocationLimitBytes);
|
| -
|
| - // Once single buffered layers are committed, they cannot be modified until
|
| - // they are drawn by the impl thread.
|
| - m_texturesAcquired = false;
|
| -
|
| - m_layerTreeHost->willCommit();
|
| - // Before applying scrolls and calling animate, we set m_animateRequested to
|
| - // false. If it is true now, it means setNeedAnimate was called again, but
|
| - // during a state when m_commitRequestSentToImplThread = true. We need to
|
| - // force that call to happen again now so that the commit request is sent to
|
| - // the impl thread.
|
| - if (m_animateRequested) {
|
| - // Forces setNeedsAnimate to consider posting a commit task.
|
| - m_animateRequested = false;
|
| - setNeedsAnimate();
|
| - }
|
| -
|
| - // Notify the impl thread that the beginFrame has completed. This will
|
| - // begin the commit process, which is blocking from the main thread's
|
| - // point of view, but asynchronously performed on the impl thread,
|
| - // coordinated by the CCScheduler.
|
| - {
|
| - TRACE_EVENT0("cc", "commit");
|
| -
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| -
|
| - base::TimeTicks startTime = base::TimeTicks::HighResNow();
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, &completion, queue.release()));
|
| - completion.wait();
|
| - base::TimeTicks endTime = base::TimeTicks::HighResNow();
|
| -
|
| - m_totalCommitTime += endTime - startTime;
|
| - m_totalCommitCount++;
|
| - }
|
| -
|
| - m_layerTreeHost->commitComplete();
|
| - m_layerTreeHost->didBeginFrame();
|
| -}
|
| -
|
| -void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion, PassOwnPtr<CCTextureUpdateQueue> queue)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::beginFrameCompleteOnImplThread");
|
| - ASSERT(!m_commitCompletionEventOnImplThread);
|
| - ASSERT(isImplThread() && isMainThreadBlocked());
|
| - ASSERT(m_schedulerOnImplThread);
|
| - ASSERT(m_schedulerOnImplThread->commitPending());
|
| -
|
| - if (!m_layerTreeHostImpl.get()) {
|
| - TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
|
| - completion->signal();
|
| - return;
|
| - }
|
| -
|
| - // Clear any uploads we were making to textures linked to evicted
|
| - // resources
|
| - if (m_layerTreeHost->evictedContentsTexturesBackingsExist())
|
| - queue->clearUploadsToEvictedResources();
|
| -
|
| - // If we unlinked evicted textures on the main thread, delete them now.
|
| - if (m_layerTreeHost->deleteEvictedContentTexturesBackings()) {
|
| - // Deleting the evicted textures' backings resulted in some textures in the
|
| - // layer tree being invalidated (unliked from their backings). Kick off
|
| - // another commit to fill them again.
|
| - setNeedsCommitOnImplThread();
|
| - } else {
|
| - // The layer tree does not reference evicted textures, so mark that we
|
| - // can draw this tree once this commit is complete.
|
| - if (m_layerTreeHostImpl->contentsTexturesPurged())
|
| - m_resetContentsTexturesPurgedAfterCommitOnImplThread = true;
|
| - }
|
| -
|
| - m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->resourceProvider()->textureUploader());
|
| - m_currentTextureUpdateControllerOnImplThread->performMoreUpdates(
|
| - m_schedulerOnImplThread->anticipatedDrawTime());
|
| -
|
| - m_commitCompletionEventOnImplThread = completion;
|
| -}
|
| -
|
| -void CCThreadProxy::beginFrameAbortedOnImplThread()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::beginFrameAbortedOnImplThread");
|
| - ASSERT(isImplThread());
|
| - ASSERT(m_schedulerOnImplThread);
|
| - ASSERT(m_schedulerOnImplThread->commitPending());
|
| -
|
| - m_schedulerOnImplThread->beginFrameAborted();
|
| -}
|
| -
|
| -void CCThreadProxy::scheduledActionCommit()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionCommit");
|
| - ASSERT(isImplThread());
|
| - ASSERT(m_commitCompletionEventOnImplThread);
|
| - ASSERT(m_currentTextureUpdateControllerOnImplThread);
|
| -
|
| - // Complete all remaining texture updates.
|
| - m_currentTextureUpdateControllerOnImplThread->finalize();
|
| - m_currentTextureUpdateControllerOnImplThread.clear();
|
| -
|
| - m_layerTreeHostImpl->beginCommit();
|
| -
|
| - m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
|
| - m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
|
| -
|
| - if (m_resetContentsTexturesPurgedAfterCommitOnImplThread) {
|
| - m_resetContentsTexturesPurgedAfterCommitOnImplThread = false;
|
| - m_layerTreeHostImpl->resetContentsTexturesPurged();
|
| - }
|
| -
|
| - m_layerTreeHostImpl->commitComplete();
|
| -
|
| - m_nextFrameIsNewlyCommittedFrameOnImplThread = true;
|
| -
|
| - m_commitCompletionEventOnImplThread->signal();
|
| - m_commitCompletionEventOnImplThread = 0;
|
| -
|
| - // SetVisible kicks off the next scheduler action, so this must be last.
|
| - m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
|
| -}
|
| -
|
| -void CCThreadProxy::scheduledActionBeginContextRecreation()
|
| -{
|
| - ASSERT(isImplThread());
|
| - m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginContextRecreation));
|
| -}
|
| -
|
| -CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapInternal(bool forcedDraw)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionDrawAndSwap");
|
| - CCScheduledActionDrawAndSwapResult result;
|
| - result.didDraw = false;
|
| - result.didSwap = false;
|
| - ASSERT(isImplThread());
|
| - ASSERT(m_layerTreeHostImpl.get());
|
| - if (!m_layerTreeHostImpl.get())
|
| - return result;
|
| -
|
| - ASSERT(m_layerTreeHostImpl->renderer());
|
| - if (!m_layerTreeHostImpl->renderer())
|
| - return result;
|
| -
|
| - // FIXME: compute the frame display time more intelligently
|
| - double monotonicTime = monotonicallyIncreasingTime();
|
| - double wallClockTime = currentTime();
|
| -
|
| - if (m_inputHandlerOnImplThread.get())
|
| - m_inputHandlerOnImplThread->animate(monotonicTime);
|
| - m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
|
| -
|
| - // This method is called on a forced draw, regardless of whether we are able to produce a frame,
|
| - // as the calling site on main thread is blocked until its request completes, and we signal
|
| - // completion here. If canDraw() is false, we will indicate success=false to the caller, but we
|
| - // must still signal completion to avoid deadlock.
|
| -
|
| - // We guard prepareToDraw() with canDraw() because it always returns a valid frame, so can only
|
| - // be used when such a frame is possible. Since drawLayers() depends on the result of
|
| - // prepareToDraw(), it is guarded on canDraw() as well.
|
| -
|
| - CCLayerTreeHostImpl::FrameData frame;
|
| - bool drawFrame = m_layerTreeHostImpl->canDraw() && (m_layerTreeHostImpl->prepareToDraw(frame) || forcedDraw);
|
| - if (drawFrame) {
|
| - m_layerTreeHostImpl->drawLayers(frame);
|
| - result.didDraw = true;
|
| - }
|
| - m_layerTreeHostImpl->didDrawAllLayers(frame);
|
| -
|
| - // Check for a pending compositeAndReadback.
|
| - if (m_readbackRequestOnImplThread) {
|
| - m_readbackRequestOnImplThread->success = false;
|
| - if (drawFrame) {
|
| - m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
|
| - m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isContextLost();
|
| - }
|
| - m_readbackRequestOnImplThread->completion.signal();
|
| - m_readbackRequestOnImplThread = 0;
|
| - } else if (drawFrame)
|
| - result.didSwap = m_layerTreeHostImpl->swapBuffers();
|
| -
|
| - // Tell the main thread that the the newly-commited frame was drawn.
|
| - if (m_nextFrameIsNewlyCommittedFrameOnImplThread) {
|
| - m_nextFrameIsNewlyCommittedFrameOnImplThread = false;
|
| - m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didCommitAndDrawFrame));
|
| - }
|
| -
|
| - return result;
|
| -}
|
| -
|
| -void CCThreadProxy::acquireLayerTextures()
|
| -{
|
| - // Called when the main thread needs to modify a layer texture that is used
|
| - // directly by the compositor.
|
| - // This method will block until the next compositor draw if there is a
|
| - // previously committed frame that is still undrawn. This is necessary to
|
| - // ensure that the main thread does not monopolize access to the textures.
|
| - ASSERT(isMainThread());
|
| -
|
| - if (m_texturesAcquired)
|
| - return;
|
| -
|
| - TRACE_EVENT0("cc", "CCThreadProxy::acquireLayerTextures");
|
| - DebugScopedSetMainThreadBlocked mainThreadBlocked;
|
| - CCCompletionEvent completion;
|
| - CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::acquireLayerTexturesForMainThreadOnImplThread, &completion));
|
| - completion.wait(); // Block until it is safe to write to layer textures from the main thread.
|
| -
|
| - m_texturesAcquired = true;
|
| -}
|
| -
|
| -void CCThreadProxy::acquireLayerTexturesForMainThreadOnImplThread(CCCompletionEvent* completion)
|
| -{
|
| - ASSERT(isImplThread());
|
| - ASSERT(!m_textureAcquisitionCompletionEventOnImplThread);
|
| -
|
| - m_textureAcquisitionCompletionEventOnImplThread = completion;
|
| - m_schedulerOnImplThread->setMainThreadNeedsLayerTextures();
|
| -}
|
| -
|
| -void CCThreadProxy::scheduledActionAcquireLayerTexturesForMainThread()
|
| -{
|
| - ASSERT(m_textureAcquisitionCompletionEventOnImplThread);
|
| - m_textureAcquisitionCompletionEventOnImplThread->signal();
|
| - m_textureAcquisitionCompletionEventOnImplThread = 0;
|
| -}
|
| -
|
| -CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapIfPossible()
|
| -{
|
| - return scheduledActionDrawAndSwapInternal(false);
|
| -}
|
| -
|
| -CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapForced()
|
| -{
|
| - return scheduledActionDrawAndSwapInternal(true);
|
| -}
|
| -
|
| -void CCThreadProxy::didAnticipatedDrawTimeChange(base::TimeTicks time)
|
| -{
|
| - if (!m_currentTextureUpdateControllerOnImplThread)
|
| - return;
|
| -
|
| - m_currentTextureUpdateControllerOnImplThread->performMoreUpdates(time);
|
| -}
|
| -
|
| -void CCThreadProxy::readyToFinalizeTextureUpdates()
|
| -{
|
| - ASSERT(isImplThread());
|
| - m_schedulerOnImplThread->beginFrameComplete();
|
| -}
|
| -
|
| -void CCThreadProxy::didCommitAndDrawFrame()
|
| -{
|
| - ASSERT(isMainThread());
|
| - if (!m_layerTreeHost)
|
| - return;
|
| - m_layerTreeHost->didCommitAndDrawFrame();
|
| -}
|
| -
|
| -void CCThreadProxy::didCompleteSwapBuffers()
|
| -{
|
| - ASSERT(isMainThread());
|
| - if (!m_layerTreeHost)
|
| - return;
|
| - m_layerTreeHost->didCompleteSwapBuffers();
|
| -}
|
| -
|
| -void CCThreadProxy::setAnimationEvents(CCAnimationEventsVector* passed_events, double wallClockTime)
|
| -{
|
| - scoped_ptr<CCAnimationEventsVector> events(make_scoped_ptr(passed_events));
|
| -
|
| - TRACE_EVENT0("cc", "CCThreadProxy::setAnimationEvents");
|
| - ASSERT(isMainThread());
|
| - if (!m_layerTreeHost)
|
| - return;
|
| - m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime);
|
| -}
|
| -
|
| -class CCThreadProxyContextRecreationTimer : public CCTimer, CCTimerClient {
|
| -public:
|
| - static PassOwnPtr<CCThreadProxyContextRecreationTimer> create(CCThreadProxy* proxy) { return adoptPtr(new CCThreadProxyContextRecreationTimer(proxy)); }
|
| -
|
| - virtual void onTimerFired() OVERRIDE
|
| - {
|
| - m_proxy->tryToRecreateContext();
|
| - }
|
| -
|
| -private:
|
| - explicit CCThreadProxyContextRecreationTimer(CCThreadProxy* proxy)
|
| - : CCTimer(CCProxy::mainThread(), this)
|
| - , m_proxy(proxy)
|
| - {
|
| - }
|
| -
|
| - CCThreadProxy* m_proxy;
|
| -};
|
| -
|
| -void CCThreadProxy::beginContextRecreation()
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::beginContextRecreation");
|
| - ASSERT(isMainThread());
|
| - ASSERT(!m_contextRecreationTimer);
|
| - m_contextRecreationTimer = CCThreadProxyContextRecreationTimer::create(this);
|
| - m_layerTreeHost->didLoseContext();
|
| - m_contextRecreationTimer->startOneShot(contextRecreationTickRate);
|
| -}
|
| -
|
| -void CCThreadProxy::tryToRecreateContext()
|
| -{
|
| - ASSERT(isMainThread());
|
| - ASSERT(m_layerTreeHost);
|
| - CCLayerTreeHost::RecreateResult result = m_layerTreeHost->recreateContext();
|
| - if (result == CCLayerTreeHost::RecreateFailedButTryAgain)
|
| - m_contextRecreationTimer->startOneShot(contextRecreationTickRate);
|
| - else if (result == CCLayerTreeHost::RecreateSucceeded)
|
| - m_contextRecreationTimer.clear();
|
| -}
|
| -
|
| -void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion, CCInputHandler* handler)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::initializeImplOnImplThread");
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
|
| - const base::TimeDelta displayRefreshInterval = base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / 60);
|
| - scoped_ptr<CCFrameRateController> frameRateController;
|
| - if (m_renderVSyncEnabled)
|
| - frameRateController.reset(new CCFrameRateController(CCDelayBasedTimeSource::create(displayRefreshInterval, CCProxy::implThread())));
|
| - else
|
| - frameRateController.reset(new CCFrameRateController(CCProxy::implThread()));
|
| - m_schedulerOnImplThread = CCScheduler::create(this, frameRateController.Pass());
|
| - m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
|
| -
|
| - m_inputHandlerOnImplThread = scoped_ptr<CCInputHandler>(handler);
|
| - if (m_inputHandlerOnImplThread.get())
|
| - m_inputHandlerOnImplThread->bindToClient(m_layerTreeHostImpl.get());
|
| -
|
| - completion->signal();
|
| -}
|
| -
|
| -void CCThreadProxy::initializeContextOnImplThread(CCGraphicsContext* context)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::initializeContextOnImplThread");
|
| - ASSERT(isImplThread());
|
| - m_contextBeforeInitializationOnImplThread = scoped_ptr<CCGraphicsContext>(context).Pass();
|
| -}
|
| -
|
| -void CCThreadProxy::initializeRendererOnImplThread(CCCompletionEvent* completion, bool* initializeSucceeded, RendererCapabilities* capabilities)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::initializeRendererOnImplThread");
|
| - ASSERT(isImplThread());
|
| - ASSERT(m_contextBeforeInitializationOnImplThread.get());
|
| - *initializeSucceeded = m_layerTreeHostImpl->initializeRenderer(m_contextBeforeInitializationOnImplThread.Pass());
|
| - if (*initializeSucceeded) {
|
| - *capabilities = m_layerTreeHostImpl->rendererCapabilities();
|
| - m_schedulerOnImplThread->setSwapBuffersCompleteSupported(
|
| - capabilities->usingSwapCompleteCallback);
|
| - }
|
| -
|
| - completion->signal();
|
| -}
|
| -
|
| -void CCThreadProxy::layerTreeHostClosedOnImplThread(CCCompletionEvent* completion)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::layerTreeHostClosedOnImplThread");
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
|
| - m_inputHandlerOnImplThread.reset();
|
| - m_layerTreeHostImpl.reset();
|
| - m_schedulerOnImplThread.clear();
|
| - completion->signal();
|
| -}
|
| -
|
| -void CCThreadProxy::setFullRootLayerDamageOnImplThread()
|
| -{
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHostImpl->setFullRootLayerDamage();
|
| -}
|
| -
|
| -size_t CCThreadProxy::maxPartialTextureUpdates() const
|
| -{
|
| - return CCTextureUpdateController::maxPartialTextureUpdates();
|
| -}
|
| -
|
| -void CCThreadProxy::recreateContextOnImplThread(CCCompletionEvent* completion, CCGraphicsContext* contextPtr, bool* recreateSucceeded, RendererCapabilities* capabilities)
|
| -{
|
| - TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread");
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
|
| - *recreateSucceeded = m_layerTreeHostImpl->initializeRenderer(scoped_ptr<CCGraphicsContext>(contextPtr).Pass());
|
| - if (*recreateSucceeded) {
|
| - *capabilities = m_layerTreeHostImpl->rendererCapabilities();
|
| - m_schedulerOnImplThread->didRecreateContext();
|
| - }
|
| - completion->signal();
|
| -}
|
| -
|
| -void CCThreadProxy::renderingStatsOnImplThread(CCCompletionEvent* completion, CCRenderingStats* stats)
|
| -{
|
| - ASSERT(isImplThread());
|
| - m_layerTreeHostImpl->renderingStats(stats);
|
| - completion->signal();
|
| -}
|
| -
|
| -CCThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
|
| - : monotonicFrameBeginTime(0)
|
| -{
|
| -}
|
| -
|
| -CCThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState()
|
| -{
|
| -}
|
| -
|
| -} // namespace cc
|
|
|