//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Stream.cpp: Implements the egl::Stream class, representing the stream
// where frames are streamed in. Implements EGLStreanKHR.

#include "libANGLE/Stream.h"

#include <platform/Platform.h>
#include <EGL/eglext.h>

#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/StreamProducerImpl.h"

namespace egl
{

Stream::Stream(Display *display, const AttributeMap &attribs)
    : mDisplay(display),
      mProducerImplementation(nullptr),
      mState(EGL_STREAM_STATE_CREATED_KHR),
      mProducerFrame(0),
      mConsumerFrame(0),
      mConsumerLatency(attribs.getAsInt(EGL_CONSUMER_LATENCY_USEC_KHR, 0)),
      mConsumerAcquireTimeout(attribs.getAsInt(EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0)),
      mPlaneCount(0),
      mConsumerType(ConsumerType::NoConsumer),
      mProducerType(ProducerType::NoProducer)
{
    for (auto &plane : mPlanes)
    {
        plane.textureUnit = -1;
        plane.texture     = nullptr;
    }
}

Stream::~Stream()
{
    SafeDelete(mProducerImplementation);
    for (auto &plane : mPlanes)
    {
        if (plane.texture != nullptr)
        {
            plane.texture->releaseStream();
        }
    }
}

void Stream::setConsumerLatency(EGLint latency)
{
    mConsumerLatency = latency;
}

EGLint Stream::getConsumerLatency() const
{
    return mConsumerLatency;
}

EGLuint64KHR Stream::getProducerFrame() const
{
    return mProducerFrame;
}

EGLuint64KHR Stream::getConsumerFrame() const
{
    return mConsumerFrame;
}

EGLenum Stream::getState() const
{
    return mState;
}

void Stream::setConsumerAcquireTimeout(EGLint timeout)
{
    mConsumerAcquireTimeout = timeout;
}

EGLint Stream::getConsumerAcquireTimeout() const
{
    return mConsumerAcquireTimeout;
}

Stream::ProducerType Stream::getProducerType() const
{
    return mProducerType;
}

Stream::ConsumerType Stream::getConsumerType() const
{
    return mConsumerType;
}

EGLint Stream::getPlaneCount() const
{
    return mPlaneCount;
}

rx::StreamProducerImpl *Stream::getImplementation()
{
    return mProducerImplementation;
}

Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context)
{
    ASSERT(mState == EGL_STREAM_STATE_CREATED_KHR);
    ASSERT(mConsumerType == ConsumerType::NoConsumer);
    ASSERT(mProducerType == ProducerType::NoProducer);
    ASSERT(context != nullptr);

    const auto &glState = context->getGLState();
    EGLenum bufferType = attributes.getAsInt(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
    if (bufferType == EGL_RGB_BUFFER)
    {
        mPlanes[0].texture = glState.getTargetTexture(GL_TEXTURE_EXTERNAL_OES);
        ASSERT(mPlanes[0].texture != nullptr);
        mPlanes[0].texture->bindStream(this);
        mConsumerType = ConsumerType::GLTextureRGB;
        mPlaneCount   = 1;
    }
    else
    {
        mPlaneCount = attributes.getAsInt(EGL_YUV_NUMBER_OF_PLANES_EXT, 2);
        ASSERT(mPlaneCount <= 3);
        for (EGLint i = 0; i < mPlaneCount; i++)
        {
            // Fetch all the textures
            mPlanes[i].textureUnit = attributes.getAsInt(EGL_YUV_PLANE0_TEXTURE_UNIT_NV + i, -1);
            if (mPlanes[i].textureUnit != EGL_NONE)
            {
                mPlanes[i].texture =
                    glState.getSamplerTexture(mPlanes[i].textureUnit, GL_TEXTURE_EXTERNAL_OES);
                ASSERT(mPlanes[i].texture != nullptr);
            }
        }

        // Bind them to the stream
        for (EGLint i = 0; i < mPlaneCount; i++)
        {
            if (mPlanes[i].textureUnit != EGL_NONE)
            {
                mPlanes[i].texture->bindStream(this);
            }
        }
        mConsumerType = ConsumerType::GLTextureYUV;
    }

    mContext = context;
    mState   = EGL_STREAM_STATE_CONNECTING_KHR;

    return Error(EGL_SUCCESS);
}

Error Stream::createProducerD3D11TextureNV12(const AttributeMap &attributes)
{
    ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR);
    ASSERT(mConsumerType == ConsumerType::GLTextureYUV);
    ASSERT(mProducerType == ProducerType::NoProducer);
    ASSERT(mPlaneCount == 2);

    mProducerImplementation = mDisplay->getImplementation()->createStreamProducerD3DTextureNV12(
        mConsumerType, attributes);
    mProducerType = ProducerType::D3D11TextureNV12;
    mState        = EGL_STREAM_STATE_EMPTY_KHR;

    return Error(EGL_SUCCESS);
}

// Called when the consumer of this stream starts using the stream
Error Stream::consumerAcquire()
{
    ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
           mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
    ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
           mConsumerType == ConsumerType::GLTextureYUV);
    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);

    mState = EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR;
    mConsumerFrame++;

    // Bind the planes to the gl textures
    for (int i = 0; i < mPlaneCount; i++)
    {
        if (mPlanes[i].texture != nullptr)
        {
            mPlanes[i].texture->acquireImageFromStream(
                mProducerImplementation->getGLFrameDescription(i));
        }
    }

    return Error(EGL_SUCCESS);
}

Error Stream::consumerRelease()
{
    ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
           mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
    ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
           mConsumerType == ConsumerType::GLTextureYUV);
    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);

    // Release the images
    for (int i = 0; i < mPlaneCount; i++)
    {
        if (mPlanes[i].texture != nullptr)
        {
            mPlanes[i].texture->releaseImageFromStream();
        }
    }

    return Error(EGL_SUCCESS);
}

bool Stream::isConsumerBoundToContext(const gl::Context *context) const
{
    ASSERT(context != nullptr);
    return (context == mContext);
}

Error Stream::validateD3D11NV12Texture(void *texture) const
{
    ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
           mConsumerType == ConsumerType::GLTextureYUV);
    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
    ASSERT(mProducerImplementation != nullptr);

    return mProducerImplementation->validateD3DNV12Texture(texture);
}

Error Stream::postD3D11NV12Texture(void *texture, const AttributeMap &attributes)
{
    ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
           mConsumerType == ConsumerType::GLTextureYUV);
    ASSERT(mProducerType == ProducerType::D3D11TextureNV12);

    mProducerImplementation->postD3DNV12Texture(texture, attributes);
    mProducerFrame++;

    mState = EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR;

    return Error(EGL_SUCCESS);
}

// This is called when a texture object associated with this stream is destroyed. Even if multiple
// textures are bound, one being destroyed invalidates the stream, so all the remaining textures
// will be released and the stream will be invalidated.
void Stream::releaseTextures()
{
    for (auto &plane : mPlanes)
    {
        if (plane.texture != nullptr)
        {
            plane.texture->releaseStream();
            plane.texture = nullptr;
        }
    }
    mConsumerType = ConsumerType::NoConsumer;
    mProducerType = ProducerType::NoProducer;
    mState        = EGL_STREAM_STATE_DISCONNECTED_KHR;
}

}  // namespace egl
