void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags)
{
    if (!m_textureMapper) {
        m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
        static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
    }

    ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
    syncRemoteContent();

    adjustPositionForFixedLayers();
    GraphicsLayer* currentRootLayer = rootLayer();
    if (!currentRootLayer)
        return;

    TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);

    if (!layer)
        return;

    layer->setTextureMapper(m_textureMapper.get());
    if (!m_animationsLocked)
        layer->applyAnimationsRecursively();
    m_textureMapper->beginPainting(PaintFlags);
    m_textureMapper->beginClip(TransformationMatrix(), clipRect);

    if (m_setDrawsBackground) {
        RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(),
            m_backgroundColor.green(), m_backgroundColor.blue(),
            m_backgroundColor.alpha() * opacity);
        m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba));
    }

    if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
        currentRootLayer->setOpacity(opacity);
        currentRootLayer->setTransform(matrix);
        currentRootLayer->flushCompositingStateForThisLayerOnly();
    }

    layer->paint();
    m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix);
    m_textureMapper->endClip();
    m_textureMapper->endPainting();

    if (layer->descendantsOrSelfHaveRunningAnimations())
        dispatchOnMainThread(bind(&CoordinatedGraphicsScene::updateViewport, this));

#if ENABLE(REQUEST_ANIMATION_FRAME)
    if (m_animationFrameRequested) {
        m_animationFrameRequested = false;
        dispatchOnMainThread(bind(&CoordinatedGraphicsScene::animationFrameReady, this));
    }
