CoordinatedLayerTreeHost.cpp [plain text]
#include "config.h"
#if USE(COORDINATED_GRAPHICS)
#include "CoordinatedLayerTreeHost.h"
#include "DrawingArea.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include <WebCore/FrameView.h>
#include <WebCore/MainFrame.h>
#include <WebCore/PageOverlayController.h>
#if USE(COORDINATED_GRAPHICS_THREADED)
#include "ThreadSafeCoordinatedSurface.h"
#endif
#if USE(GLIB_EVENT_LOOP)
#include <wtf/glib/RunLoopSourcePriority.h>
#endif
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_coordinator(webPage.corePage(), *this)
, m_layerFlushTimer(RunLoop::main(), this, &CoordinatedLayerTreeHost::layerFlushTimerFired)
{
#if USE(GLIB_EVENT_LOOP)
m_layerFlushTimer.setPriority(RunLoopSourcePriority::LayerFlushTimer);
m_layerFlushTimer.setName("[WebKit] CoordinatedLayerTreeHost");
#endif
m_coordinator.createRootLayer(m_webPage.size());
CoordinatedSurface::setFactory(createCoordinatedSurface);
scheduleLayerFlush();
}
void CoordinatedLayerTreeHost::scheduleLayerFlush()
{
if (!m_layerFlushSchedulingEnabled)
return;
if (m_isWaitingForRenderer) {
m_scheduledWhileWaitingForRenderer = true;
return;
}
if (!m_layerFlushTimer.isActive())
m_layerFlushTimer.startOneShot(0_s);
}
void CoordinatedLayerTreeHost::cancelPendingLayerFlush()
{
m_layerFlushTimer.stop();
}
void CoordinatedLayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
{
LayerTreeHost::setViewOverlayRootLayer(viewOverlayRootLayer);
m_coordinator.setViewOverlayRootLayer(viewOverlayRootLayer);
}
void CoordinatedLayerTreeHost::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
{
m_coordinator.setRootCompositingLayer(graphicsLayer);
}
void CoordinatedLayerTreeHost::invalidate()
{
cancelPendingLayerFlush();
m_coordinator.invalidate();
LayerTreeHost::invalidate();
}
void CoordinatedLayerTreeHost::forceRepaint()
{
m_coordinator.syncDisplayState();
scheduleLayerFlush();
if (m_isWaitingForRenderer)
return;
m_coordinator.flushPendingLayerChanges();
}
bool CoordinatedLayerTreeHost::forceRepaintAsync(CallbackID callbackID)
{
scheduleLayerFlush();
ASSERT(!m_forceRepaintAsync.callbackID);
m_forceRepaintAsync.callbackID = OptionalCallbackID(callbackID);
m_forceRepaintAsync.needsFreshFlush = m_scheduledWhileWaitingForRenderer;
return true;
}
void CoordinatedLayerTreeHost::sizeDidChange(const 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;
bool scheduledWhileWaitingForRenderer = std::exchange(m_scheduledWhileWaitingForRenderer, false);
m_coordinator.renderNextFrame();
if (m_forceRepaintAsync.callbackID) {
ASSERT(!m_forceRepaintAsync.needsFreshFlush || scheduledWhileWaitingForRenderer);
if (!m_forceRepaintAsync.needsFreshFlush) {
m_webPage.send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsync.callbackID.callbackID()));
m_forceRepaintAsync.callbackID = OptionalCallbackID();
}
m_forceRepaintAsync.needsFreshFlush = false;
}
if (scheduledWhileWaitingForRenderer || m_layerFlushTimer.isActive()) {
m_layerFlushTimer.stop();
layerFlushTimerFired();
}
}
void CoordinatedLayerTreeHost::didFlushRootLayer(const FloatRect& visibleContentRect)
{
if (m_viewOverlayRootLayer)
m_viewOverlayRootLayer->flushCompositingState(visibleContentRect);
}
void CoordinatedLayerTreeHost::layerFlushTimerFired()
{
if (m_isSuspended || m_isWaitingForRenderer)
return;
m_coordinator.syncDisplayState();
if (!m_isValid || !m_coordinator.rootCompositingLayer())
return;
if (m_forceRepaintAsync.callbackID)
m_coordinator.forceFrameSync();
bool didSync = m_coordinator.flushPendingLayerChanges();
if (m_notifyAfterScheduledLayerFlush && didSync) {
m_webPage.drawingArea()->layerHostDidFlushLayers();
m_notifyAfterScheduledLayerFlush = false;
}
}
void CoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&)
{
}
void CoordinatedLayerTreeHost::commitSceneState(const CoordinatedGraphicsState& state)
{
m_isWaitingForRenderer = true;
}
RefPtr<CoordinatedSurface> CoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags)
{
#if USE(COORDINATED_GRAPHICS_THREADED)
return ThreadSafeCoordinatedSurface::create(size, flags);
#else
UNUSED_PARAM(size);
UNUSED_PARAM(flags);
return nullptr;
#endif
}
void CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
{
m_coordinator.deviceOrPageScaleFactorChanged();
m_webPage.mainFrame()->pageOverlayController().didChangeDeviceScaleFactor();
}
void CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged()
{
}
GraphicsLayerFactory* CoordinatedLayerTreeHost::graphicsLayerFactory()
{
return &m_coordinator;
}
void CoordinatedLayerTreeHost::scheduleAnimation()
{
if (m_isWaitingForRenderer)
return;
if (m_layerFlushTimer.isActive())
return;
scheduleLayerFlush();
m_layerFlushTimer.startOneShot(1_s * m_coordinator.nextAnimationServiceTime());
}
void CoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset)
{
m_coordinator.commitScrollOffset(layerID, offset);
}
void CoordinatedLayerTreeHost::clearUpdateAtlases()
{
m_coordinator.clearUpdateAtlases();
}
} #endif // USE(COORDINATED_GRAPHICS)