1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "gl/GLTestContext.h"
10#import <OpenGLES/EAGL.h>
11#include <dlfcn.h>
12
13#define EAGLCTX ((EAGLContext*)(fEAGLContext))
14
15namespace {
16
17class IOSGLTestContext : public sk_gpu_test::GLTestContext {
18public:
19    IOSGLTestContext(IOSGLTestContext* shareContext);
20    ~IOSGLTestContext() override;
21
22private:
23    void destroyGLContext();
24
25    void onPlatformMakeCurrent() const override;
26    void onPlatformSwapBuffers() const override;
27    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
28
29    void* fEAGLContext;
30    void* fGLLibrary;
31};
32
33IOSGLTestContext::IOSGLTestContext(IOSGLTestContext* shareContext)
34    : fEAGLContext(NULL)
35    , fGLLibrary(RTLD_DEFAULT) {
36
37    if (shareContext) {
38        EAGLContext* iosShareContext = (EAGLContext*)(shareContext->fEAGLContext);
39        fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
40                                            sharegroup: [iosShareContext sharegroup]];
41    } else {
42        fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
43    }
44    [EAGLContext setCurrentContext:EAGLCTX];
45
46    sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
47    if (NULL == gl.get()) {
48        SkDebugf("Failed to create gl interface");
49        this->destroyGLContext();
50        return;
51    }
52    if (!gl->validate()) {
53        SkDebugf("Failed to validate gl interface");
54        this->destroyGLContext();
55        return;
56    }
57
58    fGLLibrary = dlopen(
59        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
60        RTLD_LAZY);
61
62    this->init(gl.release());
63}
64
65IOSGLTestContext::~IOSGLTestContext() {
66    this->teardown();
67    this->destroyGLContext();
68}
69
70void IOSGLTestContext::destroyGLContext() {
71    if (fEAGLContext) {
72        if ([EAGLContext currentContext] == EAGLCTX) {
73            [EAGLContext setCurrentContext:nil];
74        }
75        [EAGLCTX release];
76        fEAGLContext = NULL;
77    }
78    if (RTLD_DEFAULT != fGLLibrary) {
79        dlclose(fGLLibrary);
80    }
81}
82
83
84void IOSGLTestContext::onPlatformMakeCurrent() const {
85    if (![EAGLContext setCurrentContext:EAGLCTX]) {
86        SkDebugf("Could not set the context.\n");
87    }
88}
89
90void IOSGLTestContext::onPlatformSwapBuffers() const { }
91
92GrGLFuncPtr IOSGLTestContext::onPlatformGetProcAddress(const char* procName) const {
93    return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
94}
95
96}  // anonymous namespace
97
98namespace sk_gpu_test {
99GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
100                                           GLTestContext *shareContext) {
101    if (kGL_GrGLStandard == forcedGpuAPI) {
102        return NULL;
103    }
104    IOSGLTestContext* iosShareContext = reinterpret_cast<IOSGLTestContext*>(shareContext);
105    IOSGLTestContext *ctx = new IOSGLTestContext(iosShareContext);
106    if (!ctx->isValid()) {
107        delete ctx;
108        return NULL;
109    }
110    return ctx;
111}
112}
113