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