#endif
}
void CoordinatedGraphicsScene::commitScrollOffset(uint32_t layerID, const IntSize& offset)
{
    RefPtr<CoordinatedGraphicsScene> protector(this);
    dispatchOnMainThread([=] {
        protector->dispatchCommitScrollOffset(layerID, offset);
    });
}
void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
{
    m_renderedContentsScrollPosition = state.scrollPosition;

    createLayers(state.layersToCreate);
    deleteLayers(state.layersToRemove);

    if (state.rootCompositingLayer != m_rootLayerID)
        setRootLayerID(state.rootCompositingLayer);

    syncImageBackings(state);
    syncUpdateAtlases(state);

    for (size_t i = 0; i < state.layersToUpdate.size(); ++i)
        setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second);

    commitPendingBackingStoreOperations();
    removeReleasedImageBackingsIfNeeded();

    // The pending tiles state is on its way for the screen, tell the web process to render the next one.
    RefPtr<CoordinatedGraphicsScene> protector(this);
    dispatchOnMainThread([=] {
        protector->renderNextFrame();
    });
}
void CoordinatedGraphicsScene::purgeGLResources()
{
    m_imageBackings.clear();
    m_releasedImageBackings.clear();
#if USE(GRAPHICS_SURFACE)
    m_surfaceBackingStores.clear();
#endif
#if USE(COORDINATED_GRAPHICS_THREADED)
    m_platformLayerProxies.clear();
#endif
    m_surfaces.clear();

    m_rootLayer = nullptr;
    m_rootLayerID = InvalidCoordinatedLayerID;
    m_layers.clear();
    m_fixedLayers.clear();
    m_textureMapper = nullptr;
    m_backingStores.clear();
    m_backingStoresWithPendingBuffers.clear();

    setActive(false);

    RefPtr<CoordinatedGraphicsScene> protector(this);
    dispatchOnMainThread([=] {
        protector->purgeBackingStores();
    });
}
void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
{
    m_renderedContentsScrollPosition = state.scrollPosition;

    createLayers(state.layersToCreate);
    deleteLayers(state.layersToRemove);

    if (state.rootCompositingLayer != m_rootLayerID)
        setRootLayerID(state.rootCompositingLayer);

    syncImageBackings(state);
    syncUpdateAtlases(state);
#if ENABLE(CSS_SHADERS)
    syncCustomFilterPrograms(state);
#endif

    for (size_t i = 0; i < state.layersToUpdate.size(); ++i)
        setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second);

    commitPendingBackingStoreOperations();
    removeReleasedImageBackingsIfNeeded();

    // The pending tiles state is on its way for the screen, tell the web process to render the next one.
    dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
}
void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
{
    m_renderedContentsScrollPosition = state.scrollPosition;

    // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
    setAnimationsLocked(false);

    if (state.rootCompositingLayer != m_rootLayerID)
        setRootLayerID(state.rootCompositingLayer);

    if (state.backgroundColor != m_backgroundColor)
        setBackgroundColor(state.backgroundColor);

    for (size_t i = 0; i < state.imagesToUpdate.size(); ++i)
        updateImageBacking(state.imagesToUpdate[i].first, state.imagesToUpdate[i].second);

    for (size_t i = 0; i < state.layersToUpdate.size(); ++i)
        setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second);

    m_rootLayer->flushCompositingState(FloatRect());
    commitPendingBackingStoreOperations();
    removeReleasedImageBackingsIfNeeded();

    // The pending tiles state is on its way for the screen, tell the web process to render the next one.
    dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
}
void CoordinatedGraphicsScene::commitScrollOffset(uint32_t layerID, const IntSize& offset)
{
    if (!m_client)
        return;
    dispatchOnMainThread([this, layerID, offset] {
        if (m_client)
            m_client->commitScrollOffset(layerID, offset);
    });
}
void CoordinatedGraphicsScene::renderNextFrame()
{
    if (!m_client)
        return;
    dispatchOnMainThread([this] {
        if (m_client)
            m_client->renderNextFrame();
    });
}
void CoordinatedGraphicsScene::setActive(bool active)
{
    if (m_isActive == active)
        return;

    m_isActive = active;
    if (m_isActive) {
        RefPtr<CoordinatedGraphicsScene> protector(this);
        dispatchOnMainThread([=] {
            protector->renderNextFrame();
        });
    }
}
void CoordinatedGraphicsScene::setActive(bool active)
{
    if (m_isActive == active)
        return;

    // Have to clear render queue in both cases.
    // If there are some updates in queue during activation then those updates are from previous instance of paint node
    // and cannot be applied to the newly created instance.
    m_renderQueue.clear();
    m_isActive = active;
    if (m_isActive)
        dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
}
void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const Color& backgroundColor, bool drawsBackground, TextureMapper::PaintFlags PaintFlags)
{
    if (!m_textureMapper) {
        m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
        static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
    }

    ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
    syncRemoteContent();

    adjustPositionForFixedLayers();
    TextureMapperLayer* currentRootLayer = rootLayer();
    if (!currentRootLayer)
        return;

    currentRootLayer->setTextureMapper(m_textureMapper.get());
    currentRootLayer->applyAnimationsRecursively();
    m_textureMapper->beginPainting(PaintFlags);
    m_textureMapper->beginClip(TransformationMatrix(), clipRect);

    if (drawsBackground) {
        RGBA32 rgba = makeRGBA32FromFloats(backgroundColor.red(),
            backgroundColor.green(), backgroundColor.blue(),
            backgroundColor.alpha() * opacity);
        m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba));
    } else {
        GraphicsContext3D* context = static_cast<TextureMapperGL*>(m_textureMapper.get())->graphicsContext3D();
        context->clearColor(m_viewBackgroundColor.red() / 255.0f, m_viewBackgroundColor.green() / 255.0f, m_viewBackgroundColor.blue() / 255.0f, m_viewBackgroundColor.alpha() / 255.0f);
        context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
    }

    if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
        currentRootLayer->setOpacity(opacity);
        currentRootLayer->setTransform(matrix);
    }

    currentRootLayer->paint();
    m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix);
    m_textureMapper->endClip();
    m_textureMapper->endPainting();

    if (currentRootLayer->descendantsOrSelfHaveRunningAnimations()) {
        RefPtr<CoordinatedGraphicsScene> protector(this);
        dispatchOnMainThread([=] {
            protector->updateViewport();
        });
    }
}
void CoordinatedGraphicsScene::purgeGLResources()
{
    m_imageBackings.clear();
    m_releasedImageBackings.clear();
#if USE(GRAPHICS_SURFACE)
    m_surfaceBackingStores.clear();
#endif
    m_surfaces.clear();

    m_rootLayer = nullptr;
    m_rootLayerID = InvalidCoordinatedLayerID;
    m_layers.clear();
    m_fixedLayers.clear();
    m_textureMapper.clear();
    m_backingStores.clear();
    m_backingStoresWithPendingBuffers.clear();

    setActive(false);
    dispatchOnMainThread(bind(&CoordinatedGraphicsScene::purgeBackingStores, this));
}
void CoordinatedGraphicsScene::commitScrollOffset(uint32_t layerID, const IntSize& offset)
{
    dispatchOnMainThread(bind(&CoordinatedGraphicsScene::dispatchCommitScrollOffset, this, layerID, offset));
}