
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/gpu/gl/GLTestContext.h"
#import <OpenGLES/EAGL.h>
#include <dlfcn.h>

#define EAGLCTX ((EAGLContext*)(fEAGLContext))

namespace {

std::function<void()> context_restorer() {
    EAGLContext* context = [EAGLContext currentContext];
    return [context] { [EAGLContext setCurrentContext:context]; };
}

class IOSGLTestContext : public sk_gpu_test::GLTestContext {
public:
    IOSGLTestContext(IOSGLTestContext* shareContext);
    ~IOSGLTestContext() override;

private:
    void destroyGLContext();

    void onPlatformMakeNotCurrent() const override;
    void onPlatformMakeCurrent() const override;
    std::function<void()> onPlatformGetAutoContextRestore() const override;
    void onPlatformSwapBuffers() const override;
    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;

    EAGLContext* fEAGLContext;
    void* fGLLibrary;
};

IOSGLTestContext::IOSGLTestContext(IOSGLTestContext* shareContext)
    : fEAGLContext(NULL)
    , fGLLibrary(RTLD_DEFAULT) {

    if (shareContext) {
        EAGLContext* iosShareContext = shareContext->fEAGLContext;
        fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
                                            sharegroup:[iosShareContext sharegroup]];
        if (fEAGLContext == nil) {
            fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
                                                sharegroup:[iosShareContext sharegroup]];
        }
    } else {
        fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
        if (fEAGLContext == nil) {
            fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        }
    }
    SkScopeExit restorer(context_restorer());
    [EAGLContext setCurrentContext:fEAGLContext];

    sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
    if (NULL == gl.get()) {
        SkDebugf("Failed to create gl interface");
        this->destroyGLContext();
        return;
    }
    if (!gl->validate()) {
        SkDebugf("Failed to validate gl interface");
        this->destroyGLContext();
        return;
    }

    fGLLibrary = dlopen(
        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
        RTLD_LAZY);

    this->init(std::move(gl));
}

IOSGLTestContext::~IOSGLTestContext() {
    this->teardown();
    this->destroyGLContext();
}

void IOSGLTestContext::destroyGLContext() {
    if (fEAGLContext) {
        if ([EAGLContext currentContext] == fEAGLContext) {
            // This will ensure that the context is immediately deleted.
            [EAGLContext setCurrentContext:nil];
        }
        fEAGLContext = nil;
    }
    if (nullptr != fGLLibrary) {
        dlclose(fGLLibrary);
    }
}

void IOSGLTestContext::onPlatformMakeNotCurrent() const {
    if (![EAGLContext setCurrentContext:nil]) {
        SkDebugf("Could not reset the context.\n");
    }
}

void IOSGLTestContext::onPlatformMakeCurrent() const {
    if (![EAGLContext setCurrentContext:fEAGLContext]) {
        SkDebugf("Could not set the context.\n");
    }
}

std::function<void()> IOSGLTestContext::onPlatformGetAutoContextRestore() const {
    if ([EAGLContext currentContext] == fEAGLContext) {
        return nullptr;
    }
    return context_restorer();
}

void IOSGLTestContext::onPlatformSwapBuffers() const { }

GrGLFuncPtr IOSGLTestContext::onPlatformGetProcAddress(const char* procName) const {
    void* handle = (nullptr == fGLLibrary) ? RTLD_DEFAULT : fGLLibrary;
    return reinterpret_cast<GrGLFuncPtr>(dlsym(handle, procName));
}

}  // anonymous namespace

namespace sk_gpu_test {
GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
                                           GLTestContext *shareContext) {
    if (kGL_GrGLStandard == forcedGpuAPI) {
        return NULL;
    }
    IOSGLTestContext* iosShareContext = reinterpret_cast<IOSGLTestContext*>(shareContext);
    IOSGLTestContext *ctx = new IOSGLTestContext(iosShareContext);
    if (!ctx->isValid()) {
        delete ctx;
        return NULL;
    }
    return ctx;
}
}
