/* The EGL implementation supports only one EGLNativeDisplayType, the EGL_DEFAULT_DISPLAY. This native display type returns the only supported EGLDisplay handle with the magic value 62000. There is only a single EGLConfig configuration supported, that has the magic value 62002. The implementation only allows a single EGLContext to be created, that has the magic value of 62004. (multiple creations silently return this same context) The implementation only creates a single EGLSurface, a handle with the magic value of 62006. (multiple creations silently return the same surface) */ var LibraryEGL = { $EGL: { // This variable tracks the success status of the most recently invoked EGL function call. errorCode: 0x3000 /* EGL_SUCCESS */, defaultDisplayInitialized: false, currentContext: 0 /* EGL_NO_CONTEXT */, currentReadSurface: 0 /* EGL_NO_SURFACE */, currentDrawSurface: 0 /* EGL_NO_SURFACE */, stringCache: {}, setErrorCode: function(code) { EGL.errorCode = code; }, chooseConfig: function(display, attribList, config, config_size, numConfigs) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } // TODO: read attribList. if ((!config || !config_size) && !numConfigs) { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } if (numConfigs) { {{{ makeSetValue('numConfigs', '0', '1', 'i32') }}}; // Total number of supported configs: 1. } if (config && config_size > 0) { {{{ makeSetValue('config', '0', '62002' /* Magic ID for the only EGLConfig supported by Emscripten */, 'i32') }}}; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, }, // EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id); eglGetDisplay: function(nativeDisplayType) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); // Note: As a 'conformant' implementation of EGL, we would prefer to init here only if the user // calls this function with EGL_DEFAULT_DISPLAY. Other display IDs would be preferred to be unsupported // and EGL_NO_DISPLAY returned. Uncomment the following code lines to do this. // Instead, an alternative route has been preferred, namely that the Emscripten EGL implementation // "emulates" X11, and eglGetDisplay is expected to accept/receive a pointer to an X11 Display object. // Therefore, be lax and allow anything to be passed in, and return the magic handle to our default EGLDisplay object. // if (nativeDisplayType == 0 /* EGL_DEFAULT_DISPLAY */) { return 62000; // Magic ID for Emscripten 'default display' // } // else // return 0; // EGL_NO_DISPLAY }, // EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor); eglInitialize: function(display, majorVersion, minorVersion) { if (display == 62000 /* Magic ID for Emscripten 'default display' */) { if (majorVersion) { {{{ makeSetValue('majorVersion', '0', '1', 'i32') }}}; // Advertise EGL Major version: '1' } if (minorVersion) { {{{ makeSetValue('minorVersion', '0', '4', 'i32') }}}; // Advertise EGL Minor version: '4' } EGL.defaultDisplayInitialized = true; EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; } else { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } }, // EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy); eglTerminate: function(display) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } EGL.currentContext = 0; EGL.currentReadSurface = 0; EGL.currentDrawSurface = 0; EGL.defaultDisplayInitialized = false; EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, // EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); eglGetConfigs: function(display, configs, config_size, numConfigs) { return EGL.chooseConfig(display, 0, configs, config_size, numConfigs); }, // EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); eglChooseConfig: function(display, attrib_list, configs, config_size, numConfigs) { return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs); }, // EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); eglGetConfigAttrib: function(display, config, attribute, value) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) { EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */); return 0; } if (!value) { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); switch(attribute) { case 0x3020: // EGL_BUFFER_SIZE {{{ makeSetValue('value', '0', '32' /* 8 bits for each A,R,G,B. */, 'i32') }}}; return 1; case 0x3021: // EGL_ALPHA_SIZE {{{ makeSetValue('value', '0', '8' /* 8 bits for alpha channel. */, 'i32') }}}; return 1; case 0x3022: // EGL_BLUE_SIZE {{{ makeSetValue('value', '0', '8' /* 8 bits for blue channel. */, 'i32') }}}; return 1; case 0x3023: // EGL_GREEN_SIZE {{{ makeSetValue('value', '0', '8' /* 8 bits for green channel. */, 'i32') }}}; return 1; case 0x3024: // EGL_RED_SIZE {{{ makeSetValue('value', '0', '8' /* 8 bits for red channel. */, 'i32') }}}; return 1; case 0x3025: // EGL_DEPTH_SIZE {{{ makeSetValue('value', '0', '24' /* 24 bits for depth buffer. TODO: This is hardcoded, add support for this! */, 'i32') }}}; return 1; case 0x3026: // EGL_STENCIL_SIZE {{{ makeSetValue('value', '0', '8' /* 8 bits for stencil buffer. TODO: This is hardcoded, add support for this! */, 'i32') }}}; return 1; case 0x3027: // EGL_CONFIG_CAVEAT // We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051). {{{ makeSetValue('value', '0', '0x3038' /* EGL_NONE */, 'i32') }}}; return 1; case 0x3028: // EGL_CONFIG_ID {{{ makeSetValue('value', '0', '62002' /* Magic ID for the only EGLConfig supported by Emscripten */, 'i32') }}}; return 1; case 0x3029: // EGL_LEVEL {{{ makeSetValue('value', '0', '0' /* Z order/depth layer for this level. Not applicable for Emscripten. */, 'i32') }}}; return 1; case 0x302A: // EGL_MAX_PBUFFER_HEIGHT {{{ makeSetValue('value', '0', '4096', 'i32') }}}; return 1; case 0x302B: // EGL_MAX_PBUFFER_PIXELS {{{ makeSetValue('value', '0', '16777216' /* 4096 * 4096 */, 'i32') }}}; return 1; case 0x302C: // EGL_MAX_PBUFFER_WIDTH {{{ makeSetValue('value', '0', '4096', 'i32') }}}; return 1; case 0x302D: // EGL_NATIVE_RENDERABLE {{{ makeSetValue('value', '0', '0' /* This config does not allow co-rendering with other 'native' rendering APIs. */, 'i32') }}}; return 1; case 0x302E: // EGL_NATIVE_VISUAL_ID {{{ makeSetValue('value', '0', '0' /* N/A for Emscripten. */, 'i32') }}}; return 1; case 0x302F: // EGL_NATIVE_VISUAL_TYPE {{{ makeSetValue('value', '0', '0x3038' /* EGL_NONE */, 'i32') }}}; return 1; case 0x3031: // EGL_SAMPLES {{{ makeSetValue('value', '0', '4' /* 2x2 Multisampling */, 'i32') }}}; return 1; case 0x3032: // EGL_SAMPLE_BUFFERS {{{ makeSetValue('value', '0', '1' /* Multisampling enabled */, 'i32') }}}; return 1; case 0x3033: // EGL_SURFACE_TYPE {{{ makeSetValue('value', '0', '0x0004' /* EGL_WINDOW_BIT */, 'i32') }}}; return 1; case 0x3034: // EGL_TRANSPARENT_TYPE // If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas. {{{ makeSetValue('value', '0', '0x3038' /* EGL_NONE */, 'i32') }}}; return 1; case 0x3035: // EGL_TRANSPARENT_BLUE_VALUE case 0x3036: // EGL_TRANSPARENT_GREEN_VALUE case 0x3037: // EGL_TRANSPARENT_RED_VALUE // "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined." {{{ makeSetValue('value', '0', '-1' /* Report a "does not apply" value. */, 'i32') }}}; return 1; case 0x3039: // EGL_BIND_TO_TEXTURE_RGB case 0x303A: // EGL_BIND_TO_TEXTURE_RGBA {{{ makeSetValue('value', '0', '0' /* Only pbuffers would be bindable, but these are not supported. */, 'i32') }}}; return 1; case 0x303B: // EGL_MIN_SWAP_INTERVAL case 0x303C: // EGL_MAX_SWAP_INTERVAL {{{ makeSetValue('value', '0', '1' /* TODO: Currently this is not strictly true, since user can specify custom presentation interval in JS requestAnimationFrame/emscripten_set_main_loop. */, 'i32') }}}; return 1; case 0x303D: // EGL_LUMINANCE_SIZE case 0x303E: // EGL_ALPHA_MASK_SIZE {{{ makeSetValue('value', '0', '0' /* N/A in this config. */, 'i32') }}}; return 1; case 0x303F: // EGL_COLOR_BUFFER_TYPE // EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER. {{{ makeSetValue('value', '0', '0x308E' /* EGL_RGB_BUFFER */, 'i32') }}}; return 1; case 0x3040: // EGL_RENDERABLE_TYPE // A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT. {{{ makeSetValue('value', '0', '0x0004' /* EGL_OPENGL_ES2_BIT */, 'i32') }}}; return 1; case 0x3042: // EGL_CONFORMANT // "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API." {{{ makeSetValue('value', '0', '0' /* EGL_OPENGL_ES2_BIT */, 'i32') }}}; return 1; default: EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */); return 0; } }, // EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); eglCreateWindowSurface: function(display, config, win, attrib_list) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) { EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */); return 0; } // TODO: Examine attrib_list! Parameters that can be present there are: // - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER) // - EGL_VG_COLORSPACE (can't be set) // - EGL_VG_ALPHA_FORMAT (can't be set) EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 62006; /* Magic ID for Emscripten 'default surface' */ }, // EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface surface); eglDestroySurface: function(display, surface) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */) { EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */); return 1; } if (EGL.currentReadSurface == surface) { EGL.currentReadSurface = 0; } if (EGL.currentDrawSurface == surface) { EGL.currentDrawSurface = 0; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; /* Magic ID for Emscripten 'default surface' */ }, eglCreateContext__deps: ['glutInitDisplayMode', 'glutCreateWindow', '$GL'], // EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); eglCreateContext: function(display, config, hmm, contextAttribs) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } // EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten. // So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL. var glesContextVersion = 1; for(;;) { var param = {{{ makeGetValue('contextAttribs', '0', 'i32') }}}; if (!param) break; var value = {{{ makeGetValue('contextAttribs', '4', 'i32') }}}; if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) { glesContextVersion = value; } contextAttribs += 8; } if (glesContextVersion != 2) { #if GL_ASSERTIONS Module.printErr('When initializing GLES2/WebGL1 via EGL, one must pass EGL_CONTEXT_CLIENT_VERSION = 2 to GL context attributes! GLES version ' + glesContextVersion + ' is not supported!'); #endif EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */); return 0; /* EGL_NO_CONTEXT */ } _glutInitDisplayMode(0x92 /* GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE */); EGL.windowID = _glutCreateWindow(); if (EGL.windowID != 0) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); // Note: This function only creates a context, but it shall not make it active. return 62004; // Magic ID for Emscripten EGLContext } else { EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set. return 0; /* EGL_NO_CONTEXT */ } }, eglDestroyContext__deps: ['glutDestroyWindow', '$GL'], // EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext context); eglDestroyContext: function(display, context) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (context != 62004 /* Magic ID for Emscripten EGLContext */) { EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */); return 0; } _glutDestroyWindow(EGL.windowID); EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); if (EGL.currentContext == context) { EGL.currentContext = 0; } return 1 /* EGL_TRUE */; }, // EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx); eglDestroyContext: function(display, context) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (context != 62004 /* Magic ID for Emscripten EGLContext */) { EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */); return 0; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, // EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); eglQuerySurface: function(display, surface, attribute, value) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } if (surface != 62006 /* Magic ID for Emscripten 'default surface' */) { EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */); return 0; } if (!value) { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); switch(attribute) { case 0x3028: // EGL_CONFIG_ID {{{ makeSetValue('value', '0', '62002' /* A magic value for the only EGLConfig configuration ID supported by Emscripten. */, 'i32') }}}; return 1; case 0x3058: // EGL_LARGEST_PBUFFER // Odd EGL API: If surface is not a pbuffer surface, 'value' should not be written to. It's not specified as an error, so true should(?) be returned. // Existing Android implementation seems to do so at least. return 1; case 0x3057: // EGL_WIDTH {{{ makeSetValue('value', '0', 'Module.canvas.width', 'i32') }}}; return 1; case 0x3056: // EGL_HEIGHT {{{ makeSetValue('value', '0', 'Module.canvas.height', 'i32') }}}; return 1; case 0x3090: // EGL_HORIZONTAL_RESOLUTION {{{ makeSetValue('value', '0', '-1' /* EGL_UNKNOWN */, 'i32') }}}; return 1; case 0x3091: // EGL_VERTICAL_RESOLUTION {{{ makeSetValue('value', '0', '-1' /* EGL_UNKNOWN */, 'i32') }}}; return 1; case 0x3092: // EGL_PIXEL_ASPECT_RATIO {{{ makeSetValue('value', '0', '-1' /* EGL_UNKNOWN */, 'i32') }}}; return 1; case 0x3086: // EGL_RENDER_BUFFER // The main surface is bound to the visible canvas window - it's always backbuffered. // Alternative to EGL_BACK_BUFFER would be EGL_SINGLE_BUFFER. {{{ makeSetValue('value', '0', '0x3084' /* EGL_BACK_BUFFER */, 'i32') }}}; return 1; case 0x3099: // EGL_MULTISAMPLE_RESOLVE {{{ makeSetValue('value', '0', '0x309A' /* EGL_MULTISAMPLE_RESOLVE_DEFAULT */, 'i32') }}}; return 1; case 0x3093: // EGL_SWAP_BEHAVIOR // The two possibilities are EGL_BUFFER_PRESERVED and EGL_BUFFER_DESTROYED. Slightly unsure which is the // case for browser environment, but advertise the 'weaker' behavior to be sure. {{{ makeSetValue('value', '0', '0x3095' /* EGL_BUFFER_DESTROYED */, 'i32') }}}; return 1; case 0x3080: // EGL_TEXTURE_FORMAT case 0x3081: // EGL_TEXTURE_TARGET case 0x3082: // EGL_MIPMAP_TEXTURE case 0x3083: // EGL_MIPMAP_LEVEL // This is a window surface, not a pbuffer surface. Spec: // "Querying EGL_TEXTURE_FORMAT, EGL_TEXTURE_TARGET, EGL_MIPMAP_TEXTURE, or EGL_MIPMAP_LEVEL for a non-pbuffer surface is not an error, but value is not modified." // So pass-through. return 1; default: EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */); return 0; } }, // EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); eglQueryContext: function(display, context, attribute, value) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy. if (context != 62004 /* Magic ID for Emscripten EGLContext */) { EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */); return 0; } if (!value) { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); switch(attribute) { case 0x3028: // EGL_CONFIG_ID {{{ makeSetValue('value', '0', '62002' /* A magic value for the only EGLConfig configuration ID supported by Emscripten. */, 'i32') }}}; return 1; case 0x3097: // EGL_CONTEXT_CLIENT_TYPE {{{ makeSetValue('value', '0', '0x30A0' /* EGL_OPENGL_ES_API */, 'i32') }}}; return 1; case 0x3098: // EGL_CONTEXT_CLIENT_VERSION {{{ makeSetValue('value', '0', '2' /* GLES2 context */, 'i32') }}}; // We always report the context to be a GLES2 context (and not a GLES1 context) return 1; case 0x3086: // EGL_RENDER_BUFFER // The context is bound to the visible canvas window - it's always backbuffered. // Alternative to EGL_BACK_BUFFER would be EGL_SINGLE_BUFFER. {{{ makeSetValue('value', '0', '0x3084' /* EGL_BACK_BUFFER */, 'i32') }}}; return 1; default: EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */); return 0; } }, // EGLAPI EGLint EGLAPIENTRY eglGetError(void); eglGetError: function() { return EGL.errorCode; }, // EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name); eglQueryString: function(display, name) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); if (EGL.stringCache[name]) return EGL.stringCache[name]; var ret; switch(name) { case 0x3053 /* EGL_VENDOR */: ret = allocate(intArrayFromString("Emscripten"), 'i8', ALLOC_NORMAL); break; case 0x3054 /* EGL_VERSION */: ret = allocate(intArrayFromString("1.4 Emscripten EGL"), 'i8', ALLOC_NORMAL); break; case 0x3055 /* EGL_EXTENSIONS */: ret = allocate(intArrayFromString(""), 'i8', ALLOC_NORMAL); break; // Currently not supporting any EGL extensions. case 0x308D /* EGL_CLIENT_APIS */: ret = allocate(intArrayFromString("OpenGL_ES"), 'i8', ALLOC_NORMAL); break; default: EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } EGL.stringCache[name] = ret; return ret; }, // EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api); eglBindAPI: function(api) { if (api == 0x30A0 /* EGL_OPENGL_ES_API */) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; } else { // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; } }, // EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void); eglQueryAPI: function() { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 0x30A0; // EGL_OPENGL_ES_API }, // EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void); eglWaitClient: function() { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, // EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine); eglWaitNative: function(nativeEngineId) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, // EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void); eglWaitGL: 'eglWaitClient', // EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval); eglSwapInterval: function(display, interval) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } // \todo Could we use this function to specify the rate for requestAnimationFrame+main loop? EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; }, // EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); eglMakeCurrent: function(display, draw, read, context) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0 /* EGL_FALSE */; } //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy. if (context != 0 && context != 62004 /* Magic ID for Emscripten EGLContext */) { EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */); return 0; } if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */)) { EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */); return 0; } EGL.currentContext = context; EGL.currentDrawSurface = draw; EGL.currentReadSurface = read; EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1 /* EGL_TRUE */; }, // EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void); eglGetCurrentContext: function() { return EGL.currentContext; }, // EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw); eglGetCurrentSurface: function(readdraw) { if (readdraw == 0x305A /* EGL_READ */) { return EGL.currentReadSurface; } else if (readdraw == 0x3059 /* EGL_DRAW */) { return EGL.currentDrawSurface; } else { EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0 /* EGL_NO_SURFACE */; } }, // EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void); eglGetCurrentDisplay: function() { return EGL.currentContext ? 62000 /* Magic ID for Emscripten 'default display' */ : 0; }, // EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface); eglSwapBuffers: function() { if (!EGL.defaultDisplayInitialized) { EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */); } else if (!Module.ctx) { EGL.setErrorCode(0x3002 /* EGL_BAD_ACCESS */); } else if (Module.ctx.isContextLost()) { EGL.setErrorCode(0x300E /* EGL_CONTEXT_LOST */); } else { // According to documentation this does an implicit flush. // Due to discussion at https://github.com/kripken/emscripten/pull/1871 // the flush was removed since this _may_ result in slowing code down. //_glFlush(); EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; // EGL_TRUE } return 0; // EGL_FALSE }, eglGetProcAddress__deps: ['emscripten_GetProcAddress'], eglGetProcAddress: function(name_) { return _emscripten_GetProcAddress(name_); }, }; autoAddDeps(LibraryEGL, '$EGL'); mergeInto(LibraryManager.library, LibraryEGL);