/*
 * Copyright (C) 2014 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ThreadedCompositor.h"

#if USE(COORDINATED_GRAPHICS_THREADED)

#include "CompositingRunLoop.h"
#include "ThreadedDisplayRefreshMonitor.h"
#include <WebCore/PlatformDisplay.h>
#include <WebCore/TransformationMatrix.h>
#include <wtf/SetForScope.h>

#if USE(LIBEPOXY)
#include <epoxy/gl.h>
#elif USE(OPENGL_ES)
#include <GLES2/gl2.h>
#else
#include <GL/gl.h>
#endif

namespace WebKit {
using namespace WebCore;

Ref<ThreadedCompositor> ThreadedCompositor::create(Client& client, WebPage& webPage, const IntSize& viewportSize, float scaleFactor, ShouldDoFrameSync doFrameSync, TextureMapper::PaintFlags paintFlags)
{
    return adoptRef(*new ThreadedCompositor(client, webPage, viewportSize, scaleFactor, doFrameSync, paintFlags));
}

ThreadedCompositor::ThreadedCompositor(Client& client, WebPage& webPage, const IntSize& viewportSize, float scaleFactor, ShouldDoFrameSync doFrameSync, TextureMapper::PaintFlags paintFlags)
    : m_client(client)
    , m_doFrameSync(doFrameSync)
    , m_paintFlags(paintFlags)
    , m_compositingRunLoop(std::make_unique<CompositingRunLoop>([this] { renderLayerTree(); }))
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
    , m_displayRefreshMonitor(ThreadedDisplayRefreshMonitor::create(*this))
#endif
{
    {
        // Locking isn't really necessary here, but it's done for consistency.
        LockHolder locker(m_attributes.lock);
        m_attributes.viewportSize = viewportSize;
        m_attributes.scaleFactor = scaleFactor;
        m_attributes.needsResize = !viewportSize.isEmpty();
    }

    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
        m_nativeSurfaceHandle = m_client.nativeSurfaceHandleForCompositing();

        m_scene->setActive(!!m_nativeSurfaceHandle);
        if (m_nativeSurfaceHandle)
            createGLContext();
    });
}

ThreadedCompositor::~ThreadedCompositor()
{
}

void ThreadedCompositor::createGLContext()
{
    ASSERT(!RunLoop::isMain());

    ASSERT(m_nativeSurfaceHandle);

    m_context = GLContext::createContextForWindow(reinterpret_cast<GLNativeWindowType>(m_nativeSurfaceHandle), &PlatformDisplay::sharedDisplayForCompositing());
    if (!m_context)
        return;

    if (!m_context->makeContextCurrent())
        return;

    if (m_doFrameSync == ShouldDoFrameSync::No)
        m_context->swapInterval(0);
}

void ThreadedCompositor::invalidate()
{
    m_scene->detach();
    m_compositingRunLoop->stopUpdates();
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
    m_displayRefreshMonitor->invalidate();
#endif
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        if (!m_context || !m_context->makeContextCurrent())
            return;
        m_scene->purgeGLResources();
        m_context = nullptr;
        m_client.didDestroyGLContext();
        m_scene = nullptr;
    });
    m_compositingRunLoop = nullptr;
}

void ThreadedCompositor::setNativeSurfaceHandleForCompositing(uint64_t handle)
{
    m_compositingRunLoop->stopUpdates();
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this), handle] {
        // A new native handle can't be set without destroying the previous one first if any.
        ASSERT(!!handle ^ !!m_nativeSurfaceHandle);
        m_nativeSurfaceHandle = handle;

        m_scene->setActive(!!m_nativeSurfaceHandle);
        if (m_nativeSurfaceHandle)
            createGLContext();
        else
            m_context = nullptr;
    });
}

void ThreadedCompositor::setScaleFactor(float scale)
{
    LockHolder locker(m_attributes.lock);
    m_attributes.scaleFactor = scale;
    m_compositingRunLoop->scheduleUpdate();
}

void ThreadedCompositor::setScrollPosition(const IntPoint& scrollPosition, float scale)
{
    LockHolder locker(m_attributes.lock);
    m_attributes.scrollPosition = scrollPosition;
    m_attributes.scaleFactor = scale;
    m_compositingRunLoop->scheduleUpdate();
}

void ThreadedCompositor::setViewportSize(const IntSize& viewportSize, float scale)
{
    LockHolder locker(m_attributes.lock);
    m_attributes.viewportSize = viewportSize;
    m_attributes.scaleFactor = scale;
    m_attributes.needsResize = true;
    m_compositingRunLoop->scheduleUpdate();
}

void ThreadedCompositor::setDrawsBackground(bool drawsBackground)
{
    LockHolder locker(m_attributes.lock);
    m_attributes.drawsBackground = drawsBackground;
    m_compositingRunLoop->scheduleUpdate();
}

void ThreadedCompositor::updateViewport()
{
    m_compositingRunLoop->scheduleUpdate();
}

void ThreadedCompositor::forceRepaint()
{
    // FIXME: Enable this for WPE once it's possible to do these forced updates
    // in a way that doesn't starve out the underlying graphics buffers.
#if PLATFORM(GTK)
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        SetForScope<bool> change(m_inForceRepaint, true);
        renderLayerTree();
    });
#endif
}

void ThreadedCompositor::renderLayerTree()
{
    if (!m_scene || !m_scene->isActive())
        return;

    if (!m_context || !m_context->makeContextCurrent())
        return;

    m_client.willRenderFrame();

    // Retrieve the scene attributes in a thread-safe manner.
    WebCore::IntSize viewportSize;
    WebCore::IntPoint scrollPosition;
    float scaleFactor;
    bool drawsBackground;
    bool needsResize;
    Vector<WebCore::CoordinatedGraphicsState> states;

    {
        LockHolder locker(m_attributes.lock);
        viewportSize = m_attributes.viewportSize;
        scrollPosition = m_attributes.scrollPosition;
        scaleFactor = m_attributes.scaleFactor;
        drawsBackground = m_attributes.drawsBackground;
        needsResize = m_attributes.needsResize;

        states = WTFMove(m_attributes.states);

        if (!states.isEmpty()) {
            // Client has to be notified upon finishing this scene update.
            m_attributes.clientRendersNextFrame = true;

            // Coordinate scene update completion with the client in case of changed or updated platform layers.
            // But do not change coordinateUpdateCompletionWithClient while in force repaint because that
            // demands immediate scene update completion regardless of platform layers.
            if (!m_inForceRepaint) {
                bool coordinateUpdate = false;
                for (auto& state : states)
                    coordinateUpdate |= std::any_of(state.layersToUpdate.begin(), state.layersToUpdate.end(),
                        [](auto& it) { return it.second.platformLayerChanged || it.second.platformLayerUpdated; });
                m_attributes.coordinateUpdateCompletionWithClient = coordinateUpdate;
            }
        }

        // Reset the needsResize attribute to false.
        m_attributes.needsResize = false;
    }

    if (needsResize)
        glViewport(0, 0, viewportSize.width(), viewportSize.height());

    TransformationMatrix viewportTransform;
    viewportTransform.scale(scaleFactor);
    viewportTransform.translate(-scrollPosition.x(), -scrollPosition.y());

    if (!drawsBackground) {
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    m_scene->applyStateChanges(states);
    m_scene->paintToCurrentGLContext(viewportTransform, 1, FloatRect { FloatPoint { }, viewportSize },
        Color::transparent, !drawsBackground, m_paintFlags);

    m_context->swapBuffers();

    if (m_scene->isActive())
        m_client.didRenderFrame();
}

void ThreadedCompositor::sceneUpdateFinished()
{
    // The composition has finished. Now we have to determine how to manage
    // the scene update completion.

    // The DisplayRefreshMonitor will be used to dispatch a callback on the client thread if:
    //  - clientRendersNextFrame is true (i.e. client has to be notified about the finished update), or
    //  - a DisplayRefreshMonitor callback was requested from the Web engine
    bool shouldDispatchDisplayRefreshCallback { false };

    // If coordinateUpdateCompletionWithClient is true, the scene update completion has to be
    // delayed until the DisplayRefreshMonitor callback.
    bool shouldCoordinateUpdateCompletionWithClient { false };

    {
        LockHolder locker(m_attributes.lock);
        shouldDispatchDisplayRefreshCallback = m_attributes.clientRendersNextFrame
            || m_displayRefreshMonitor->requiresDisplayRefreshCallback();
        shouldCoordinateUpdateCompletionWithClient = m_attributes.coordinateUpdateCompletionWithClient;
    }

    LockHolder stateLocker(m_compositingRunLoop->stateLock());

    // Schedule the DisplayRefreshMonitor callback, if necessary.
    if (shouldDispatchDisplayRefreshCallback)
        m_displayRefreshMonitor->dispatchDisplayRefreshCallback();

    // Mark the scene update as completed if no coordination is required and if not in a forced repaint.
    if (!shouldCoordinateUpdateCompletionWithClient && !m_inForceRepaint)
        m_compositingRunLoop->updateCompleted(stateLocker);

    // Independent of the scene update, the composition itself is now completed.
    m_compositingRunLoop->compositionCompleted(stateLocker);
}

void ThreadedCompositor::updateSceneState(const CoordinatedGraphicsState& state)
{
    LockHolder locker(m_attributes.lock);
    m_attributes.states.append(state);
    m_compositingRunLoop->scheduleUpdate();
}

#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
RefPtr<WebCore::DisplayRefreshMonitor> ThreadedCompositor::displayRefreshMonitor(PlatformDisplayID)
{
    return m_displayRefreshMonitor.copyRef();
}

void ThreadedCompositor::requestDisplayRefreshMonitorUpdate()
{
    // This is invoked by ThreadedDisplayRefreshMonitor when a fresh update is required.

    LockHolder stateLocker(m_compositingRunLoop->stateLock());
    {
        // coordinateUpdateCompletionWithClient is set to true in order to delay the scene update
        // completion until the DisplayRefreshMonitor is fired on the main thread after the composition
        // is completed.
        LockHolder locker(m_attributes.lock);
        m_attributes.coordinateUpdateCompletionWithClient = true;
    }
    m_compositingRunLoop->scheduleUpdate(stateLocker);
}

void ThreadedCompositor::handleDisplayRefreshMonitorUpdate(bool hasBeenRescheduled)
{
    // Retrieve the clientRendersNextFrame and coordinateUpdateCompletionWithClient.
    bool clientRendersNextFrame { false };
    bool coordinateUpdateCompletionWithClient { false };
    {
        LockHolder locker(m_attributes.lock);
        clientRendersNextFrame = std::exchange(m_attributes.clientRendersNextFrame, false);
        coordinateUpdateCompletionWithClient = std::exchange(m_attributes.coordinateUpdateCompletionWithClient, false);
    }

    // If clientRendersNextFrame is true, the client is finally notified about the scene update nearing
    // completion. The client will use this opportunity to clean up resources as appropriate. It can also
    // perform any layer flush that was requested during the composition, or by any DisplayRefreshMonitor
    // notifications that have been handled at this point.
    if (clientRendersNextFrame)
        m_client.renderNextFrame();

    LockHolder stateLocker(m_compositingRunLoop->stateLock());

    // If required, mark the current scene update as completed. CompositingRunLoop will take care of
    // scheduling a new update in case an update was marked as pending due to previous layer flushes
    // or DisplayRefreshMonitor notifications.
    if (coordinateUpdateCompletionWithClient)
        m_compositingRunLoop->updateCompleted(stateLocker);

    // If the DisplayRefreshMonitor was scheduled again, we immediately demand the update completion
    // coordination (like we do in requestDisplayRefreshMonitorUpdate()) and request an update.
    if (hasBeenRescheduled) {
        {
            LockHolder locker(m_attributes.lock);
            m_attributes.coordinateUpdateCompletionWithClient = true;
        }
        m_compositingRunLoop->scheduleUpdate(stateLocker);
    }
}
#endif

void ThreadedCompositor::frameComplete()
{
    ASSERT(!RunLoop::isMain());
    sceneUpdateFinished();
}

}
#endif // USE(COORDINATED_GRAPHICS_THREADED)
