aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc9
-rw-r--r--src/library_egl.js76
-rw-r--r--tests/test_benchmark.py2
-rw-r--r--tests/test_browser.py6
-rw-r--r--tests/test_egl.c73
5 files changed, 141 insertions, 25 deletions
diff --git a/emcc b/emcc
index 8f8ad4aa..9afec57a 100755
--- a/emcc
+++ b/emcc
@@ -1133,10 +1133,11 @@ try:
heap = 4096
while heap < shared.Settings.TOTAL_MEMORY:
- if heap <= 16*1024*1024:
- heap *= 2
- else:
- heap += 16*1024*1024
+ heap *= 2
+ #if heap <= 16*1024*1024:
+ # heap *= 2
+ #else:
+ # heap += 16*1024*1024
if heap != shared.Settings.TOTAL_MEMORY:
logging.warning('increasing TOTAL_MEMORY to %d to be more reasonable for asm.js' % heap)
shared.Settings.TOTAL_MEMORY = heap
diff --git a/src/library_egl.js b/src/library_egl.js
index cc702fec..73d5e544 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -9,12 +9,16 @@
var LibraryEGL = {
$EGL: {
// This variable tracks the success status of the most recently invoked EGL function call.
- eglErrorCode: 0x3000 /* EGL_SUCCESS */,
+ 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.eglErrorCode = code;
+ EGL.errorCode = code;
},
chooseConfig: function(display, attribList, config, config_size, numConfigs) {
@@ -65,6 +69,7 @@ var LibraryEGL = {
if (minorVersion) {
{{{ makeSetValue('minorVersion', '0', '4', 'i32') }}}; // Advertise EGL Minor version: '4'
}
+ EGL.defaultDisplayInitialized = true;
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
return 1;
}
@@ -80,18 +85,10 @@ var LibraryEGL = {
EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
return 0;
}
- // TODO: Tear down EGL here. Currently a no-op since we don't need to actually do anything here for the browser.
- EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
- return 1;
- },
-
-// 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;
- }
- // TODO: Tear down EGL here. Currently a no-op since we don't need to actually do anything here for the browser.
+ EGL.currentContext = 0;
+ EGL.currentReadSurface = 0;
+ EGL.currentDrawSurface = 0;
+ EGL.defaultDisplayInitialized = false;
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
return 1;
},
@@ -248,6 +245,12 @@ var LibraryEGL = {
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' */
},
@@ -265,6 +268,7 @@ var LibraryEGL = {
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.
@@ -280,10 +284,17 @@ var LibraryEGL = {
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 */);
- return 62004; // Magic ID for Emscripten EGLContext
+ if (EGL.currentContext == context) {
+ EGL.currentContext = 0;
+ }
+ return 1 /* EGL_TRUE */;
},
// EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
@@ -407,7 +418,7 @@ var LibraryEGL = {
// EGLAPI EGLint EGLAPIENTRY eglGetError(void);
eglGetError: function() {
- return EGL.eglErrorCode;
+ return EGL.errorCode;
},
// EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
@@ -477,21 +488,46 @@ var LibraryEGL = {
eglMakeCurrent: function(display, draw, read, context) {
if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
- return 0;
+ return 0 /* EGL_FALSE */;
}
//\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
- if (context != 62004 /* Magic ID for Emscripten EGLContext */) {
+ if (context != 0 && context != 62004 /* Magic ID for Emscripten EGLContext */) {
EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
return 0;
}
- if (read != 62006 || draw != 62006 /* Magic ID for Emscripten 'default surface' */) {
+ 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;
+ 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() {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index 011ab256..63e0041f 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -420,7 +420,7 @@ process(sys.argv[1])
return 100.0/float(re.search('Unrolled Double Precision +([\d\.]+) Mflops', output).group(1))
self.do_benchmark('linpack_double', open(path_from_root('tests', 'linpack.c')).read(), '''Unrolled Double Precision''', force_c=True, output_parser=output_parser)
- def test_linpack_float(self):
+ def test_linpack_float(self): # TODO: investigate if this might benefit from -ffast-math in LLVM 3.3+ which has fast math stuff in LLVM IR
def output_parser(output):
return 100.0/float(re.search('Unrolled Single Precision +([\d\.]+) Mflops', output).group(1))
self.do_benchmark('linpack_float', open(path_from_root('tests', 'linpack.c')).read(), '''Unrolled Single Precision''', force_c=True, output_parser=output_parser, shared_args=['-DSP'])
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 1900e2cf..111702e6 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1147,6 +1147,12 @@ keydown(100);keyup(100); // trigger the end
Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
self.run_browser('page.html', '', '/report_result?1')
+ def test_egl(self):
+ open(os.path.join(self.get_dir(), 'test_egl.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'test_egl.c')).read()))
+
+ Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'test_egl.c'), '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?1')
+
def test_egl_width_height(self):
open(os.path.join(self.get_dir(), 'test_egl_width_height.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'test_egl_width_height.c')).read()))
diff --git a/tests/test_egl.c b/tests/test_egl.c
new file mode 100644
index 00000000..5864a797
--- /dev/null
+++ b/tests/test_egl.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <EGL/egl.h>
+
+int result = 1; // Success
+#define assert(x) do { if (!(x)) {result = 0; printf("Assertion failure: %s in %s:%d!\n", #x, __FILE__, __LINE__); } } while(0)
+
+int main(int argc, char *argv[])
+{
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ assert(display != EGL_NO_DISPLAY);
+ assert(eglGetError() == EGL_SUCCESS);
+
+ EGLint major = 0, minor = 0;
+ EGLBoolean ret = eglInitialize(display, &major, &minor);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+ assert(major * 10000 + minor >= 10004);
+
+ EGLint numConfigs;
+ ret = eglGetConfigs(display, NULL, 0, &numConfigs);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+
+ EGLint attribs[] = {
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_NONE
+ };
+ EGLConfig config;
+ ret = eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+
+ EGLNativeWindowType dummyWindow;
+ EGLSurface surface = eglCreateWindowSurface(display, config, dummyWindow, NULL);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(surface != 0);
+
+ EGLint contextAttribs[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ EGLContext context = eglCreateContext(display, config, NULL, contextAttribs);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(context != 0);
+
+ assert(eglGetCurrentContext() == 0); // Creating a context does not yet activate it.
+ assert(eglGetError() == EGL_SUCCESS);
+
+ ret = eglMakeCurrent(display, surface, surface, context);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+ assert(eglGetCurrentContext() == context);
+ assert(eglGetCurrentSurface(EGL_READ) == surface);
+ assert(eglGetCurrentSurface(EGL_DRAW) == surface);
+
+ ret = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+ assert(eglGetCurrentContext() == EGL_NO_CONTEXT);
+ assert(eglGetCurrentSurface(EGL_READ) == EGL_NO_SURFACE);
+ assert(eglGetCurrentSurface(EGL_DRAW) == EGL_NO_SURFACE);
+
+ ret = eglTerminate(display);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(ret == EGL_TRUE);
+
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+}