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