ThreadedCoordinatedLayerTreeHost.cpp [plain text]
#include "config.h"
#include "ThreadedCoordinatedLayerTreeHost.h"
#if USE(COORDINATED_GRAPHICS_THREADED)
#include "DrawingAreaImpl.h"
#include "NotImplemented.h"
#include "ThreadSafeCoordinatedSurface.h"
#include "WebPage.h"
#include <WebCore/CoordinatedGraphicsLayer.h>
#include <WebCore/CoordinatedGraphicsState.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
#include <wtf/CurrentTime.h>
using namespace WebCore;
namespace WebKit {
Ref<ThreadedCoordinatedLayerTreeHost> ThreadedCoordinatedLayerTreeHost::create(WebPage* webPage)
{
return adoptRef(*new ThreadedCoordinatedLayerTreeHost(webPage));
}
ThreadedCoordinatedLayerTreeHost::~ThreadedCoordinatedLayerTreeHost()
{
}
ThreadedCoordinatedLayerTreeHost::ThreadedCoordinatedLayerTreeHost(WebPage* webPage)
: LayerTreeHost(webPage)
, m_forceRepaintAsyncCallbackID(0)
, m_contentLayer(nullptr)
, m_viewOverlayRootLayer(nullptr)
, m_notifyAfterScheduledLayerFlush(false)
, m_isSuspended(false)
, m_isWaitingForRenderer(false)
, m_layerFlushTimer(RunLoop::main(), this, &ThreadedCoordinatedLayerTreeHost::performScheduledLayerFlush)
, m_layerFlushSchedulingEnabled(true)
{
m_coordinator = std::make_unique<CompositingCoordinator>(m_webPage->corePage(), this);
m_coordinator->createRootLayer(m_webPage->size());
CoordinatedSurface::setFactory(createCoordinatedSurface);
m_compositor = ThreadedCompositor::create(this);
scheduleLayerFlush();
}
PassRefPtr<CoordinatedSurface> ThreadedCoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags)
{
return ThreadSafeCoordinatedSurface::create(size, flags);
}
void ThreadedCoordinatedLayerTreeHost::scheduleLayerFlush()
{
if (!m_layerFlushSchedulingEnabled)
return;
if (!m_layerFlushTimer.isActive())
m_layerFlushTimer.startOneShot(0);
}
void ThreadedCoordinatedLayerTreeHost::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
{
if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
return;
m_layerFlushSchedulingEnabled = layerFlushingEnabled;
if (m_layerFlushSchedulingEnabled) {
scheduleLayerFlush();
return;
}
cancelPendingLayerFlush();
}
void ThreadedCoordinatedLayerTreeHost::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
{
m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
}
void ThreadedCoordinatedLayerTreeHost::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
{
m_contentLayer = graphicsLayer;
updateRootLayers();
}
void ThreadedCoordinatedLayerTreeHost::invalidate()
{
notImplemented();
}
void ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents(const WebCore::IntRect& rect)
{
m_compositor->scrollTo(rect.location());
scheduleLayerFlush();
}
void ThreadedCoordinatedLayerTreeHost::forceRepaint()
{
notImplemented();
}
bool ThreadedCoordinatedLayerTreeHost::forceRepaintAsync(uint64_t callbackID)
{
ASSERT(!m_forceRepaintAsyncCallbackID);
m_forceRepaintAsyncCallbackID = callbackID;
scheduleLayerFlush();
return true;
}
void ThreadedCoordinatedLayerTreeHost::sizeDidChange(const WebCore::IntSize& newSize)
{
m_coordinator->sizeDidChange(newSize);
m_compositor->didChangeContentsSize(newSize);
}
void ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
{
m_coordinator->deviceOrPageScaleFactorChanged();
}
void ThreadedCoordinatedLayerTreeHost::pauseRendering()
{
m_isSuspended = true;
}
void ThreadedCoordinatedLayerTreeHost::resumeRendering()
{
m_isSuspended = false;
scheduleLayerFlush();
}
GraphicsLayerFactory* ThreadedCoordinatedLayerTreeHost::graphicsLayerFactory()
{
return m_coordinator.get();
}
void ThreadedCoordinatedLayerTreeHost::viewportSizeChanged(const WebCore::IntSize& size)
{
m_compositor->didChangeViewportSize(size);
}
void ThreadedCoordinatedLayerTreeHost::didChangeViewportProperties(const WebCore::ViewportAttributes& attr)
{
m_compositor->didChangeViewportAttribute(attr);
}
void ThreadedCoordinatedLayerTreeHost::compositorDidFlushLayers()
{
static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
}
void ThreadedCoordinatedLayerTreeHost::didScaleFactorChanged(float scale, const IntPoint& origin)
{
m_webPage->scalePage(scale, origin);
}
void ThreadedCoordinatedLayerTreeHost::updateRootLayers()
{
if (!m_contentLayer && !m_viewOverlayRootLayer)
return;
m_coordinator->setRootCompositingLayer(m_contentLayer, m_viewOverlayRootLayer);
}
void ThreadedCoordinatedLayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
{
m_viewOverlayRootLayer = viewOverlayRootLayer;
updateRootLayers();
}
#if PLATFORM(GTK)
void ThreadedCoordinatedLayerTreeHost::setNativeSurfaceHandleForCompositing(uint64_t handle)
{
m_layerTreeContext.contextID = handle;
m_compositor->setNativeSurfaceHandleForCompositing(handle);
}
#endif
#if ENABLE(REQUEST_ANIMATION_FRAME)
void ThreadedCoordinatedLayerTreeHost::scheduleAnimation()
{
if (m_isWaitingForRenderer)
return;
if (m_layerFlushTimer.isActive())
return;
m_layerFlushTimer.startOneShot(m_coordinator->nextAnimationServiceTime());
scheduleLayerFlush();
}
#endif
void ThreadedCoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector, float scale)
{
m_coordinator->setVisibleContentsRect(rect, trajectoryVector);
if (m_lastScrollPosition != roundedIntPoint(rect.location())) {
m_lastScrollPosition = roundedIntPoint(rect.location());
if (!m_webPage->corePage()->mainFrame().view()->useFixedLayout())
m_webPage->corePage()->mainFrame().view()->notifyScrollPositionChanged(m_lastScrollPosition);
}
if (m_lastScaleFactor != scale) {
m_lastScaleFactor = scale;
didScaleFactorChanged(m_lastScaleFactor, m_lastScrollPosition);
}
scheduleLayerFlush();
}
void ThreadedCoordinatedLayerTreeHost::cancelPendingLayerFlush()
{
m_layerFlushTimer.stop();
}
void ThreadedCoordinatedLayerTreeHost::performScheduledLayerFlush()
{
if (m_isSuspended || m_isWaitingForRenderer)
return;
m_coordinator->syncDisplayState();
bool didSync = m_coordinator->flushPendingLayerChanges();
if (m_notifyAfterScheduledLayerFlush && didSync) {
compositorDidFlushLayers();
m_notifyAfterScheduledLayerFlush = false;
}
}
void ThreadedCoordinatedLayerTreeHost::purgeBackingStores()
{
m_coordinator->purgeBackingStores();
}
void ThreadedCoordinatedLayerTreeHost::renderNextFrame()
{
m_isWaitingForRenderer = false;
m_coordinator->renderNextFrame();
scheduleLayerFlush();
}
void ThreadedCoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const IntSize& offset)
{
m_coordinator->commitScrollOffset(layerID, offset);
}
void ThreadedCoordinatedLayerTreeHost::notifyFlushRequired()
{
scheduleLayerFlush();
}
void ThreadedCoordinatedLayerTreeHost::commitSceneState(const CoordinatedGraphicsState& state)
{
m_isWaitingForRenderer = true;
m_compositor->updateSceneState(state);
}
void ThreadedCoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&)
{
}
}
#endif // USE(COORDINATED_GRAPHICS)