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/SkGLContext.h"
10#import <OpenGLES/EAGL.h>
11#include <dlfcn.h>
12
13#define EAGLCTX ((EAGLContext*)(fEAGLContext))
14
15namespace {
16
17class IOSGLContext : public SkGLContext {
18public:
19    IOSGLContext();
20    ~IOSGLContext() 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
33IOSGLContext::IOSGLContext()
34    : fEAGLContext(NULL)
35    , fGLLibrary(RTLD_DEFAULT) {
36
37    fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
38    [EAGLContext setCurrentContext:EAGLCTX];
39
40    SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
41    if (NULL == gl.get()) {
42        SkDebugf("Failed to create gl interface");
43        this->destroyGLContext();
44        return;
45    }
46    if (!gl->validate()) {
47        SkDebugf("Failed to validate gl interface");
48        this->destroyGLContext();
49        return;
50    }
51
52    fGLLibrary = dlopen(
53        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
54        RTLD_LAZY);
55
56    this->init(gl.detach());
57}
58
59IOSGLContext::~IOSGLContext() {
60    this->teardown();
61    this->destroyGLContext();
62}
63
64void IOSGLContext::destroyGLContext() {
65    if (fEAGLContext) {
66        if ([EAGLContext currentContext] == EAGLCTX) {
67            [EAGLContext setCurrentContext:nil];
68        }
69        [EAGLCTX release];
70        fEAGLContext = NULL;
71    }
72    if (RTLD_DEFAULT != fGLLibrary) {
73        dlclose(fGLLibrary);
74    }
75}
76
77
78void IOSGLContext::onPlatformMakeCurrent() const {
79    if (![EAGLContext setCurrentContext:EAGLCTX]) {
80        SkDebugf("Could not set the context.\n");
81    }
82}
83
84void IOSGLContext::onPlatformSwapBuffers() const { }
85
86GrGLFuncPtr IOSGLContext::onPlatformGetProcAddress(const char* procName) const {
87    return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
88}
89
90} // anonymous namespace
91
92SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI, SkGLContext* shareContext) {
93    SkASSERT(!shareContext);
94    if (shareContext) {
95        return NULL;
96    }
97    if (kGL_GrGLStandard == forcedGpuAPI) {
98        return NULL;
99    }
100    IOSGLContext* ctx = new IOSGLContext;
101    if (!ctx->isValid()) {
102        delete ctx;
103        return NULL;
104    }
105    return ctx;
106}
107