CCSingleThreadProxy.cpp [plain text]
#include "config.h"
#include "cc/CCSingleThreadProxy.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "TraceEvent.h"
#include "cc/CCFontAtlas.h"
#include "cc/CCLayerTreeHost.h"
#include "cc/CCTextureUpdater.h"
#include <wtf/CurrentTime.h>
using namespace std;
using namespace WTF;
namespace WebCore {
PassOwnPtr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost)
{
return adoptPtr(new CCSingleThreadProxy(layerTreeHost));
}
CCSingleThreadProxy::CCSingleThreadProxy(CCLayerTreeHost* layerTreeHost)
: m_layerTreeHost(layerTreeHost)
, m_contextLost(false)
, m_compositorIdentifier(-1)
, m_layerRendererInitialized(false)
, m_nextFrameIsNewlyCommittedFrame(false)
{
TRACE_EVENT("CCSingleThreadProxy::CCSingleThreadProxy", this, 0);
ASSERT(CCProxy::isMainThread());
}
void CCSingleThreadProxy::start()
{
DebugScopedSetImplThread impl;
m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this);
}
CCSingleThreadProxy::~CCSingleThreadProxy()
{
TRACE_EVENT("CCSingleThreadProxy::~CCSingleThreadProxy", this, 0);
ASSERT(CCProxy::isMainThread());
ASSERT(!m_layerTreeHostImpl && !m_layerTreeHost); }
bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
{
TRACE_EVENT("CCSingleThreadProxy::compositeAndReadback", this, 0);
ASSERT(CCProxy::isMainThread());
if (!commitAndComposite())
return false;
m_layerTreeHostImpl->readback(pixels, rect);
if (m_layerTreeHostImpl->isContextLost())
return false;
m_layerTreeHostImpl->swapBuffers();
didSwapFrame();
return true;
}
void CCSingleThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
{
m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor, scale, monotonicallyIncreasingTime(), duration);
}
GraphicsContext3D* CCSingleThreadProxy::context()
{
ASSERT(CCProxy::isMainThread());
if (m_contextBeforeInitialization)
return m_contextBeforeInitialization.get();
DebugScopedSetImplThread impl;
return m_layerTreeHostImpl->context();
}
void CCSingleThreadProxy::finishAllRendering()
{
ASSERT(CCProxy::isMainThread());
{
DebugScopedSetImplThread impl;
m_layerTreeHostImpl->finishAllRendering();
}
}
bool CCSingleThreadProxy::isStarted() const
{
ASSERT(CCProxy::isMainThread());
return m_layerTreeHostImpl;
}
bool CCSingleThreadProxy::initializeContext()
{
ASSERT(CCProxy::isMainThread());
RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
if (!context)
return false;
ASSERT(context->hasOneRef());
m_contextBeforeInitialization = context;
return true;
}
void CCSingleThreadProxy::setSurfaceReady()
{
}
bool CCSingleThreadProxy::initializeLayerRenderer()
{
ASSERT(CCProxy::isMainThread());
ASSERT(m_contextBeforeInitialization);
{
DebugScopedSetImplThread impl;
bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release());
if (ok) {
m_layerRendererInitialized = true;
m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
}
return ok;
}
}
bool CCSingleThreadProxy::recreateContext()
{
TRACE_EVENT0("cc", "CCSingleThreadProxy::recreateContext");
ASSERT(CCProxy::isMainThread());
ASSERT(m_contextLost);
RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
if (!context)
return false;
ASSERT(context->hasOneRef());
bool initialized;
{
DebugScopedSetImplThread impl;
m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
initialized = m_layerTreeHostImpl->initializeLayerRenderer(context);
if (initialized) {
m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
}
}
if (initialized)
m_contextLost = false;
return initialized;
}
const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities() const
{
ASSERT(m_layerRendererInitialized);
return m_layerRendererCapabilitiesForMainThread;
}
void CCSingleThreadProxy::loseContext()
{
ASSERT(CCProxy::isMainThread());
m_layerTreeHost->didLoseContext();
m_contextLost = true;
}
void CCSingleThreadProxy::setNeedsAnimate()
{
ASSERT_NOT_REACHED();
}
void CCSingleThreadProxy::doCommit(CCTextureUpdater& updater)
{
ASSERT(CCProxy::isMainThread());
{
DebugScopedSetImplThread impl;
m_layerTreeHostImpl->beginCommit();
m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
updater.update(m_layerTreeHostImpl->context(), m_layerTreeHostImpl->contentsTextureAllocator(), m_layerTreeHostImpl->layerRenderer()->textureCopier(), m_layerTreeHostImpl->layerRenderer()->textureUploader(), numeric_limits<size_t>::max());
ASSERT(!updater.hasMoreUpdates());
m_layerTreeHostImpl->setVisible(m_layerTreeHost->visible());
m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
m_layerTreeHostImpl->commitComplete();
#if !ASSERT_DISABLED
OwnPtr<CCScrollAndScaleSet> scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
ASSERT(!scrollInfo->scrolls.size());
#endif
}
m_layerTreeHost->commitComplete();
m_nextFrameIsNewlyCommittedFrame = true;
}
void CCSingleThreadProxy::setNeedsCommit()
{
ASSERT(CCProxy::isMainThread());
m_layerTreeHost->setNeedsCommit();
}
void CCSingleThreadProxy::setNeedsRedraw()
{
m_layerTreeHostImpl->setFullRootLayerDamage();
setNeedsCommit();
}
bool CCSingleThreadProxy::commitRequested() const
{
return false;
}
void CCSingleThreadProxy::setVisible(bool visible)
{
m_layerTreeHostImpl->setVisible(visible);
if (!visible) {
DebugScopedSetImplThread impl;
m_layerTreeHost->didBecomeInvisibleOnImplThread(m_layerTreeHostImpl.get());
return;
}
setNeedsCommit();
}
void CCSingleThreadProxy::stop()
{
TRACE_EVENT("CCSingleThreadProxy::stop", this, 0);
ASSERT(CCProxy::isMainThread());
{
DebugScopedSetImplThread impl;
m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
m_layerTreeHostImpl.clear();
}
m_layerTreeHost = 0;
}
void CCSingleThreadProxy::setFontAtlas(PassOwnPtr<CCFontAtlas> fontAtlas)
{
ASSERT(isMainThread());
DebugScopedSetImplThread impl;
m_layerTreeHostImpl->setFontAtlas(fontAtlas);
}
void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
ASSERT(CCProxy::isImplThread());
DebugScopedSetMainThread main;
m_layerTreeHost->setAnimationEvents(events, wallClockTime);
}
void CCSingleThreadProxy::postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t bytes)
{
ASSERT(CCProxy::isMainThread());
ASSERT(m_layerTreeHost);
m_layerTreeHost->setContentsMemoryAllocationLimitBytes(bytes);
}
void CCSingleThreadProxy::compositeImmediately()
{
if (commitAndComposite()) {
m_layerTreeHostImpl->swapBuffers();
didSwapFrame();
}
}
void CCSingleThreadProxy::forceSerializeOnSwapBuffers()
{
{
DebugScopedSetImplThread impl;
if (m_layerRendererInitialized)
m_layerTreeHostImpl->layerRenderer()->doNoOp();
}
}
bool CCSingleThreadProxy::commitAndComposite()
{
ASSERT(CCProxy::isMainThread());
CCTextureUpdater updater;
if (!m_layerTreeHost->updateLayers(updater))
return false;
doCommit(updater);
return doComposite();
}
bool CCSingleThreadProxy::doComposite()
{
ASSERT(!m_contextLost);
{
DebugScopedSetImplThread impl;
double monotonicTime = monotonicallyIncreasingTime();
double wallClockTime = currentTime();
m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
CCLayerTreeHostImpl::FrameData frame;
m_layerTreeHostImpl->prepareToDraw(frame);
m_layerTreeHostImpl->drawLayers(frame);
m_layerTreeHostImpl->didDrawAllLayers(frame);
}
if (m_layerTreeHostImpl->isContextLost()) {
m_contextLost = true;
m_layerTreeHost->didLoseContext();
return false;
}
return true;
}
void CCSingleThreadProxy::didSwapFrame()
{
if (m_nextFrameIsNewlyCommittedFrame) {
m_nextFrameIsNewlyCommittedFrame = false;
m_layerTreeHost->didCommitAndDrawFrame();
}
}
}