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/SkGLContext.h"
     10 #import <OpenGLES/EAGL.h>
     11 #include <dlfcn.h>
     12 
     13 #define EAGLCTX ((EAGLContext*)(fEAGLContext))
     14 
     15 namespace {
     16 
     17 class IOSGLContext : public SkGLContext {
     18 public:
     19     IOSGLContext();
     20     ~IOSGLContext() override;
     21 
     22 private:
     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 
     33 IOSGLContext::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 
     59 IOSGLContext::~IOSGLContext() {
     60     this->teardown();
     61     this->destroyGLContext();
     62 }
     63 
     64 void 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 
     78 void IOSGLContext::onPlatformMakeCurrent() const {
     79     if (![EAGLContext setCurrentContext:EAGLCTX]) {
     80         SkDebugf("Could not set the context.\n");
     81     }
     82 }
     83 
     84 void IOSGLContext::onPlatformSwapBuffers() const { }
     85 
     86 GrGLFuncPtr IOSGLContext::onPlatformGetProcAddress(const char* procName) const {
     87     return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
     88 }
     89 
     90 } // anonymous namespace
     91 
     92 SkGLContext* 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