OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkOnce.h" | 8 #include "SkOnce.h" |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "gl/GrGLAssembleInterface.h" | 10 #include "gl/GrGLAssembleInterface.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 typedef void (*__eglMustCastToProperFunctionPointerType)(void); | 26 typedef void (*__eglMustCastToProperFunctionPointerType)(void); |
27 #define EGL_FALSE 0 | 27 #define EGL_FALSE 0 |
28 #define EGL_OPENGL_ES2_BIT 0x0004 | 28 #define EGL_OPENGL_ES2_BIT 0x0004 |
29 #define EGL_CONTEXT_CLIENT_VERSION 0x3098 | 29 #define EGL_CONTEXT_CLIENT_VERSION 0x3098 |
30 #define EGL_NO_SURFACE ((EGLSurface)0) | 30 #define EGL_NO_SURFACE ((EGLSurface)0) |
31 #define EGL_NO_DISPLAY ((EGLDisplay)0) | 31 #define EGL_NO_DISPLAY ((EGLDisplay)0) |
32 #define EGL_NO_CONTEXT ((EGLContext)0) | 32 #define EGL_NO_CONTEXT ((EGLContext)0) |
33 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) | 33 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) |
34 #define EGL_SURFACE_TYPE 0x3033 | 34 #define EGL_SURFACE_TYPE 0x3033 |
35 #define EGL_PBUFFER_BIT 0x0001 | 35 #define EGL_PBUFFER_BIT 0x0001 |
36 #define EGL_WINDOW_BIT 0x0004 | |
37 #define EGL_RENDERABLE_TYPE 0x3040 | 36 #define EGL_RENDERABLE_TYPE 0x3040 |
38 #define EGL_RED_SIZE 0x3024 | 37 #define EGL_RED_SIZE 0x3024 |
39 #define EGL_GREEN_SIZE 0x3023 | 38 #define EGL_GREEN_SIZE 0x3023 |
40 #define EGL_BLUE_SIZE 0x3022 | 39 #define EGL_BLUE_SIZE 0x3022 |
41 #define EGL_ALPHA_SIZE 0x3021 | 40 #define EGL_ALPHA_SIZE 0x3021 |
42 #define EGL_DEPTH_SIZE 0x3025 | 41 #define EGL_DEPTH_SIZE 0x3025 |
43 #define EGL_STENCIL_SIZE 0x3025 | 42 #define EGL_STENCIL_SIZE 0x3025 |
44 #define EGL_SAMPLES 0x3031 | 43 #define EGL_SAMPLES 0x3031 |
45 #define EGL_SAMPLE_BUFFERS 0x3032 | 44 #define EGL_SAMPLE_BUFFERS 0x3032 |
46 #define EGL_NONE 0x3038 | 45 #define EGL_NONE 0x3038 |
47 #define EGL_WIDTH 0x3057 | 46 #define EGL_WIDTH 0x3057 |
48 #define EGL_HEIGHT 0x3056 | 47 #define EGL_HEIGHT 0x3056 |
49 | 48 |
50 #else | 49 #else |
51 | 50 |
52 #include <EGL/egl.h> | 51 #include <EGL/egl.h> |
53 | 52 |
54 #endif | 53 #endif |
55 | 54 |
56 #ifndef EGL_OPENGL_ES3_BIT | |
57 // Part of EGL 1.5, typical headers are 1.4. | |
58 #define EGL_OPENGL_ES3_BIT 0x0040 | |
59 #endif | |
60 | |
61 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); | 55 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); |
62 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); | 56 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); |
63 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); | 57 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); |
64 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); | 58 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); |
65 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); | 59 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); |
66 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); | 60 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); |
67 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); | 61 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); |
68 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); | 62 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); |
69 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); | 63 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); |
70 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); | 64 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 } | 130 } |
137 | 131 |
138 const GrGLInterface* GrGLCreateCommandBufferInterface() { | 132 const GrGLInterface* GrGLCreateCommandBufferInterface() { |
139 LoadCommandBufferOnce(); | 133 LoadCommandBufferOnce(); |
140 if (!gfFunctionsLoadedSuccessfully) { | 134 if (!gfFunctionsLoadedSuccessfully) { |
141 return nullptr; | 135 return nullptr; |
142 } | 136 } |
143 return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); | 137 return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); |
144 } | 138 } |
145 | 139 |
146 SkCommandBufferGLContext::SkCommandBufferGLContext(ContextVersion minContextVers
ion) | 140 SkCommandBufferGLContext::SkCommandBufferGLContext() |
147 : fContext(EGL_NO_CONTEXT) | 141 : fContext(EGL_NO_CONTEXT) |
148 , fDisplay(EGL_NO_DISPLAY) | 142 , fDisplay(EGL_NO_DISPLAY) |
149 , fSurface(EGL_NO_SURFACE) { | 143 , fSurface(EGL_NO_SURFACE) { |
150 | 144 |
151 static const EGLint configAttribs[] = { | 145 static const EGLint configAttribs[] = { |
152 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | 146 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
153 EGL_RENDERABLE_TYPE, minContextVersion == kGLES3_ContextVersion ? EGL_O
PENGL_ES3_BIT | 147 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
154 : EGL_O
PENGL_ES2_BIT, | |
155 EGL_RED_SIZE, 8, | 148 EGL_RED_SIZE, 8, |
156 EGL_GREEN_SIZE, 8, | 149 EGL_GREEN_SIZE, 8, |
157 EGL_BLUE_SIZE, 8, | 150 EGL_BLUE_SIZE, 8, |
158 EGL_ALPHA_SIZE, 8, | 151 EGL_ALPHA_SIZE, 8, |
159 EGL_NONE | 152 EGL_NONE |
160 }; | 153 }; |
161 | 154 |
162 static const EGLint surfaceAttribs[] = { | 155 static const EGLint surfaceAttribs[] = { |
163 EGL_WIDTH, 1, | 156 EGL_WIDTH, 1, |
164 EGL_HEIGHT, 1, | 157 EGL_HEIGHT, 1, |
165 EGL_NONE | 158 EGL_NONE |
166 }; | 159 }; |
167 | 160 |
168 initializeGLContext(minContextVersion, nullptr, configAttribs, surfaceAttrib
s); | 161 initializeGLContext(nullptr, configAttribs, surfaceAttribs); |
169 } | 162 } |
170 | 163 |
171 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS
ampleCount) { | 164 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS
ampleCount) { |
172 static const EGLint surfaceAttribs[] = { EGL_NONE }; | 165 static const EGLint surfaceAttribs[] = { EGL_NONE }; |
173 | 166 |
174 EGLint configAttribs[] = { | 167 EGLint configAttribs[] = { |
175 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | |
176 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
177 EGL_RED_SIZE, 8, | 168 EGL_RED_SIZE, 8, |
178 EGL_GREEN_SIZE, 8, | 169 EGL_GREEN_SIZE, 8, |
179 EGL_BLUE_SIZE, 8, | 170 EGL_BLUE_SIZE, 8, |
180 EGL_ALPHA_SIZE, 8, | 171 EGL_ALPHA_SIZE, 8, |
181 EGL_DEPTH_SIZE, 8, | 172 EGL_DEPTH_SIZE, 8, |
182 EGL_STENCIL_SIZE, 8, | 173 EGL_STENCIL_SIZE, 8, |
183 EGL_SAMPLE_BUFFERS, 1, | 174 EGL_SAMPLE_BUFFERS, 1, |
184 EGL_SAMPLES, msaaSampleCount, | 175 EGL_SAMPLES, msaaSampleCount, |
185 EGL_NONE | 176 EGL_NONE |
186 }; | 177 }; |
187 if (msaaSampleCount == 0) { | 178 if (msaaSampleCount == 0) { |
188 configAttribs[12] = EGL_NONE; | 179 configAttribs[12] = EGL_NONE; |
189 } | 180 } |
190 | 181 |
191 initializeGLContext(kGLES2_ContextVersion, nativeWindow, configAttribs, surf
aceAttribs); | 182 initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); |
192 } | 183 } |
193 | 184 |
194 void SkCommandBufferGLContext::initializeGLContext(ContextVersion minContextVers
ion, | 185 void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int
* configAttribs, |
195 void* nativeWindow, const int
* configAttribs, | |
196 const int* surfaceAttribs) { | 186 const int* surfaceAttribs) { |
197 LoadCommandBufferOnce(); | 187 LoadCommandBufferOnce(); |
198 if (!gfFunctionsLoadedSuccessfully) { | 188 if (!gfFunctionsLoadedSuccessfully) { |
199 SkDebugf("Command Buffer: Could not load EGL functions.\n"); | 189 SkDebugf("Command Buffer: Could not load EGL functions.\n"); |
200 return; | 190 return; |
201 } | 191 } |
202 | 192 |
203 // Make sure CHROMIUM_path_rendering is enabled for NVPR support. | 193 // Make sure CHROMIUM_path_rendering is enabled for NVPR support. |
204 sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering --
enable-unsafe-es3-apis"); | 194 sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering"); |
205 fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); | 195 fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); |
206 if (EGL_NO_DISPLAY == fDisplay) { | 196 if (EGL_NO_DISPLAY == fDisplay) { |
207 SkDebugf("Command Buffer: Could not create EGL display.\n"); | 197 SkDebugf("Command Buffer: Could not create EGL display.\n"); |
208 return; | 198 return; |
209 } | 199 } |
210 | 200 |
211 if (!gfInitialize(fDisplay, nullptr, nullptr)) { | 201 EGLint majorVersion; |
| 202 EGLint minorVersion; |
| 203 if (!gfInitialize(fDisplay, &majorVersion, &minorVersion)) { |
212 SkDebugf("Command Buffer: Could not initialize EGL display.\n"); | 204 SkDebugf("Command Buffer: Could not initialize EGL display.\n"); |
213 this->destroyGLContext(); | 205 this->destroyGLContext(); |
214 return; | 206 return; |
215 } | 207 } |
216 | 208 |
217 EGLint numConfigs; | 209 EGLint numConfigs; |
218 if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig*>(&fConfi
g), 1, | 210 if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig*>(&fConfi
g), 1, |
219 &numConfigs) || numConfigs < 1) { | 211 &numConfigs) || numConfigs != 1) { |
220 SkDebugf("Command Buffer: Could not choose EGL config.\n"); | 212 SkDebugf("Command Buffer: Could not choose EGL config.\n"); |
221 this->destroyGLContext(); | 213 this->destroyGLContext(); |
222 return; | 214 return; |
223 } | 215 } |
224 | 216 |
225 if (nativeWindow) { | 217 if (nativeWindow) { |
226 fSurface = gfCreateWindowSurface(fDisplay, | 218 fSurface = gfCreateWindowSurface(fDisplay, |
227 static_cast<EGLConfig>(fConfig), | 219 static_cast<EGLConfig>(fConfig), |
228 (EGLNativeWindowType)nativeWindow, | 220 (EGLNativeWindowType)nativeWindow, |
229 surfaceAttribs); | 221 surfaceAttribs); |
230 } else { | 222 } else { |
231 fSurface = gfCreatePbufferSurface(fDisplay, | 223 fSurface = gfCreatePbufferSurface(fDisplay, |
232 static_cast<EGLConfig>(fConfig), | 224 static_cast<EGLConfig>(fConfig), |
233 surfaceAttribs); | 225 surfaceAttribs); |
234 } | 226 } |
235 if (EGL_NO_SURFACE == fSurface) { | 227 if (EGL_NO_SURFACE == fSurface) { |
236 SkDebugf("Command Buffer: Could not create EGL surface.\n"); | 228 SkDebugf("Command Buffer: Could not create EGL surface.\n"); |
237 this->destroyGLContext(); | 229 this->destroyGLContext(); |
238 return; | 230 return; |
239 } | 231 } |
240 | 232 |
241 static const EGLint contextAttribs[] = { | 233 static const EGLint contextAttribs[] = { |
242 EGL_CONTEXT_CLIENT_VERSION, minContextVersion == kGLES3_ContextVersion ?
3 : 2, | 234 EGL_CONTEXT_CLIENT_VERSION, 2, |
243 EGL_NONE | 235 EGL_NONE |
244 }; | 236 }; |
245 fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullpt
r, contextAttribs); | 237 fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullpt
r, contextAttribs); |
246 if (EGL_NO_CONTEXT == fContext) { | 238 if (EGL_NO_CONTEXT == fContext) { |
247 SkDebugf("Command Buffer: Could not create EGL context.\n"); | 239 SkDebugf("Command Buffer: Could not create EGL context.\n"); |
248 this->destroyGLContext(); | 240 this->destroyGLContext(); |
249 return; | 241 return; |
250 } | 242 } |
251 | 243 |
252 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 244 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
(...skipping 19 matching lines...) Expand all Loading... |
272 | 264 |
273 SkCommandBufferGLContext::~SkCommandBufferGLContext() { | 265 SkCommandBufferGLContext::~SkCommandBufferGLContext() { |
274 this->teardown(); | 266 this->teardown(); |
275 this->destroyGLContext(); | 267 this->destroyGLContext(); |
276 } | 268 } |
277 | 269 |
278 void SkCommandBufferGLContext::destroyGLContext() { | 270 void SkCommandBufferGLContext::destroyGLContext() { |
279 if (!gfFunctionsLoadedSuccessfully) { | 271 if (!gfFunctionsLoadedSuccessfully) { |
280 return; | 272 return; |
281 } | 273 } |
282 if (EGL_NO_DISPLAY == fDisplay) { | 274 if (fDisplay) { |
283 return; | 275 gfMakeCurrent(fDisplay, 0, 0, 0); |
| 276 |
| 277 if (fContext) { |
| 278 gfDestroyContext(fDisplay, fContext); |
| 279 fContext = EGL_NO_CONTEXT; |
| 280 } |
| 281 |
| 282 if (fSurface) { |
| 283 gfDestroySurface(fDisplay, fSurface); |
| 284 fSurface = EGL_NO_SURFACE; |
| 285 } |
| 286 |
| 287 gfTerminate(fDisplay); |
| 288 fDisplay = EGL_NO_DISPLAY; |
284 } | 289 } |
285 | |
286 if (EGL_NO_CONTEXT != fContext) { | |
287 gfDestroyContext(fDisplay, fContext); | |
288 fContext = EGL_NO_CONTEXT; | |
289 } | |
290 // Call MakeCurrent after destroying the context, so that the EGL implementa
tion knows | |
291 // that the context is not used anymore after it is released from being curr
ent. | |
292 // This way command buffer does not need to abandon the context before destr
uction, and no | |
293 // client-side errors are printed. | |
294 gfMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
295 | |
296 if (EGL_NO_SURFACE != fSurface) { | |
297 gfDestroySurface(fDisplay, fSurface); | |
298 fSurface = EGL_NO_SURFACE; | |
299 } | |
300 // The display is likely to be used again for another test, do not call gfTe
rminate. Also, | |
301 // terminating could imply terminating the "host" EGL inside command buffer.
This would | |
302 // terminate also EGL that this thread might use outside of command buffer. | |
303 fDisplay = EGL_NO_DISPLAY; | |
304 } | 290 } |
305 | 291 |
306 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { | 292 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { |
307 if (!gfFunctionsLoadedSuccessfully) { | 293 if (!gfFunctionsLoadedSuccessfully) { |
308 return; | 294 return; |
309 } | 295 } |
310 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 296 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
311 SkDebugf("Command Buffer: Could not make EGL context current.\n"); | 297 SkDebugf("Command Buffer: Could not make EGL context current.\n"); |
312 } | 298 } |
313 } | 299 } |
(...skipping 30 matching lines...) Expand all Loading... |
344 EGLint result = 0; | 330 EGLint result = 0; |
345 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZ
E, &result); | 331 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZ
E, &result); |
346 return result; | 332 return result; |
347 } | 333 } |
348 | 334 |
349 int SkCommandBufferGLContext::getSampleCount() { | 335 int SkCommandBufferGLContext::getSampleCount() { |
350 EGLint result = 0; | 336 EGLint result = 0; |
351 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &r
esult); | 337 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &r
esult); |
352 return result; | 338 return result; |
353 } | 339 } |
OLD | NEW |