| /* | |
| * Copyright 2011 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SkTypes.h" | |
| #if defined(SK_BUILD_FOR_MAC) | |
| #include "gl/SkGLContext.h" | |
| #include "AvailabilityMacros.h" | |
| #include <OpenGL/OpenGL.h> | |
| #include <dlfcn.h> | |
| namespace { | |
| class MacGLContext : public SkGLContext { | |
| public: | |
| MacGLContext(); | |
| ~MacGLContext() override; | |
| private: | |
| void destroyGLContext(); | |
| void onPlatformMakeCurrent() const override; | |
| void onPlatformSwapBuffers() const override; | |
| GrGLFuncPtr onPlatformGetProcAddress(const char*) const override; | |
| CGLContextObj fContext; | |
| void* fGLLibrary; | |
| }; | |
| MacGLContext::MacGLContext() | |
| : fContext(nullptr) | |
| , fGLLibrary(RTLD_DEFAULT) { | |
| CGLPixelFormatAttribute attributes[] = { | |
| #if MAC_OS_X_VERSION_10_7 | |
| kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, | |
| #endif | |
| kCGLPFADoubleBuffer, | |
| (CGLPixelFormatAttribute)0 | |
| }; | |
| CGLPixelFormatObj pixFormat; | |
| GLint npix; | |
| CGLChoosePixelFormat(attributes, &pixFormat, &npix); | |
| if (nullptr == pixFormat) { | |
| SkDebugf("CGLChoosePixelFormat failed."); | |
| return; | |
| } | |
| CGLCreateContext(pixFormat, nullptr, &fContext); | |
| CGLReleasePixelFormat(pixFormat); | |
| if (nullptr == fContext) { | |
| SkDebugf("CGLCreateContext failed."); | |
| return; | |
| } | |
| CGLSetCurrentContext(fContext); | |
| SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface()); | |
| if (nullptr == gl.get()) { | |
| SkDebugf("Context could not create GL interface.\n"); | |
| this->destroyGLContext(); | |
| return; | |
| } | |
| if (!gl->validate()) { | |
| SkDebugf("Context could not validate GL interface.\n"); | |
| this->destroyGLContext(); | |
| return; | |
| } | |
| fGLLibrary = dlopen( | |
| "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", | |
| RTLD_LAZY); | |
| this->init(gl.detach()); | |
| } | |
| MacGLContext::~MacGLContext() { | |
| this->teardown(); | |
| this->destroyGLContext(); | |
| } | |
| void MacGLContext::destroyGLContext() { | |
| if (fContext) { | |
| CGLReleaseContext(fContext); | |
| fContext = nullptr; | |
| } | |
| if (RTLD_DEFAULT != fGLLibrary) { | |
| dlclose(fGLLibrary); | |
| } | |
| } | |
| void MacGLContext::onPlatformMakeCurrent() const { | |
| CGLSetCurrentContext(fContext); | |
| } | |
| void MacGLContext::onPlatformSwapBuffers() const { | |
| CGLFlushDrawable(fContext); | |
| } | |
| GrGLFuncPtr MacGLContext::onPlatformGetProcAddress(const char* procName) const { | |
| return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName)); | |
| } | |
| } // anonymous namespace | |
| SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI, SkGLContext* shareContext) { | |
| SkASSERT(!shareContext); | |
| if (shareContext) { | |
| return nullptr; | |
| } | |
| if (kGLES_GrGLStandard == forcedGpuAPI) { | |
| return nullptr; | |
| } | |
| MacGLContext* ctx = new MacGLContext; | |
| if (!ctx->isValid()) { | |
| delete ctx; | |
| return nullptr; | |
| } | |
| return ctx; | |
| } | |
| #endif//defined(SK_BUILD_FOR_MAC) |