Flutter Engine
The Flutter Engine
CreatePlatformGLTestContext_mac.cpp
Go to the documentation of this file.
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 */
9
12
13#include <OpenGL/OpenGL.h>
14#include <dlfcn.h>
15
16namespace {
17
18std::function<void()> context_restorer() {
19 auto context = CGLGetCurrentContext();
20 return [context] { CGLSetCurrentContext(context); };
21}
22
23class MacGLTestContext : public sk_gpu_test::GLTestContext {
24public:
25 MacGLTestContext(MacGLTestContext* shareContext);
26 ~MacGLTestContext() override;
27
28private:
29 void destroyGLContext();
30
31 void onPlatformMakeNotCurrent() const override;
32 void onPlatformMakeCurrent() const override;
33 std::function<void()> onPlatformGetAutoContextRestore() const override;
34 GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
35
36 CGLContextObj fContext;
37 void* fGLLibrary;
38};
39
40MacGLTestContext::MacGLTestContext(MacGLTestContext* shareContext)
41 : fContext(nullptr)
42 , fGLLibrary(RTLD_DEFAULT) {
43 // We first try to request a Radeon eGPU if one is available.
44 // This will be a Radeon HD7000 and up, which includes all eGPU configs.
45 // If that fails, we try again with only the base parameters.
46 CGLPixelFormatAttribute attributes[] = {
47 // base parameters
48 kCGLPFAOpenGLProfile,
49 (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
50 kCGLPFADoubleBuffer,
51
52 // eGPU parameters
53 kCGLPFAAllowOfflineRenderers, // Enables e-GPU.
54 kCGLPFANoRecovery, // Disallows software rendering.
55 kCGLPFARendererID, (CGLPixelFormatAttribute)kCGLRendererATIRadeonX4000ID, // Select Radeon
56 (CGLPixelFormatAttribute)NULL
57 };
58 static const int kFirstEGPUParameter = 3;
59 SkASSERT(kCGLPFAAllowOfflineRenderers == attributes[kFirstEGPUParameter]);
60
61 CGLPixelFormatObj pixFormat;
62 GLint npix;
63 CGLChoosePixelFormat(attributes, &pixFormat, &npix);
64
65 if (nullptr == pixFormat) {
66 // Move the NULL-termination up to remove the eGPU parameters and try again
67 attributes[kFirstEGPUParameter] = (CGLPixelFormatAttribute)NULL;
68 CGLChoosePixelFormat(attributes, &pixFormat, &npix);
69 }
70 if (nullptr == pixFormat) {
71 SkDebugf("CGLChoosePixelFormat failed.");
72 return;
73 }
74
75 CGLCreateContext(pixFormat, shareContext ? shareContext->fContext : nullptr, &fContext);
76 CGLReleasePixelFormat(pixFormat);
77
78 if (nullptr == fContext) {
79 SkDebugf("CGLCreateContext failed.");
80 return;
81 }
82
83 SkScopeExit restorer(context_restorer());
84 CGLSetCurrentContext(fContext);
85
87 if (!gl) {
88 SkDebugf("Context could not create GL interface.\n");
89 this->destroyGLContext();
90 return;
91 }
92 if (!gl->validate()) {
93 SkDebugf("Context could not validate GL interface.\n");
94 this->destroyGLContext();
95 return;
96 }
97
98 fGLLibrary = dlopen(
99 "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
100 RTLD_LAZY);
101
102 this->init(std::move(gl));
103}
104
105MacGLTestContext::~MacGLTestContext() {
106 this->teardown();
107 this->destroyGLContext();
108}
109
110void MacGLTestContext::destroyGLContext() {
111 if (fContext) {
112 if (CGLGetCurrentContext() == fContext) {
113 // This will ensure that the context is immediately deleted.
114 CGLSetCurrentContext(nullptr);
115 }
116 CGLReleaseContext(fContext);
117 fContext = nullptr;
118 }
119 if (nullptr != fGLLibrary) {
120 dlclose(fGLLibrary);
121 }
122}
123
124void MacGLTestContext::onPlatformMakeNotCurrent() const {
125 CGLSetCurrentContext(nullptr);
126}
127
128void MacGLTestContext::onPlatformMakeCurrent() const {
129 CGLSetCurrentContext(fContext);
130}
131
132std::function<void()> MacGLTestContext::onPlatformGetAutoContextRestore() const {
133 if (CGLGetCurrentContext() == fContext) {
134 return nullptr;
135 }
136 return context_restorer();
137}
138
139GrGLFuncPtr MacGLTestContext::onPlatformGetProcAddress(const char* procName) const {
140 void* handle = (nullptr == fGLLibrary) ? RTLD_DEFAULT : fGLLibrary;
141 return reinterpret_cast<GrGLFuncPtr>(dlsym(handle, procName));
142}
143
144} // anonymous namespace
145
146namespace sk_gpu_test {
147GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
148 GLTestContext* shareContext) {
149 if (kGLES_GrGLStandard == forcedGpuAPI) {
150 return nullptr;
151 }
152 MacGLTestContext* macShareContext = reinterpret_cast<MacGLTestContext*>(shareContext);
153 MacGLTestContext* ctx = new MacGLTestContext(macShareContext);
154 if (!ctx->isValid()) {
155 delete ctx;
156 return nullptr;
157 }
158 return ctx;
159}
160} // namespace sk_gpu_test
void(* GrGLFuncPtr)()
Definition: GrGLInterface.h:17
GrGLStandard
Definition: GrGLTypes.h:19
@ kGLES_GrGLStandard
Definition: GrGLTypes.h:22
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
const Context & fContext
Dart_NativeFunction function
Definition: fuchsia.cc:51
SK_API sk_sp< const GrGLInterface > MakeMac()
static bool init()
gl
Definition: malisc.py:41
GLTestContext * CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext *shareContext)