
/*
 * 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 "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 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::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;
}
}
