/*
 * Copyright (C) 2015 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 "TextureMapperPlatformLayerProxy.h"

#if USE(COORDINATED_GRAPHICS)

#include "BitmapTextureGL.h"
#include "TextureMapperGL.h"
#include "TextureMapperLayer.h"
#include "TextureMapperPlatformLayerBuffer.h"

#if USE(GLIB_EVENT_LOOP)
#include <wtf/glib/RunLoopSourcePriority.h>
#endif
#include <wtf/Scope.h>

static const Seconds releaseUnusedSecondsTolerance { 1_s };
static const Seconds releaseUnusedBuffersTimerInterval = { 500_ms };

namespace WebCore {

TextureMapperPlatformLayerProxy::TextureMapperPlatformLayerProxy()
    : m_compositor(nullptr)
    , m_targetLayer(nullptr)
{
}

TextureMapperPlatformLayerProxy::~TextureMapperPlatformLayerProxy()
{
    Locker locker { m_lock };
    if (m_targetLayer)
        m_targetLayer->setContentsLayer(nullptr);
}

void TextureMapperPlatformLayerProxy::activateOnCompositingThread(Compositor* compositor, TextureMapperLayer* targetLayer)
{
#ifndef NDEBUG
    if (!m_compositorThread)
        m_compositorThread = &Thread::current();
#endif
    ASSERT(m_compositorThread == &Thread::current());
    ASSERT(compositor);
    ASSERT(targetLayer);
    Function<void()> updateFunction;
    {
        Locker locker { m_lock };
        m_compositor = compositor;
        m_targetLayer = targetLayer;
        if (m_targetLayer && m_currentBuffer)
            m_targetLayer->setContentsLayer(m_currentBuffer.get());

        m_releaseUnusedBuffersTimer = makeUnique<RunLoop::Timer<TextureMapperPlatformLayerProxy>>(RunLoop::current(), this, &TextureMapperPlatformLayerProxy::releaseUnusedBuffersTimerFired);
        m_compositorThreadUpdateTimer = makeUnique<RunLoop::Timer<TextureMapperPlatformLayerProxy>>(RunLoop::current(), this, &TextureMapperPlatformLayerProxy::compositorThreadUpdateTimerFired);

#if USE(GLIB_EVENT_LOOP)
        m_compositorThreadUpdateTimer->setPriority(RunLoopSourcePriority::CompositingThreadUpdateTimer);
        m_releaseUnusedBuffersTimer->setPriority(RunLoopSourcePriority::ReleaseUnusedResourcesTimer);
#endif

        if (!m_compositorThreadUpdateFunction)
            return;
        updateFunction = WTFMove(m_compositorThreadUpdateFunction);
    }
    updateFunction();
}

void TextureMapperPlatformLayerProxy::invalidate()
{
    ASSERT(m_compositorThread == &Thread::current());
    Function<void()> updateFunction;
    {
        Locker locker { m_lock };
        m_compositor = nullptr;
        m_targetLayer = nullptr;

        m_currentBuffer = nullptr;
        m_pendingBuffer = nullptr;
        m_releaseUnusedBuffersTimer = nullptr;
        m_usedBuffers.clear();

        // Clear the timer and dispatch the update function manually now.
        m_compositorThreadUpdateTimer = nullptr;
        if (!m_compositorThreadUpdateFunction)
            return;
        updateFunction = WTFMove(m_compositorThreadUpdateFunction);
    }

    updateFunction();
}

bool TextureMapperPlatformLayerProxy::isActive()
{
    ASSERT(m_lock.isHeld());
    return !!m_targetLayer && !!m_compositor;
}

void TextureMapperPlatformLayerProxy::pushNextBuffer(std::unique_ptr<TextureMapperPlatformLayerBuffer>&& newBuffer)
{
    ASSERT(m_lock.isHeld());
#if USE(ANGLE)
    // When the newBuffer overwrites m_pendingBuffer that is not swapped yet,
    // the layer related to m_pendingBuffer is flickering since its texture is destroyed.
    if (m_pendingBuffer && m_pendingBuffer->hasManagedTexture())
        return;
#endif
    m_pendingBuffer = WTFMove(newBuffer);
    m_wasBufferDropped = false;

    if (m_compositor)
        m_compositor->onNewBufferAvailable();
}

std::unique_ptr<TextureMapperPlatformLayerBuffer> TextureMapperPlatformLayerProxy::getAvailableBuffer(const IntSize& size, GLint internalFormat)
{
    ASSERT(m_lock.isHeld());
    ASSERT(m_compositorThread == &Thread::current());
    std::unique_ptr<TextureMapperPlatformLayerBuffer> availableBuffer;

    auto buffers = WTFMove(m_usedBuffers);
    for (auto& buffer : buffers) {
        if (!buffer)
            continue;

        if (!availableBuffer && buffer->canReuseWithoutReset(size, internalFormat)) {
            availableBuffer = WTFMove(buffer);
            availableBuffer->markUsed();
            continue;
        }
        m_usedBuffers.append(WTFMove(buffer));
    }

    if (!m_usedBuffers.isEmpty())
        scheduleReleaseUnusedBuffers();
    return availableBuffer;
}

void TextureMapperPlatformLayerProxy::appendToUnusedBuffers(std::unique_ptr<TextureMapperPlatformLayerBuffer> buffer)
{
    ASSERT(m_lock.isHeld());
    ASSERT(m_compositorThread == &Thread::current());
    m_usedBuffers.append(WTFMove(buffer));
    scheduleReleaseUnusedBuffers();
}

void TextureMapperPlatformLayerProxy::scheduleReleaseUnusedBuffers()
{
    if (!m_releaseUnusedBuffersTimer->isActive())
        m_releaseUnusedBuffersTimer->startOneShot(releaseUnusedBuffersTimerInterval);
}

void TextureMapperPlatformLayerProxy::releaseUnusedBuffersTimerFired()
{
    Locker locker { m_lock };
    if (m_usedBuffers.isEmpty())
        return;

    auto buffers = WTFMove(m_usedBuffers);
    MonotonicTime minUsedTime = MonotonicTime::now() - releaseUnusedSecondsTolerance;

    for (auto& buffer : buffers) {
        if (buffer && buffer->lastUsedTime() >= minUsedTime)
            m_usedBuffers.append(WTFMove(buffer));
    }
}

void TextureMapperPlatformLayerProxy::swapBuffer()
{
    ASSERT(m_compositorThread == &Thread::current());
    Locker locker { m_lock };
    if (!m_targetLayer || !m_pendingBuffer)
        return;

    auto prevBuffer = WTFMove(m_currentBuffer);

    m_currentBuffer = WTFMove(m_pendingBuffer);
    m_targetLayer->setContentsLayer(m_currentBuffer.get());

    if (prevBuffer && prevBuffer->hasManagedTexture())
        appendToUnusedBuffers(WTFMove(prevBuffer));
}

void TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture(bool shouldWait)
{
    if (!shouldWait)
        ASSERT(m_lock.isHeld());

    if (m_pendingBuffer && m_pendingBuffer->hasManagedTexture()) {
        m_usedBuffers.append(WTFMove(m_pendingBuffer));
        scheduleReleaseUnusedBuffers();
    }

    if (!m_compositorThreadUpdateTimer)
        return;

    m_compositorThreadUpdateFunction =
        [this, shouldWait] {
            Locker locker { m_lock };

            auto maybeNotifySynchronousOperation = makeScopeExit([this, shouldWait]() {
                if (shouldWait) {
                    Locker locker { m_wasBufferDroppedLock };
                    m_wasBufferDropped = true;
                    m_wasBufferDroppedCondition.notifyAll();
                }
            });

            if (!m_compositor || !m_targetLayer || !m_currentBuffer)
                return;

            m_pendingBuffer = m_currentBuffer->clone();
            auto prevBuffer = WTFMove(m_currentBuffer);
            m_currentBuffer = WTFMove(m_pendingBuffer);
            m_targetLayer->setContentsLayer(m_currentBuffer.get());

            if (prevBuffer->hasManagedTexture())
                appendToUnusedBuffers(WTFMove(prevBuffer));
        };

    if (shouldWait) {
        Locker locker { m_wasBufferDroppedLock };
        m_wasBufferDropped = false;
    }

    m_compositorThreadUpdateTimer->startOneShot(0_s);
    if (shouldWait) {
        Locker locker { m_wasBufferDroppedLock };
        m_wasBufferDroppedCondition.wait(m_wasBufferDroppedLock, [this] {
            assertIsHeld(m_wasBufferDroppedLock);
            return m_wasBufferDropped;
        });
    }
}

bool TextureMapperPlatformLayerProxy::scheduleUpdateOnCompositorThread(Function<void()>&& updateFunction)
{
    Locker locker { m_lock };
    m_compositorThreadUpdateFunction = WTFMove(updateFunction);

    if (!m_compositorThreadUpdateTimer)
        return false;

    m_compositorThreadUpdateTimer->startOneShot(0_s);
    return true;
}

void TextureMapperPlatformLayerProxy::compositorThreadUpdateTimerFired()
{
    Function<void()> updateFunction;
    {
        Locker locker { m_lock };
        if (!m_compositorThreadUpdateFunction)
            return;
        updateFunction = WTFMove(m_compositorThreadUpdateFunction);
    }

    updateFunction();
}

} // namespace WebCore

#endif // USE(COORDINATED_GRAPHICS)
