CoordinatedLayerTreeHost.cpp [plain text]
#include "config.h"
#if USE(COORDINATED_GRAPHICS)
#include "CoordinatedLayerTreeHost.h"
#include "CoordinatedDrawingArea.h"
#include "CoordinatedGraphicsArgumentCoders.h"
#include "CoordinatedLayerTreeHostProxyMessages.h"
#include "GraphicsContext.h"
#include "WebCoordinatedSurface.h"
#include "WebCoreArgumentCoders.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
#include <WebCore/MainFrame.h>
#include <WebCore/PageOverlayController.h>
#include <WebCore/Settings.h>
#include <wtf/CurrentTime.h>
using namespace WebCore;
namespace WebKit {
Ref<CoordinatedLayerTreeHost> CoordinatedLayerTreeHost::create(WebPage* webPage)
{
return adoptRef(*new CoordinatedLayerTreeHost(webPage));
}
CoordinatedLayerTreeHost::~CoordinatedLayerTreeHost()
{
}
CoordinatedLayerTreeHost::CoordinatedLayerTreeHost(WebPage* webPage)
: LayerTreeHost(webPage)
, m_notifyAfterScheduledLayerFlush(false)
, m_isValid(true)
, m_isSuspended(false)
, m_isWaitingForRenderer(true)
, m_layerFlushTimer(*this, &CoordinatedLayerTreeHost::layerFlushTimerFired)
, m_layerFlushSchedulingEnabled(true)
, m_forceRepaintAsyncCallbackID(0)
, m_contentLayer(nullptr)
, m_viewOverlayRootLayer(nullptr)
{
m_coordinator = std::make_unique<CompositingCoordinator>(webPage->corePage(), this);
m_coordinator->createRootLayer(webPage->size());
m_layerTreeContext.contextID = toCoordinatedGraphicsLayer(m_coordinator->rootLayer())->id();
CoordinatedSurface::setFactory(createCoordinatedSurface);
scheduleLayerFlush();
}
void CoordinatedLayerTreeHost::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
{
if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
return;
m_layerFlushSchedulingEnabled = layerFlushingEnabled;
if (m_layerFlushSchedulingEnabled) {
scheduleLayerFlush();
return;
}
cancelPendingLayerFlush();
}
void CoordinatedLayerTreeHost::scheduleLayerFlush()
{
if (!m_layerFlushSchedulingEnabled)
return;
if (!m_layerFlushTimer.isActive() || m_layerFlushTimer.nextFireInterval() > 0)
m_layerFlushTimer.startOneShot(0);
}
void CoordinatedLayerTreeHost::cancelPendingLayerFlush()
{
m_layerFlushTimer.stop();
}
void CoordinatedLayerTreeHost::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
{
m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
}
void CoordinatedLayerTreeHost::updateRootLayers()
{
if (!m_contentLayer && !m_viewOverlayRootLayer)
return;
m_coordinator->setRootCompositingLayer(m_contentLayer, m_viewOverlayRootLayer);
}
void CoordinatedLayerTreeHost::setViewOverlayRootLayer(WebCore::GraphicsLayer* viewOverlayRootLayer)
{
m_viewOverlayRootLayer = viewOverlayRootLayer;
updateRootLayers();
}
void CoordinatedLayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
{
m_contentLayer = graphicsLayer;
updateRootLayers();
}
void CoordinatedLayerTreeHost::invalidate()
{
cancelPendingLayerFlush();
ASSERT(m_isValid);
m_coordinator->clearRootLayer();
m_isValid = false;
}
void CoordinatedLayerTreeHost::forceRepaint()
{
m_coordinator->syncDisplayState();
scheduleLayerFlush();
if (m_isWaitingForRenderer)
return;
m_coordinator->flushPendingLayerChanges();
}
bool CoordinatedLayerTreeHost::forceRepaintAsync(uint64_t callbackID)
{
ASSERT(!m_forceRepaintAsyncCallbackID);
m_forceRepaintAsyncCallbackID = callbackID;
scheduleLayerFlush();
return true;
}
void CoordinatedLayerTreeHost::sizeDidChange(const WebCore::IntSize& newSize)
{
m_coordinator->sizeDidChange(newSize);
scheduleLayerFlush();
}
void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector)
{
m_coordinator->setVisibleContentsRect(rect, trajectoryVector);
scheduleLayerFlush();
}
void CoordinatedLayerTreeHost::renderNextFrame()
{
m_isWaitingForRenderer = false;
scheduleLayerFlush();
m_coordinator->renderNextFrame();
}
void CoordinatedLayerTreeHost::purgeBackingStores()
{
m_coordinator->purgeBackingStores();
}
void CoordinatedLayerTreeHost::didFlushRootLayer(const FloatRect& visibleContentRect)
{
if (m_coordinator->mainContentsLayer())
m_coordinator->mainContentsLayer()->flushCompositingState(visibleContentRect, m_webPage->mainFrame()->view()->viewportIsStable());
}
void CoordinatedLayerTreeHost::performScheduledLayerFlush()
{
if (m_isSuspended || m_isWaitingForRenderer)
return;
m_coordinator->syncDisplayState();
if (!m_isValid)
return;
bool didSync = m_coordinator->flushPendingLayerChanges();
if (m_forceRepaintAsyncCallbackID) {
m_webPage->send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsyncCallbackID));
m_forceRepaintAsyncCallbackID = 0;
}
if (m_notifyAfterScheduledLayerFlush && didSync) {
static_cast<CoordinatedDrawingArea*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
m_notifyAfterScheduledLayerFlush = false;
}
}
void CoordinatedLayerTreeHost::layerFlushTimerFired()
{
performScheduledLayerFlush();
}
void CoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&)
{
}
void CoordinatedLayerTreeHost::commitSceneState(const WebCore::CoordinatedGraphicsState& state)
{
m_webPage->send(Messages::CoordinatedLayerTreeHostProxy::CommitCoordinatedGraphicsState(state));
m_isWaitingForRenderer = true;
}
PassRefPtr<CoordinatedSurface> CoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags)
{
return WebCoordinatedSurface::create(size, flags);
}
void CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
{
m_coordinator->deviceOrPageScaleFactorChanged();
m_webPage->mainFrame()->pageOverlayController().didChangeDeviceScaleFactor();
}
void CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged()
{
}
GraphicsLayerFactory* CoordinatedLayerTreeHost::graphicsLayerFactory()
{
return m_coordinator.get();
}
#if ENABLE(REQUEST_ANIMATION_FRAME)
void CoordinatedLayerTreeHost::scheduleAnimation()
{
if (m_isWaitingForRenderer)
return;
if (m_layerFlushTimer.isActive())
return;
scheduleLayerFlush();
m_layerFlushTimer.startOneShot(m_coordinator->nextAnimationServiceTime());
}
#endif
void CoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset)
{
m_coordinator->commitScrollOffset(layerID, offset);
}
} #endif // USE(COORDINATED_GRAPHICS)