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 |
36 #define EGL_RENDERABLE_TYPE 0x3040 | 37 #define EGL_RENDERABLE_TYPE 0x3040 |
37 #define EGL_RED_SIZE 0x3024 | 38 #define EGL_RED_SIZE 0x3024 |
38 #define EGL_GREEN_SIZE 0x3023 | 39 #define EGL_GREEN_SIZE 0x3023 |
39 #define EGL_BLUE_SIZE 0x3022 | 40 #define EGL_BLUE_SIZE 0x3022 |
40 #define EGL_ALPHA_SIZE 0x3021 | 41 #define EGL_ALPHA_SIZE 0x3021 |
41 #define EGL_DEPTH_SIZE 0x3025 | 42 #define EGL_DEPTH_SIZE 0x3025 |
42 #define EGL_STENCIL_SIZE 0x3025 | 43 #define EGL_STENCIL_SIZE 0x3025 |
43 #define EGL_SAMPLES 0x3031 | 44 #define EGL_SAMPLES 0x3031 |
44 #define EGL_SAMPLE_BUFFERS 0x3032 | 45 #define EGL_SAMPLE_BUFFERS 0x3032 |
45 #define EGL_NONE 0x3038 | 46 #define EGL_NONE 0x3038 |
46 #define EGL_WIDTH 0x3057 | 47 #define EGL_WIDTH 0x3057 |
47 #define EGL_HEIGHT 0x3056 | 48 #define EGL_HEIGHT 0x3056 |
48 | 49 |
49 #else | 50 #else |
50 | 51 |
51 #include <EGL/egl.h> | 52 #include <EGL/egl.h> |
52 | 53 |
53 #endif | 54 #endif |
54 | 55 |
| 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 |
55 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); | 61 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); |
56 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); | 62 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); |
57 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); | 63 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); |
58 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); | 64 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); |
59 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); | 65 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); |
60 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); | 66 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); |
61 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); | 67 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); |
62 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); | 68 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); |
63 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); | 69 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); |
64 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); | 70 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 136 } |
131 | 137 |
132 const GrGLInterface* GrGLCreateCommandBufferInterface() { | 138 const GrGLInterface* GrGLCreateCommandBufferInterface() { |
133 LoadCommandBufferOnce(); | 139 LoadCommandBufferOnce(); |
134 if (!gfFunctionsLoadedSuccessfully) { | 140 if (!gfFunctionsLoadedSuccessfully) { |
135 return nullptr; | 141 return nullptr; |
136 } | 142 } |
137 return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); | 143 return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); |
138 } | 144 } |
139 | 145 |
140 SkCommandBufferGLContext::SkCommandBufferGLContext() | 146 SkCommandBufferGLContext::SkCommandBufferGLContext(ContextVersion minContextVers
ion) |
141 : fContext(EGL_NO_CONTEXT) | 147 : fContext(EGL_NO_CONTEXT) |
142 , fDisplay(EGL_NO_DISPLAY) | 148 , fDisplay(EGL_NO_DISPLAY) |
143 , fSurface(EGL_NO_SURFACE) { | 149 , fSurface(EGL_NO_SURFACE) { |
144 | 150 |
145 static const EGLint configAttribs[] = { | 151 static const EGLint configAttribs[] = { |
146 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | 152 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
147 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | 153 EGL_RENDERABLE_TYPE, minContextVersion == kGLES3_ContextVersion ? EGL_O
PENGL_ES3_BIT |
| 154 : EGL_O
PENGL_ES2_BIT, |
148 EGL_RED_SIZE, 8, | 155 EGL_RED_SIZE, 8, |
149 EGL_GREEN_SIZE, 8, | 156 EGL_GREEN_SIZE, 8, |
150 EGL_BLUE_SIZE, 8, | 157 EGL_BLUE_SIZE, 8, |
151 EGL_ALPHA_SIZE, 8, | 158 EGL_ALPHA_SIZE, 8, |
152 EGL_NONE | 159 EGL_NONE |
153 }; | 160 }; |
154 | 161 |
155 static const EGLint surfaceAttribs[] = { | 162 static const EGLint surfaceAttribs[] = { |
156 EGL_WIDTH, 1, | 163 EGL_WIDTH, 1, |
157 EGL_HEIGHT, 1, | 164 EGL_HEIGHT, 1, |
158 EGL_NONE | 165 EGL_NONE |
159 }; | 166 }; |
160 | 167 |
161 initializeGLContext(nullptr, configAttribs, surfaceAttribs); | 168 initializeGLContext(minContextVersion, nullptr, configAttribs, surfaceAttrib
s); |
162 } | 169 } |
163 | 170 |
164 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS
ampleCount) { | 171 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS
ampleCount) { |
165 static const EGLint surfaceAttribs[] = { EGL_NONE }; | 172 static const EGLint surfaceAttribs[] = { EGL_NONE }; |
166 | 173 |
167 EGLint configAttribs[] = { | 174 EGLint configAttribs[] = { |
| 175 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
| 176 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
168 EGL_RED_SIZE, 8, | 177 EGL_RED_SIZE, 8, |
169 EGL_GREEN_SIZE, 8, | 178 EGL_GREEN_SIZE, 8, |
170 EGL_BLUE_SIZE, 8, | 179 EGL_BLUE_SIZE, 8, |
171 EGL_ALPHA_SIZE, 8, | 180 EGL_ALPHA_SIZE, 8, |
172 EGL_DEPTH_SIZE, 8, | 181 EGL_DEPTH_SIZE, 8, |
173 EGL_STENCIL_SIZE, 8, | 182 EGL_STENCIL_SIZE, 8, |
174 EGL_SAMPLE_BUFFERS, 1, | 183 EGL_SAMPLE_BUFFERS, 1, |
175 EGL_SAMPLES, msaaSampleCount, | 184 EGL_SAMPLES, msaaSampleCount, |
176 EGL_NONE | 185 EGL_NONE |
177 }; | 186 }; |
178 if (msaaSampleCount == 0) { | 187 if (msaaSampleCount == 0) { |
179 configAttribs[12] = EGL_NONE; | 188 configAttribs[12] = EGL_NONE; |
180 } | 189 } |
181 | 190 |
182 initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); | 191 initializeGLContext(kGLES2_ContextVersion, nativeWindow, configAttribs, surf
aceAttribs); |
183 } | 192 } |
184 | 193 |
185 void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int
* configAttribs, | 194 void SkCommandBufferGLContext::initializeGLContext(ContextVersion minContextVers
ion, |
| 195 void* nativeWindow, const int
* configAttribs, |
186 const int* surfaceAttribs) { | 196 const int* surfaceAttribs) { |
187 LoadCommandBufferOnce(); | 197 LoadCommandBufferOnce(); |
188 if (!gfFunctionsLoadedSuccessfully) { | 198 if (!gfFunctionsLoadedSuccessfully) { |
189 SkDebugf("Command Buffer: Could not load EGL functions.\n"); | 199 SkDebugf("Command Buffer: Could not load EGL functions.\n"); |
190 return; | 200 return; |
191 } | 201 } |
192 | 202 |
193 // Make sure CHROMIUM_path_rendering is enabled for NVPR support. | 203 // Make sure CHROMIUM_path_rendering is enabled for NVPR support. |
194 sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering"); | 204 sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering --
enable-unsafe-es3-apis"); |
195 fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); | 205 fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); |
196 if (EGL_NO_DISPLAY == fDisplay) { | 206 if (EGL_NO_DISPLAY == fDisplay) { |
197 SkDebugf("Command Buffer: Could not create EGL display.\n"); | 207 SkDebugf("Command Buffer: Could not create EGL display.\n"); |
198 return; | 208 return; |
199 } | 209 } |
200 | 210 |
201 EGLint majorVersion; | 211 if (!gfInitialize(fDisplay, nullptr, nullptr)) { |
202 EGLint minorVersion; | |
203 if (!gfInitialize(fDisplay, &majorVersion, &minorVersion)) { | |
204 SkDebugf("Command Buffer: Could not initialize EGL display.\n"); | 212 SkDebugf("Command Buffer: Could not initialize EGL display.\n"); |
205 this->destroyGLContext(); | 213 this->destroyGLContext(); |
206 return; | 214 return; |
207 } | 215 } |
208 | 216 |
209 EGLint numConfigs; | 217 EGLint numConfigs; |
210 if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig*>(&fConfi
g), 1, | 218 if (!gfChooseConfig(fDisplay, configAttribs, static_cast<EGLConfig*>(&fConfi
g), 1, |
211 &numConfigs) || numConfigs != 1) { | 219 &numConfigs) || numConfigs < 1) { |
212 SkDebugf("Command Buffer: Could not choose EGL config.\n"); | 220 SkDebugf("Command Buffer: Could not choose EGL config.\n"); |
213 this->destroyGLContext(); | 221 this->destroyGLContext(); |
214 return; | 222 return; |
215 } | 223 } |
216 | 224 |
217 if (nativeWindow) { | 225 if (nativeWindow) { |
218 fSurface = gfCreateWindowSurface(fDisplay, | 226 fSurface = gfCreateWindowSurface(fDisplay, |
219 static_cast<EGLConfig>(fConfig), | 227 static_cast<EGLConfig>(fConfig), |
220 (EGLNativeWindowType)nativeWindow, | 228 (EGLNativeWindowType)nativeWindow, |
221 surfaceAttribs); | 229 surfaceAttribs); |
222 } else { | 230 } else { |
223 fSurface = gfCreatePbufferSurface(fDisplay, | 231 fSurface = gfCreatePbufferSurface(fDisplay, |
224 static_cast<EGLConfig>(fConfig), | 232 static_cast<EGLConfig>(fConfig), |
225 surfaceAttribs); | 233 surfaceAttribs); |
226 } | 234 } |
227 if (EGL_NO_SURFACE == fSurface) { | 235 if (EGL_NO_SURFACE == fSurface) { |
228 SkDebugf("Command Buffer: Could not create EGL surface.\n"); | 236 SkDebugf("Command Buffer: Could not create EGL surface.\n"); |
229 this->destroyGLContext(); | 237 this->destroyGLContext(); |
230 return; | 238 return; |
231 } | 239 } |
232 | 240 |
233 static const EGLint contextAttribs[] = { | 241 static const EGLint contextAttribs[] = { |
234 EGL_CONTEXT_CLIENT_VERSION, 2, | 242 EGL_CONTEXT_CLIENT_VERSION, minContextVersion == kGLES3_ContextVersion ?
3 : 2, |
235 EGL_NONE | 243 EGL_NONE |
236 }; | 244 }; |
237 fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullpt
r, contextAttribs); | 245 fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullpt
r, contextAttribs); |
238 if (EGL_NO_CONTEXT == fContext) { | 246 if (EGL_NO_CONTEXT == fContext) { |
239 SkDebugf("Command Buffer: Could not create EGL context.\n"); | 247 SkDebugf("Command Buffer: Could not create EGL context.\n"); |
240 this->destroyGLContext(); | 248 this->destroyGLContext(); |
241 return; | 249 return; |
242 } | 250 } |
243 | 251 |
244 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 252 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
(...skipping 19 matching lines...) Expand all Loading... |
264 | 272 |
265 SkCommandBufferGLContext::~SkCommandBufferGLContext() { | 273 SkCommandBufferGLContext::~SkCommandBufferGLContext() { |
266 this->teardown(); | 274 this->teardown(); |
267 this->destroyGLContext(); | 275 this->destroyGLContext(); |
268 } | 276 } |
269 | 277 |
270 void SkCommandBufferGLContext::destroyGLContext() { | 278 void SkCommandBufferGLContext::destroyGLContext() { |
271 if (!gfFunctionsLoadedSuccessfully) { | 279 if (!gfFunctionsLoadedSuccessfully) { |
272 return; | 280 return; |
273 } | 281 } |
274 if (fDisplay) { | 282 if (EGL_NO_DISPLAY == fDisplay) { |
275 gfMakeCurrent(fDisplay, 0, 0, 0); | 283 return; |
| 284 } |
276 | 285 |
277 if (fContext) { | 286 if (EGL_NO_CONTEXT != fContext) { |
278 gfDestroyContext(fDisplay, fContext); | 287 gfDestroyContext(fDisplay, fContext); |
279 fContext = EGL_NO_CONTEXT; | 288 fContext = EGL_NO_CONTEXT; |
280 } | 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); |
281 | 295 |
282 if (fSurface) { | 296 if (EGL_NO_SURFACE != fSurface) { |
283 gfDestroySurface(fDisplay, fSurface); | 297 gfDestroySurface(fDisplay, fSurface); |
284 fSurface = EGL_NO_SURFACE; | 298 fSurface = EGL_NO_SURFACE; |
285 } | |
286 | |
287 gfTerminate(fDisplay); | |
288 fDisplay = EGL_NO_DISPLAY; | |
289 } | 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; |
290 } | 304 } |
291 | 305 |
292 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { | 306 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { |
293 if (!gfFunctionsLoadedSuccessfully) { | 307 if (!gfFunctionsLoadedSuccessfully) { |
294 return; | 308 return; |
295 } | 309 } |
296 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 310 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
297 SkDebugf("Command Buffer: Could not make EGL context current.\n"); | 311 SkDebugf("Command Buffer: Could not make EGL context current.\n"); |
298 } | 312 } |
299 } | 313 } |
(...skipping 30 matching lines...) Expand all Loading... |
330 EGLint result = 0; | 344 EGLint result = 0; |
331 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZ
E, &result); | 345 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_STENCIL_SIZ
E, &result); |
332 return result; | 346 return result; |
333 } | 347 } |
334 | 348 |
335 int SkCommandBufferGLContext::getSampleCount() { | 349 int SkCommandBufferGLContext::getSampleCount() { |
336 EGLint result = 0; | 350 EGLint result = 0; |
337 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &r
esult); | 351 gfGetConfigAttrib(fDisplay, static_cast<EGLConfig>(fConfig), EGL_SAMPLES, &r
esult); |
338 return result; | 352 return result; |
339 } | 353 } |
OLD | NEW |