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