//
// Copyright (c) 2015 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.
//

// WindowSurfaceCGL.cpp: CGL implementation of egl::Surface for windows

#if __has_include(<Cocoa/Cocoa.h>)

#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"

#import <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#import <QuartzCore/QuartzCore.h>

#include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

@interface WebSwapLayer : CAOpenGLLayer
{
    CGLContextObj mDisplayContext;

    bool initialized;
    rx::SharedSwapState *mSwapState;
    const rx::FunctionsGL *mFunctions;

    GLuint mReadFramebuffer;
}
- (id)initWithSharedState:(rx::SharedSwapState *)swapState
              withContext:(CGLContextObj)displayContext
            withFunctions:(const rx::FunctionsGL *)functions;
@end

@implementation WebSwapLayer
- (id)initWithSharedState:(rx::SharedSwapState *)swapState
              withContext:(CGLContextObj)displayContext
            withFunctions:(const rx::FunctionsGL *)functions
    {
        self = [super init];
        if (self != nil)
        {
            self.asynchronous = YES;
            mDisplayContext   = displayContext;

            initialized = false;
            mSwapState  = swapState;
            mFunctions  = functions;

            [self setFrame:CGRectMake(0, 0, mSwapState->textures[0].width,
                                      mSwapState->textures[0].height)];
        }
        return self;
    }

    - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
    {
        CGLPixelFormatAttribute attribs[] = {
            kCGLPFADisplayMask, static_cast<CGLPixelFormatAttribute>(mask), kCGLPFAOpenGLProfile,
            static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_3_2_Core),
            static_cast<CGLPixelFormatAttribute>(0)};

        CGLPixelFormatObj pixelFormat = nullptr;
        GLint numFormats = 0;
        CGLChoosePixelFormat(attribs, &pixelFormat, &numFormats);

        return pixelFormat;
    }

    - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
    {
        CGLContextObj context = nullptr;
        CGLCreateContext(pixelFormat, mDisplayContext, &context);
        return context;
    }

    - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext
                    pixelFormat:(CGLPixelFormatObj)pixelFormat
                   forLayerTime:(CFTimeInterval)timeInterval
                    displayTime:(const CVTimeStamp *)timeStamp
    {
        BOOL result = NO;

        pthread_mutex_lock(&mSwapState->mutex);
        {
            if (mSwapState->lastRendered->swapId > mSwapState->beingPresented->swapId)
            {
                std::swap(mSwapState->lastRendered, mSwapState->beingPresented);
                result = YES;
            }
        }
        pthread_mutex_unlock(&mSwapState->mutex);

        return result;
    }

    - (void)drawInCGLContext:(CGLContextObj)glContext
                 pixelFormat:(CGLPixelFormatObj)pixelFormat
                forLayerTime:(CFTimeInterval)timeInterval
                 displayTime:(const CVTimeStamp *)timeStamp
    {
        CGLSetCurrentContext(glContext);
        if (!initialized)
        {
            initialized = true;

            mFunctions->genFramebuffers(1, &mReadFramebuffer);
        }

        const auto &texture = *mSwapState->beingPresented;
        if ([self frame].size.width != texture.width || [self frame].size.height != texture.height)
        {
            [self setFrame:CGRectMake(0, 0, texture.width, texture.height)];

            // Without this, the OSX compositor / window system doesn't see the resize.
            [self setNeedsDisplay];
        }

        // TODO(cwallez) support 2.1 contexts too that don't have blitFramebuffer nor the
        // GL_DRAW_FRAMEBUFFER_BINDING query
        GLint drawFBO;
        mFunctions->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFBO);

        mFunctions->bindFramebuffer(GL_FRAMEBUFFER, mReadFramebuffer);
        mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         texture.texture, 0);

        mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer);
        mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
        mFunctions->blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width,
                                    texture.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);

        // Call the super method to flush the context
        [super drawInCGLContext:glContext
                    pixelFormat:pixelFormat
                   forLayerTime:timeInterval
                    displayTime:timeStamp];
    }
    @end

    namespace rx
    {

    WindowSurfaceCGL::WindowSurfaceCGL(const egl::SurfaceState &state,
                                       RendererGL *renderer,
                                       EGLNativeWindowType layer,
                                       CGLContextObj context)
        : SurfaceGL(state),
          mSwapLayer(nil),
          mCurrentSwapId(0),
          mLayer(reinterpret_cast<CALayer *>(layer)),
          mContext(context),
          mFunctions(renderer->getFunctions()),
          mStateManager(renderer->getStateManager()),
          mDSRenderbuffer(0)
    {
        pthread_mutex_init(&mSwapState.mutex, nullptr);
}

WindowSurfaceCGL::~WindowSurfaceCGL()
{
    pthread_mutex_destroy(&mSwapState.mutex);

    if (mDSRenderbuffer != 0)
    {
        mFunctions->deleteRenderbuffers(1, &mDSRenderbuffer);
        mDSRenderbuffer = 0;
    }

    if (mSwapLayer != nil)
    {
        [mSwapLayer removeFromSuperlayer];
        [mSwapLayer release];
        mSwapLayer = nil;
    }

    for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i)
    {
        if (mSwapState.textures[i].texture != 0)
        {
            mFunctions->deleteTextures(1, &mSwapState.textures[i].texture);
            mSwapState.textures[i].texture = 0;
        }
    }
}

