OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2015 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 "SkOnce.h" | |
10 #include "gl/GrGLInterface.h" | |
11 #include "gl/GrGLAssembleInterface.h" | |
12 #include "gl/command_buffer/GLTestContext_command_buffer.h" | |
13 #include "../ports/SkOSEnvironment.h" | |
14 #include "../ports/SkOSLibrary.h" | |
15 | |
16 #if defined SK_BUILD_FOR_MAC | |
17 | |
18 // EGL doesn't exist on the mac, so expose what we need to get the command buffe
r's EGL running. | |
19 typedef void *EGLDisplay; | |
20 typedef unsigned int EGLBoolean; | |
21 typedef void *EGLConfig; | |
22 typedef void *EGLSurface; | |
23 typedef void *EGLContext; | |
24 typedef int32_t EGLint; | |
25 typedef void* EGLNativeDisplayType; | |
26 typedef void* EGLNativeWindowType; | |
27 typedef void (*__eglMustCastToProperFunctionPointerType)(void); | |
28 #define EGL_FALSE 0 | |
29 #define EGL_OPENGL_ES2_BIT 0x0004 | |
30 #define EGL_CONTEXT_CLIENT_VERSION 0x3098 | |
31 #define EGL_NO_SURFACE ((EGLSurface)0) | |
32 #define EGL_NO_DISPLAY ((EGLDisplay)0) | |
33 #define EGL_NO_CONTEXT ((EGLContext)0) | |
34 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) | |
35 #define EGL_SURFACE_TYPE 0x3033 | |
36 #define EGL_PBUFFER_BIT 0x0001 | |
37 #define EGL_RENDERABLE_TYPE 0x3040 | |
38 #define EGL_RED_SIZE 0x3024 | |
39 #define EGL_GREEN_SIZE 0x3023 | |
40 #define EGL_BLUE_SIZE 0x3022 | |
41 #define EGL_ALPHA_SIZE 0x3021 | |
42 #define EGL_DEPTH_SIZE 0x3025 | |
43 #define EGL_STENCIL_SIZE 0x3025 | |
44 #define EGL_SAMPLES 0x3031 | |
45 #define EGL_SAMPLE_BUFFERS 0x3032 | |
46 #define EGL_NONE 0x3038 | |
47 #define EGL_WIDTH 0x3057 | |
48 #define EGL_HEIGHT 0x3056 | |
49 | |
50 #else | |
51 | |
52 #include <EGL/egl.h> | |
53 | |
54 #endif | |
55 | |
56 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); | |
57 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); | |
58 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); | |
59 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); | |
60 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); | |
61 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); | |
62 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); | |
63 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); | |
64 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); | |
65 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); | |
66 typedef EGLBoolean (*MakeCurrentProc)(EGLDisplay dpy, EGLSurface draw, EGLSurfac
e read, EGLContext ctx); | |
67 typedef EGLBoolean (*SwapBuffersProc)(EGLDisplay dpy, EGLSurface surface); | |
68 typedef __eglMustCastToProperFunctionPointerType (*GetProcAddressProc)(const cha
r* procname); | |
69 | |
70 static GetDisplayProc gfGetDisplay = nullptr; | |
71 static InitializeProc gfInitialize = nullptr; | |
72 static TerminateProc gfTerminate = nullptr; | |
73 static ChooseConfigProc gfChooseConfig = nullptr; | |
74 static GetConfigAttrib gfGetConfigAttrib = nullptr; | |
75 static CreateWindowSurfaceProc gfCreateWindowSurface = nullptr; | |
76 static CreatePbufferSurfaceProc gfCreatePbufferSurface = nullptr; | |
77 static DestroySurfaceProc gfDestroySurface = nullptr; | |
78 static CreateContextProc gfCreateContext = nullptr; | |
79 static DestroyContextProc gfDestroyContext = nullptr; | |
80 static MakeCurrentProc gfMakeCurrent = nullptr; | |
81 static SwapBuffersProc gfSwapBuffers = nullptr; | |
82 static GetProcAddressProc gfGetProcAddress = nullptr; | |
83 | |
84 static void* gLibrary = nullptr; | |
85 static bool gfFunctionsLoadedSuccessfully = false; | |
86 | |
87 namespace { | |
88 static void load_command_buffer_functions() { | |
89 if (!gLibrary) { | |
90 #if defined _WIN32 | |
91 gLibrary = DynamicLoadLibrary("command_buffer_gles2.dll"); | |
92 #elif defined SK_BUILD_FOR_MAC | |
93 gLibrary = DynamicLoadLibrary("libcommand_buffer_gles2.dylib"); | |
94 #else | |
95 gLibrary = DynamicLoadLibrary("libcommand_buffer_gles2.so"); | |
96 #endif // defined _WIN32 | |
97 if (gLibrary) { | |
98 gfGetDisplay = (GetDisplayProc)GetProcedureAddress(gLibrary, "eglGet
Display"); | |
99 gfInitialize = (InitializeProc)GetProcedureAddress(gLibrary, "eglIni
tialize"); | |
100 gfTerminate = (TerminateProc)GetProcedureAddress(gLibrary, "eglTermi
nate"); | |
101 gfChooseConfig = (ChooseConfigProc)GetProcedureAddress(gLibrary, "eg
lChooseConfig"); | |
102 gfGetConfigAttrib = (GetConfigAttrib)GetProcedureAddress(gLibrary, "
eglGetConfigAttrib"); | |
103 gfCreateWindowSurface = (CreateWindowSurfaceProc)GetProcedureAddress
(gLibrary, "eglCreateWindowSurface"); | |
104 gfCreatePbufferSurface = (CreatePbufferSurfaceProc)GetProcedureAddre
ss(gLibrary, "eglCreatePbufferSurface"); | |
105 gfDestroySurface = (DestroySurfaceProc)GetProcedureAddress(gLibrary,
"eglDestroySurface"); | |
106 gfCreateContext = (CreateContextProc)GetProcedureAddress(gLibrary, "
eglCreateContext"); | |
107 gfDestroyContext = (DestroyContextProc)GetProcedureAddress(gLibrary,
"eglDestroyContext"); | |
108 gfMakeCurrent = (MakeCurrentProc)GetProcedureAddress(gLibrary, "eglM
akeCurrent"); | |
109 gfSwapBuffers = (SwapBuffersProc)GetProcedureAddress(gLibrary, "eglS
wapBuffers"); | |
110 gfGetProcAddress = (GetProcAddressProc)GetProcedureAddress(gLibrary,
"eglGetProcAddress"); | |
111 | |
112 gfFunctionsLoadedSuccessfully = gfGetDisplay && gfInitialize && gfTe
rminate && | |
113 gfChooseConfig && gfCreateWindowSurf
ace && | |
114 gfCreatePbufferSurface && gfDestroyS
urface && | |
115 gfCreateContext && gfDestroyContext
&& gfMakeCurrent && | |
116 gfSwapBuffers && gfGetProcAddress; | |
117 | |
118 } | |
119 } | |
120 } | |
121 | |
122 static GrGLFuncPtr command_buffer_get_gl_proc(void* ctx, const char name[]) { | |
123 if (!gfFunctionsLoadedSuccessfully) { | |
124 return nullptr; | |
125 } | |
126 return gfGetProcAddress(name); | |
127 } | |
128 | |
129 SK_DECLARE_STATIC_ONCE(loadCommandBufferOnce); | |
130 static void load_command_buffer_once() { | |
131 SkOnce(&loadCommandBufferOnce, load_command_buffer_functions); | |
132 } | |
133 | |
134 static const GrGLInterface* create_command_buffer_interface() { | |
135 load_command_buffer_once(); | |
136 if (!gfFunctionsLoadedSuccessfully) { | |
137 return nullptr; | |
138 } | |
139 return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); | |
140 } | |
141 | |
142 } // anonymous namespace | |
143 | |
144 namespace sk_gpu_test { | |
145 | |
146 CommandBufferGLTestContext::CommandBufferGLTestContext() | |
147 : fContext(EGL_NO_CONTEXT), fDisplay(EGL_NO_DISPLAY), fSurface(EGL_NO_SURFAC
E) { | |
148 | |
149 static const EGLint configAttribs[] = { | |
150 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | |
151 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
152 EGL_RED_SIZE, 8, | |
153 EGL_GREEN_SIZE, 8, | |
154 EGL_BLUE_SIZE, 8, | |
155 EGL_ALPHA_SIZE, 8, | |
156 EGL_NONE | |
157 }; | |
158 | |
159 static const EGLint surfaceAttribs[] = { | |
160 EGL_WIDTH, 1, | |
161 EGL_HEIGHT, 1, | |
162 EGL_NONE | |
163 }; | |
164 | |
165 initializeGLContext(nullptr, configAttribs, surfaceAttribs); | |
166 } | |
167 | |
168 CommandBufferGLTestContext::CommandBufferGLTestContext(void *nativeWindow, int m
saaSampleCount) { | |
169 static const EGLint surfaceAttribs[] = {EGL_NONE}; | |
170 | |
171 EGLint configAttribs[] = { | |
172 EGL_RED_SIZE, 8, | |
173 EGL_GREEN_SIZE, 8, | |
174 EGL_BLUE_SIZE, 8, | |
175 EGL_ALPHA_SIZE, 8, | |
176 EGL_DEPTH_SIZE, 8, | |
177 EGL_STENCIL_SIZE, 8, | |
178 EGL_SAMPLE_BUFFERS, 1, | |
179 EGL_SAMPLES, msaaSampleCount, | |
180 EGL_NONE | |
181 }; | |
182 if (msaaSampleCount == 0) { | |
183 configAttribs[12] = EGL_NONE; | |
184 } | |
185 | |
186 initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); | |
187 } | |
188 | |
189 void CommandBufferGLTestContext::initializeGLContext(void *nativeWindow, const i
nt *configAttribs, | |
190 const int *surfaceAttribs) { | |
191 load_command_buffer_once(); | |
192 if (!gfFunctionsLoadedSuccessfully) { | |
193 SkDebugf("Command Buffer: Could not load EGL functions.\n"); | |
194 return; | |
195 } | |
196 | |
197 // Make sure CHROMIUM_path_rendering is enabled for NVPR support. | |
198 sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering"); | |
199 fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); | |
200 if (EGL_NO_DISPLAY == fDisplay) { | |
201 SkDebugf("Command Buffer: Could not create EGL display.\n"); | |
202 return; | |
203 } | |
204 | |
205 EGLint majorVersion; | |
206 EGLint minorVersion; | |
207 if (!gfInitialize(fDisplay, &majorVersion, &minorVersion)) { | |
208 SkDebugf("Command Buffer: Could not initialize EGL display.\n"); | |
209 this->destroyGLContext(); | |
210 return; | |
211 } | |
212 | |
213 EGLint numConfigs; | |
214 if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig *>(&fConf
ig), 1, | |
215 &numConfigs) || numConfigs != 1) { | |
216 SkDebugf("Command Buffer: Could not choose EGL config.\n"); | |
217 this->destroyGLContext(); | |
218 return; | |
219 } | |
220 | |
221 if (nativeWindow) { | |
222 fSurface = gfCreateWindowSurface(fDisplay, | |
223 static_cast<EGLConfig>(fConfig), | |
224 (EGLNativeWindowType) nativeWindow, | |
225 surfaceAttribs); | |
226 } else { | |
227 fSurface = gfCreatePbufferSurface(fDisplay, | |
228 static_cast<EGLConfig>(fConfig), | |
229 surfaceAttribs); | |
230 } | |
231 if (EGL_NO_SURFACE == fSurface) { | |
232 SkDebugf("Command Buffer: Could not create EGL surface.\n"); | |
233 this->destroyGLContext(); | |
234 return; | |
235 } | |
236 | |
237 static const EGLint contextAttribs[] = { | |
238 EGL_CONTEXT_CLIENT_VERSION, 2, | |
239 EGL_NONE | |
240 }; | |
241 fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullpt
r, contextAttribs); | |
242 if (EGL_NO_CONTEXT == fContext) { | |
243 SkDebugf("Command Buffer: Could not create EGL context.\n"); | |
244 this->destroyGLContext(); | |
245 return; | |
246 } | |
247 | |
248 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | |
249 SkDebugf("Command Buffer: Could not make EGL context current.\n"); | |
250 this->destroyGLContext(); | |
251 return; | |
252 } | |
253 | |
254 SkAutoTUnref<const GrGLInterface> gl(create_command_buffer_interface()); | |
255 if (nullptr == gl.get()) { | |
256 SkDebugf("Command Buffer: Could not create CommandBuffer GL interface.\n
"); | |
257 this->destroyGLContext(); | |
258 return; | |
259 } | |
260 if (!gl->validate()) { | |
261 SkDebugf("Command Buffer: Could not validate CommandBuffer GL interface.
\n"); | |
262 this->destroyGLContext(); | |
263 return; | |
264 } | |
265 | |
266 this->init(gl.release()); | |
267 } | |
268 | |
269 CommandBufferGLTestContext::~CommandBufferGLTestContext() { | |
270 this->teardown(); | |
271 this->destroyGLContext(); | |
272 } | |
273 | |
274 void CommandBufferGLTestContext::destroyGLContext() { | |
275 if (!gfFunctionsLoadedSuccessfully) { | |
276 return; | |
277 } | |
278 if (fDisplay) { | |
279 gfMakeCurrent(fDisplay, 0, 0, 0); | |
280 | |
281 if (fContext) { | |
282 gfDestroyContext(fDisplay, fContext); | |
283 fContext = EGL_NO_CONTEXT; | |
284 } | |
285 | |
286 if (fSurface) { | |
287 gfDestroySurface(fDisplay, fSurface); | |
288 fSurface = EGL_NO_SURFACE; | |
289 } | |
290 | |
291 gfTerminate(fDisplay); | |
292 fDisplay = EGL_NO_DISPLAY; | |
293 } | |
294 } | |
295 | |
296 void CommandBufferGLTestContext::onPlatformMakeCurrent() const { | |
297 if (!gfFunctionsLoadedSuccessfully) { | |
298 return; | |
299 } | |
300 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | |
301 SkDebugf("Command Buffer: Could not make EGL context current.\n"); | |
302 } | |
303 } | |
304 | |
305 void CommandBufferGLTestContext::onPlatformSwapBuffers() const { | |
306 if (!gfFunctionsLoadedSuccessfully) { | |
307 return; | |
308 } | |
309 if (!gfSwapBuffers(fDisplay, fSurface)) { | |
310 SkDebugf("Command Buffer: Could not complete gfSwapBuffers.\n"); | |
311 } | |
312 } | |
313 | |
314 GrGLFuncPtr CommandBufferGLTestContext::onPlatformGetProcAddress(const char *nam
e) const { | |
315 if (!gfFunctionsLoadedSuccessfully) { | |
316 return nullptr; | |
317 } | |
318 return gfGetProcAddress(name); | |
319 } | |
320 | |
321 void CommandBufferGLTestContext::presentCommandBuffer() { | |
322 if (this->gl()) { | |
323 this->gl()->fFunctions.fFlush(); | |
324 } | |
325 | |
326 this->onPlatformSwapBuffers(); | |
327 } | |
328 | |
329 bool CommandBufferGLTestContext::makeCurrent() { | |
330 return gfMakeCurrent(fDisplay, fSurface, fSurface, fContext) != EGL_FALSE; | |
331 } | |
332 | |
333 int CommandBufferGLTestContext::getStencilBits() { | |
334 EGLint result = 0; | |
335 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZ
E, &result); | |
336 return result; | |
337 } | |
338 | |
339 int CommandBufferGLTestContext::getSampleCount() { | |
340 EGLint result = 0; | |
341 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &r
esult); | |
342 return result; | |
343 } | |
344 | |
345 } // namespace sk_gpu_test | |
OLD | NEW |