• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 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 #include "include/core/SkTypes.h"
9 
10 #include "tools/gpu/gl/GLTestContext.h"
11 #include "AvailabilityMacros.h"
12 
13 #include <OpenGL/OpenGL.h>
14 #include <dlfcn.h>
15 
16 namespace {
17 
context_restorer()18 std::function<void()> context_restorer() {
19     auto context = CGLGetCurrentContext();
20     return [context] { CGLSetCurrentContext(context); };
21 }
22 
23 class MacGLTestContext : public sk_gpu_test::GLTestContext {
24 public:
25     MacGLTestContext(MacGLTestContext* shareContext);
26     ~MacGLTestContext() override;
27 
28 private:
29     void destroyGLContext();
30 
31     void onPlatformMakeCurrent() const override;
32     std::function<void()> onPlatformGetAutoContextRestore() const override;
33     void onPlatformSwapBuffers() const override;
34     GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
35 
36     CGLContextObj fContext;
37     void* fGLLibrary;
38 };
39 
MacGLTestContext(MacGLTestContext * shareContext)40 MacGLTestContext::MacGLTestContext(MacGLTestContext* shareContext)
41     : fContext(nullptr)
42     , fGLLibrary(RTLD_DEFAULT) {
43     CGLPixelFormatAttribute attributes[] = {
44 #if MAC_OS_X_VERSION_10_7
45         kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
46 #endif
47         kCGLPFADoubleBuffer,
48         (CGLPixelFormatAttribute)0
49     };
50     CGLPixelFormatObj pixFormat;
51     GLint npix;
52 
53     CGLChoosePixelFormat(attributes, &pixFormat, &npix);
54 
55     if (nullptr == pixFormat) {
56         SkDebugf("CGLChoosePixelFormat failed.");
57         return;
58     }
59 
60     CGLCreateContext(pixFormat, shareContext ? shareContext->fContext : nullptr, &fContext);
61     CGLReleasePixelFormat(pixFormat);
62 
63     if (nullptr == fContext) {
64         SkDebugf("CGLCreateContext failed.");
65         return;
66     }
67 
68     SkScopeExit restorer(context_restorer());
69     CGLSetCurrentContext(fContext);
70 
71     auto gl = GrGLMakeNativeInterface();
72     if (!gl) {
73         SkDebugf("Context could not create GL interface.\n");
74         this->destroyGLContext();
75         return;
76     }
77     if (!gl->validate()) {
78         SkDebugf("Context could not validate GL interface.\n");
79         this->destroyGLContext();
80         return;
81     }
82 
83     fGLLibrary = dlopen(
84         "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
85         RTLD_LAZY);
86 
87     this->init(std::move(gl));
88 }
89 
~MacGLTestContext()90 MacGLTestContext::~MacGLTestContext() {
91     this->teardown();
92     this->destroyGLContext();
93 }
94 
destroyGLContext()95 void MacGLTestContext::destroyGLContext() {
96     if (fContext) {
97         if (CGLGetCurrentContext() == fContext) {
98             // This will ensure that the context is immediately deleted.
99             CGLSetCurrentContext(nullptr);
100         }
101         CGLReleaseContext(fContext);
102         fContext = nullptr;
103     }
104     if (nullptr != fGLLibrary) {
105         dlclose(fGLLibrary);
106     }
107 }
108 
onPlatformMakeCurrent() const109 void MacGLTestContext::onPlatformMakeCurrent() const {
110     CGLSetCurrentContext(fContext);
111 }
112 
onPlatformGetAutoContextRestore() const113 std::function<void()> MacGLTestContext::onPlatformGetAutoContextRestore() const {
114     if (CGLGetCurrentContext() == fContext) {
115         return nullptr;
116     }
117     return context_restorer();
118 }
119 
onPlatformSwapBuffers() const120 void MacGLTestContext::onPlatformSwapBuffers() const {
121     CGLFlushDrawable(fContext);
122 }
123 
onPlatformGetProcAddress(const char * procName) const124 GrGLFuncPtr MacGLTestContext::onPlatformGetProcAddress(const char* procName) const {
125     void* handle = (nullptr == fGLLibrary) ? RTLD_DEFAULT : fGLLibrary;
126     return reinterpret_cast<GrGLFuncPtr>(dlsym(handle, procName));
127 }
128 
129 }  // anonymous namespace
130 
131 namespace sk_gpu_test {
CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,GLTestContext * shareContext)132 GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
133                                            GLTestContext* shareContext) {
134     if (kGLES_GrGLStandard == forcedGpuAPI) {
135         return nullptr;
136     }
137     MacGLTestContext* macShareContext = reinterpret_cast<MacGLTestContext*>(shareContext);
138     MacGLTestContext* ctx = new MacGLTestContext(macShareContext);
139     if (!ctx->isValid()) {
140         delete ctx;
141         return nullptr;
142     }
143     return ctx;
144 }
145 }  // namespace sk_gpu_test
146