egl::Error WindowSurfaceCGL::initialize(const egl::Display *display)
{
    unsigned width  = getWidth();
    unsigned height = getHeight();

    for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i)
    {
        mFunctions->genTextures(1, &mSwapState.textures[i].texture);
        mStateManager->bindTexture(gl::TextureType::_2D, mSwapState.textures[i].texture);
        mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                               GL_UNSIGNED_BYTE, nullptr);
        mSwapState.textures[i].width  = width;
        mSwapState.textures[i].height = height;
        mSwapState.textures[i].swapId = 0;
    }
    mSwapState.beingRendered  = &mSwapState.textures[0];
    mSwapState.lastRendered   = &mSwapState.textures[1];
    mSwapState.beingPresented = &mSwapState.textures[2];

    mSwapLayer = [[WebSwapLayer alloc] initWithSharedState:&mSwapState
                                            withContext:mContext
                                          withFunctions:mFunctions];
    [mLayer addSublayer:mSwapLayer];

    mFunctions->genRenderbuffers(1, &mDSRenderbuffer);
    mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
    mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);

    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::makeCurrent(const gl::Context *context)
{
    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::swap(const gl::Context *context)
{
    const FunctionsGL *functions = GetFunctionsGL(context);
    StateManagerGL *stateManager = GetStateManagerGL(context);

    functions->flush();
    mSwapState.beingRendered->swapId = ++mCurrentSwapId;

    pthread_mutex_lock(&mSwapState.mutex);
    {
        std::swap(mSwapState.beingRendered, mSwapState.lastRendered);
    }
    pthread_mutex_unlock(&mSwapState.mutex);

    unsigned width  = getWidth();
    unsigned height = getHeight();
    auto &texture   = *mSwapState.beingRendered;

    if (texture.width != width || texture.height != height)
    {
        stateManager->bindTexture(gl::TextureType::_2D, texture.texture);
        functions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                              GL_UNSIGNED_BYTE, nullptr);

        stateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
        functions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);

        texture.width  = width;
        texture.height = height;
    }

    FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(context->getFramebuffer(0));
    stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebufferGL->getFramebufferID());
    functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                    mSwapState.beingRendered->texture, 0);

    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::postSubBuffer(const gl::Context *context,
                                           EGLint x,
                                           EGLint y,
                                           EGLint width,
                                           EGLint height)
{
    UNIMPLEMENTED();
    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value)
{
    UNIMPLEMENTED();
    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::bindTexImage(const gl::Context *context,
                                          gl::Texture *texture,
                                          EGLint buffer)
{
    UNIMPLEMENTED();
    return egl::Error(EGL_SUCCESS);
}

egl::Error WindowSurfaceCGL::releaseTexImage(const gl::Context *context, EGLint buffer)
{
    UNIMPLEMENTED();
    return egl::Error(EGL_SUCCESS);
}

void WindowSurfaceCGL::setSwapInterval(EGLint interval)
{
    // TODO(cwallez) investigate implementing swap intervals other than 0
}

EGLint WindowSurfaceCGL::getWidth() const
{
    return CGRectGetWidth([mLayer frame]);
}

EGLint WindowSurfaceCGL::getHeight() const
{
    return CGRectGetHeight([mLayer frame]);
}

EGLint WindowSurfaceCGL::isPostSubBufferSupported() const
{
    UNIMPLEMENTED();
    return EGL_FALSE;
}

EGLint WindowSurfaceCGL::getSwapBehavior() const
{
    return EGL_BUFFER_DESTROYED;
}

FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::Context *context,
                                                            const gl::FramebufferState &state)
{
    const FunctionsGL *functions = GetFunctionsGL(context);
    StateManagerGL *stateManager = GetStateManagerGL(context);

    GLuint framebuffer = 0;
    functions->genFramebuffers(1, &framebuffer);
    stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                    mSwapState.beingRendered->texture, 0);
    functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                       mDSRenderbuffer);

    return new FramebufferGL(state, framebuffer, true);
}

}  // namespace rx

#pragma clang diagnostic pop

#endif // __has_include(<Cocoa/Cocoa.h>)
