• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "tools/gpu/gl/GLTestContext.h"
10#import <OpenGLES/EAGL.h>
11#include <dlfcn.h>
12
13#include "include/ports/SkCFObject.h"
14
15#define EAGLCTX ((EAGLContext*)(fEAGLContext))
16
17namespace {
18
19std::function<void()> context_restorer() {
20    EAGLContext* context = [EAGLContext currentContext];
21    return [context] { [EAGLContext setCurrentContext:context]; };
22}
23
24class IOSGLTestContext : public sk_gpu_test::GLTestContext {
25public:
26    IOSGLTestContext(IOSGLTestContext* shareContext);
27    ~IOSGLTestContext() override;
28
29private:
30    void destroyGLContext();
31
32    void onPlatformMakeNotCurrent() const override;
33    void onPlatformMakeCurrent() const override;
34    std::function<void()> onPlatformGetAutoContextRestore() const override;
35    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
36
37    sk_cfp<EAGLContext*> fEAGLContext;
38    void* fGLLibrary;
39};
40
41IOSGLTestContext::IOSGLTestContext(IOSGLTestContext* shareContext)
42    : fGLLibrary(RTLD_DEFAULT) {
43
44    if (shareContext) {
45        EAGLContext* iosShareContext = shareContext->fEAGLContext.get();
46        fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
47                                                 sharegroup:[iosShareContext sharegroup]]);
48        if (!fEAGLContext) {
49            fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
50                                                     sharegroup:[iosShareContext sharegroup]]);
51        }
52    } else {
53        fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]);
54        if (!fEAGLContext) {
55            fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]);
56        }
57    }
58    SkScopeExit restorer(context_restorer());
59    [EAGLContext setCurrentContext:fEAGLContext.get()];
60
61    sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
62    if (NULL == gl.get()) {
63        SkDebugf("Failed to create gl interface");
64        this->destroyGLContext();
65        return;
66    }
67    if (!gl->validate()) {
68        SkDebugf("Failed to validate gl interface");
69        this->destroyGLContext();
70        return;
71    }
72
73    fGLLibrary = dlopen(
74        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
75        RTLD_LAZY);
76
77    this->init(std::move(gl));
78}
79
80IOSGLTestContext::~IOSGLTestContext() {
81    this->teardown();
82    this->destroyGLContext();
83}
84
85void IOSGLTestContext::destroyGLContext() {
86    if (fEAGLContext) {
87        if ([EAGLContext currentContext] == fEAGLContext.get()) {
88            // This will ensure that the context is immediately deleted.
89            [EAGLContext setCurrentContext:nil];
90        }
91        fEAGLContext.reset();
92    }
93    if (nullptr != fGLLibrary) {
94        dlclose(fGLLibrary);
95    }
96}
97
98void IOSGLTestContext::onPlatformMakeNotCurrent() const {
99    if (![EAGLContext setCurrentContext:nil]) {
100        SkDebugf("Could not reset the context.\n");
101    }
102}
103
104void IOSGLTestContext::onPlatformMakeCurrent() const {
105    if (![EAGLContext setCurrentContext:fEAGLContext.get()]) {
106        SkDebugf("Could not set the context.\n");
107    }
108}
109
110std::function<void()> IOSGLTestContext::onPlatformGetAutoContextRestore() const {
111    if ([EAGLContext currentContext] == fEAGLContext.get()) {
112        return nullptr;
113    }
114    return context_restorer();
115}
116
117GrGLFuncPtr IOSGLTestContext::onPlatformGetProcAddress(const char* procName) const {
118    void* handle = (nullptr == fGLLibrary) ? RTLD_DEFAULT : fGLLibrary;
119    return reinterpret_cast<GrGLFuncPtr>(dlsym(handle, procName));
120}
121
122}  // anonymous namespace
123
124namespace sk_gpu_test {
125GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
126                                           GLTestContext *shareContext) {
127    if (kGL_GrGLStandard == forcedGpuAPI) {
128        return NULL;
129    }
130    IOSGLTestContext* iosShareContext = reinterpret_cast<IOSGLTestContext*>(shareContext);
131    IOSGLTestContext *ctx = new IOSGLTestContext(iosShareContext);
132    if (!ctx->isValid()) {
133        delete ctx;
134        return NULL;
135    }
136    return ctx;
137}
138}
139