Bumping manifests a=b2g-bump
[gecko.git] / gfx / gl / GLLibraryEGL.h
blob2c23158d05fa3cf13f64d178db78515bf3f84720
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef GLLIBRARYEGL_H_
6 #define GLLIBRARYEGL_H_
8 #if defined(MOZ_X11)
9 #include "mozilla/X11Util.h"
10 #endif
12 #include "GLLibraryLoader.h"
13 #include "mozilla/ThreadLocal.h"
14 #include "nsIFile.h"
16 #include <bitset>
18 #if defined(XP_WIN)
20 #ifndef WIN32_LEAN_AND_MEAN
21 #define WIN32_LEAN_AND_MEAN 1
22 #endif
24 #include <windows.h>
26 typedef HDC EGLNativeDisplayType;
27 typedef HBITMAP EGLNativePixmapType;
28 typedef HWND EGLNativeWindowType;
30 #define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
32 #else
33 typedef void *EGLNativeDisplayType;
34 typedef void *EGLNativePixmapType;
35 typedef void *EGLNativeWindowType;
37 #ifdef ANDROID
38 // We only need to explicitly dlopen egltrace
39 // on android as we can use LD_PRELOAD or other tricks
40 // on other platforms. We look for it in /data/local
41 // as that's writeable by all users
43 // This should really go in GLLibraryEGL.cpp but we currently reference
44 // APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring
45 // will come in subsequent patches on Bug 732865
46 #define APITRACE_LIB "/data/local/tmp/egltrace.so"
48 #ifdef MOZ_WIDGET_ANDROID
50 #endif // MOZ_WIDGET_ANDROID
51 #endif // ANDROID
52 #endif
54 #if defined(MOZ_X11)
55 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
56 #else
57 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
58 #endif
60 namespace mozilla {
61 namespace gl {
63 #undef BEFORE_GL_CALL
64 #undef AFTER_GL_CALL
66 #ifdef DEBUG
68 #ifndef MOZ_FUNCTION_NAME
69 # ifdef __GNUC__
70 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
71 # elif defined(_MSC_VER)
72 # define MOZ_FUNCTION_NAME __FUNCTION__
73 # else
74 # define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
75 # endif
76 #endif
78 #define BEFORE_GL_CALL do { \
79 BeforeGLCall(MOZ_FUNCTION_NAME); \
80 } while (0)
82 #define AFTER_GL_CALL do { \
83 AfterGLCall(MOZ_FUNCTION_NAME); \
84 } while (0)
85 // We rely on the fact that GLLibraryEGL.h #defines BEFORE_GL_CALL and
86 // AFTER_GL_CALL to nothing if !defined(DEBUG).
87 #else
88 #define BEFORE_GL_CALL
89 #define AFTER_GL_CALL
90 #endif
92 class GLLibraryEGL
94 public:
95 GLLibraryEGL()
96 : mInitialized(false),
97 mEGLLibrary(nullptr),
98 mIsANGLE(false)
102 void InitExtensions();
105 * Known GL extensions that can be queried by
106 * IsExtensionSupported. The results of this are cached, and as
107 * such it's safe to use this even in performance critical code.
108 * If you add to this array, remember to add to the string names
109 * in GLContext.cpp.
111 enum EGLExtensions {
112 KHR_image_base,
113 KHR_image_pixmap,
114 KHR_gl_texture_2D_image,
115 KHR_lock_surface,
116 ANGLE_surface_d3d_texture_2d_share_handle,
117 EXT_create_context_robustness,
118 KHR_image,
119 KHR_fence_sync,
120 ANDROID_native_fence_sync,
121 Extensions_Max
124 bool IsExtensionSupported(EGLExtensions aKnownExtension) const {
125 return mAvailableExtensions[aKnownExtension];
128 void MarkExtensionUnsupported(EGLExtensions aKnownExtension) {
129 mAvailableExtensions[aKnownExtension] = false;
132 protected:
133 std::bitset<Extensions_Max> mAvailableExtensions;
135 public:
137 EGLDisplay fGetDisplay(void* display_id)
139 BEFORE_GL_CALL;
140 EGLDisplay disp = mSymbols.fGetDisplay(display_id);
141 AFTER_GL_CALL;
142 return disp;
145 EGLSurface fGetCurrentSurface(EGLint id)
147 BEFORE_GL_CALL;
148 EGLSurface surf = mSymbols.fGetCurrentSurface(id);
149 AFTER_GL_CALL;
150 return surf;
153 EGLContext fGetCurrentContext()
155 BEFORE_GL_CALL;
156 EGLContext context = mSymbols.fGetCurrentContext();
157 AFTER_GL_CALL;
158 return context;
161 EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
163 BEFORE_GL_CALL;
164 EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
165 AFTER_GL_CALL;
166 return b;
169 EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
171 BEFORE_GL_CALL;
172 EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
173 AFTER_GL_CALL;
174 return b;
177 EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
179 BEFORE_GL_CALL;
180 EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
181 AFTER_GL_CALL;
182 return ctx;
185 EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
187 BEFORE_GL_CALL;
188 EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
189 AFTER_GL_CALL;
190 return b;
193 EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
195 BEFORE_GL_CALL;
196 EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
197 AFTER_GL_CALL;
198 return surf;
201 EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
203 BEFORE_GL_CALL;
204 EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
205 AFTER_GL_CALL;
206 return surf;
209 EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
211 BEFORE_GL_CALL;
212 EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
213 AFTER_GL_CALL;
214 return surf;
217 EGLBoolean fBindAPI(EGLenum api)
219 BEFORE_GL_CALL;
220 EGLBoolean b = mSymbols.fBindAPI(api);
221 AFTER_GL_CALL;
222 return b;
225 EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
227 BEFORE_GL_CALL;
228 EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
229 AFTER_GL_CALL;
230 return b;
233 EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
235 BEFORE_GL_CALL;
236 EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
237 AFTER_GL_CALL;
238 return b;
241 EGLint fGetError()
243 BEFORE_GL_CALL;
244 EGLint i = mSymbols.fGetError();
245 AFTER_GL_CALL;
246 return i;
249 EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
251 BEFORE_GL_CALL;
252 EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
253 AFTER_GL_CALL;
254 return b;
257 EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
259 BEFORE_GL_CALL;
260 EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
261 AFTER_GL_CALL;
262 return b;
265 EGLBoolean fWaitNative(EGLint engine)
267 BEFORE_GL_CALL;
268 EGLBoolean b = mSymbols.fWaitNative(engine);
269 AFTER_GL_CALL;
270 return b;
273 EGLCastToRelevantPtr fGetProcAddress(const char *procname)
275 BEFORE_GL_CALL;
276 EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
277 AFTER_GL_CALL;
278 return p;
281 EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
283 BEFORE_GL_CALL;
284 EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
285 AFTER_GL_CALL;
286 return b;
289 EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
291 BEFORE_GL_CALL;
292 EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
293 AFTER_GL_CALL;
294 return b;
297 const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
299 BEFORE_GL_CALL;
300 const GLubyte* b;
301 if (mSymbols.fQueryStringImplementationANDROID) {
302 b = mSymbols.fQueryStringImplementationANDROID(dpy, name);
303 } else {
304 b = mSymbols.fQueryString(dpy, name);
306 AFTER_GL_CALL;
307 return b;
310 EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
312 BEFORE_GL_CALL;
313 EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
314 AFTER_GL_CALL;
315 return b;
318 EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
320 BEFORE_GL_CALL;
321 EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
322 AFTER_GL_CALL;
323 return b;
326 EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
328 BEFORE_GL_CALL;
329 EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
330 AFTER_GL_CALL;
331 return b;
334 EGLImage fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
336 BEFORE_GL_CALL;
337 EGLImage i = mSymbols.fCreateImage(dpy, ctx, target, buffer, attrib_list);
338 AFTER_GL_CALL;
339 return i;
342 EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image)
344 BEFORE_GL_CALL;
345 EGLBoolean b = mSymbols.fDestroyImage(dpy, image);
346 AFTER_GL_CALL;
347 return b;
350 // New extension which allow us to lock texture and get raw image pointer
351 EGLBoolean fLockSurface(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
353 BEFORE_GL_CALL;
354 EGLBoolean b = mSymbols.fLockSurface(dpy, surface, attrib_list);
355 AFTER_GL_CALL;
356 return b;
359 EGLBoolean fUnlockSurface(EGLDisplay dpy, EGLSurface surface)
361 BEFORE_GL_CALL;
362 EGLBoolean b = mSymbols.fUnlockSurface(dpy, surface);
363 AFTER_GL_CALL;
364 return b;
367 EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
369 BEFORE_GL_CALL;
370 EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
371 AFTER_GL_CALL;
372 return b;
375 EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
377 BEFORE_GL_CALL;
378 EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
379 AFTER_GL_CALL;
380 return b;
383 EGLSync fCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
385 BEFORE_GL_CALL;
386 EGLSync ret = mSymbols.fCreateSync(dpy, type, attrib_list);
387 AFTER_GL_CALL;
388 return ret;
391 EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync)
393 BEFORE_GL_CALL;
394 EGLBoolean b = mSymbols.fDestroySync(dpy, sync);
395 AFTER_GL_CALL;
396 return b;
399 EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
401 BEFORE_GL_CALL;
402 EGLint ret = mSymbols.fClientWaitSync(dpy, sync, flags, timeout);
403 AFTER_GL_CALL;
404 return ret;
407 EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
409 BEFORE_GL_CALL;
410 EGLBoolean b = mSymbols.fGetSyncAttrib(dpy, sync, attribute, value);
411 AFTER_GL_CALL;
412 return b;
415 EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
417 MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID);
418 BEFORE_GL_CALL;
419 EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync);
420 AFTER_GL_CALL;
421 return ret;
424 EGLDisplay Display() {
425 return mEGLDisplay;
428 bool IsANGLE() const {
429 return mIsANGLE;
432 bool HasKHRImageBase() {
433 return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base);
436 bool HasKHRImagePixmap() {
437 return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_pixmap);
440 bool HasKHRImageTexture2D() {
441 return IsExtensionSupported(KHR_gl_texture_2D_image);
444 bool HasANGLESurfaceD3DTexture2DShareHandle() {
445 return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle);
448 bool HasRobustness() const {
449 return IsExtensionSupported(EXT_create_context_robustness);
452 bool EnsureInitialized();
454 void DumpEGLConfig(EGLConfig cfg);
455 void DumpEGLConfigs();
457 struct {
458 typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
459 pfnGetDisplay fGetDisplay;
460 typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
461 pfnGetCurrentSurface fGetCurrentSurface;
462 typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
463 pfnGetCurrentContext fGetCurrentContext;
464 typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
465 pfnMakeCurrent fMakeCurrent;
466 typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
467 pfnDestroyContext fDestroyContext;
468 typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
469 pfnCreateContext fCreateContext;
470 typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
471 pfnDestroySurface fDestroySurface;
472 typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
473 pfnCreateWindowSurface fCreateWindowSurface;
474 typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
475 pfnCreatePbufferSurface fCreatePbufferSurface;
476 typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
477 pfnCreatePixmapSurface fCreatePixmapSurface;
478 typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
479 pfnBindAPI fBindAPI;
480 typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
481 pfnInitialize fInitialize;
482 typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
483 pfnChooseConfig fChooseConfig;
484 typedef EGLint (GLAPIENTRY * pfnGetError)(void);
485 pfnGetError fGetError;
486 typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
487 pfnGetConfigAttrib fGetConfigAttrib;
488 typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
489 pfnGetConfigs fGetConfigs;
490 typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
491 pfnWaitNative fWaitNative;
492 typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
493 pfnGetProcAddress fGetProcAddress;
494 typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
495 pfnSwapBuffers fSwapBuffers;
496 typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
497 EGLNativePixmapType target);
498 pfnCopyBuffers fCopyBuffers;
499 typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
500 pfnQueryString fQueryString;
501 pfnQueryString fQueryStringImplementationANDROID;
502 typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
503 EGLint attribute, EGLint *value);
504 pfnQueryContext fQueryContext;
505 typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
506 pfnBindTexImage fBindTexImage;
507 typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
508 pfnReleaseTexImage fReleaseTexImage;
509 typedef EGLImage (GLAPIENTRY * pfnCreateImage)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
510 pfnCreateImage fCreateImage;
511 typedef EGLBoolean (GLAPIENTRY * pfnDestroyImage)(EGLDisplay dpy, EGLImage image);
512 pfnDestroyImage fDestroyImage;
514 // New extension which allow us to lock texture and get raw image pointer
515 typedef EGLBoolean (GLAPIENTRY * pfnLockSurface)(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
516 pfnLockSurface fLockSurface;
517 typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurface)(EGLDisplay dpy, EGLSurface surface);
518 pfnUnlockSurface fUnlockSurface;
519 typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
520 pfnQuerySurface fQuerySurface;
522 typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
523 pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
525 typedef EGLSync (GLAPIENTRY * pfnCreateSync)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
526 pfnCreateSync fCreateSync;
527 typedef EGLBoolean (GLAPIENTRY * pfnDestroySync)(EGLDisplay dpy, EGLSync sync);
528 pfnDestroySync fDestroySync;
529 typedef EGLint (GLAPIENTRY * pfnClientWaitSync)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
530 pfnClientWaitSync fClientWaitSync;
531 typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value);
532 pfnGetSyncAttrib fGetSyncAttrib;
533 typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
534 pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID;
535 } mSymbols;
537 #ifdef DEBUG
538 static void BeforeGLCall(const char* glFunction);
539 static void AfterGLCall(const char* glFunction);
540 #endif
542 #ifdef MOZ_B2G
543 EGLContext CachedCurrentContext() {
544 return sCurrentContext.get();
546 void UnsetCachedCurrentContext() {
547 sCurrentContext.set(nullptr);
549 void SetCachedCurrentContext(EGLContext aCtx) {
550 sCurrentContext.set(aCtx);
552 bool CachedCurrentContextMatches() {
553 return sCurrentContext.get() == fGetCurrentContext();
556 private:
557 static ThreadLocal<EGLContext> sCurrentContext;
558 public:
560 #else
561 EGLContext CachedCurrentContext() {
562 return nullptr;
564 void UnsetCachedCurrentContext() {}
565 void SetCachedCurrentContext(EGLContext aCtx) { }
566 bool CachedCurrentContextMatches() { return true; }
567 #endif
569 private:
570 bool mInitialized;
571 PRLibrary* mEGLLibrary;
572 EGLDisplay mEGLDisplay;
574 bool mIsANGLE;
577 extern GLLibraryEGL sEGLLibrary;
578 #define EGL_DISPLAY() sEGLLibrary.Display()
580 } /* namespace gl */
581 } /* namespace mozilla */
583 #endif /* GLLIBRARYEGL_H_ */