diff options
-rw-r--r-- | src/library_egl.js | 8 | ||||
-rw-r--r-- | src/library_fs.js | 172 | ||||
-rw-r--r-- | src/library_gl.js | 8 | ||||
-rw-r--r-- | src/library_glfw.js | 4 | ||||
-rw-r--r-- | src/library_glut.js | 4 | ||||
-rw-r--r-- | src/library_idbfs.js | 2 | ||||
-rw-r--r-- | src/library_memfs.js | 98 | ||||
-rw-r--r-- | src/library_nodefs.js | 12 | ||||
-rw-r--r-- | src/library_path.js | 22 | ||||
-rw-r--r-- | src/library_sdl.js | 6 | ||||
-rw-r--r-- | src/preamble.js | 10 | ||||
-rw-r--r-- | src/shell.html | 5 | ||||
-rw-r--r-- | tests/aniso.c | 3 | ||||
-rw-r--r-- | tests/test_browser.py | 42 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_common.c | 262 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_glfw.c | 47 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_glut.c | 42 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_sdl.c | 50 | ||||
-rw-r--r-- | tools/file_packager.py | 39 |
19 files changed, 673 insertions, 163 deletions
diff --git a/src/library_egl.js b/src/library_egl.js index 69902785..cc702fec 100644 --- a/src/library_egl.js +++ b/src/library_egl.js @@ -421,10 +421,10 @@ var LibraryEGL = { if (EGL.stringCache[name]) return EGL.stringCache[name]; var ret; switch(name) { - case 0x3053 /* EGL_VENDOR */: ret = allocate(intArrayFromString("Emscripten"), 'i8', ALLOC_NORMAL); - case 0x3054 /* EGL_VERSION */: ret = allocate(intArrayFromString("1.4 Emscripten EGL"), 'i8', ALLOC_NORMAL); - case 0x3055 /* EGL_EXTENSIONS */: ret = allocate(intArrayFromString(""), 'i8', ALLOC_NORMAL); // Currently not supporting any EGL extensions. - case 0x308D /* EGL_CLIENT_APIS */: ret = allocate(intArrayFromString("OpenGL_ES"), 'i8', ALLOC_NORMAL); + 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; diff --git a/src/library_fs.js b/src/library_fs.js index bd1522a8..aece2664 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -28,6 +28,7 @@ mergeInto(LibraryManager.library, { ignorePermissions: true, ErrnoError: null, // set during init + genericErrors: {}, handleFSError: function(e) { if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace(); @@ -62,7 +63,7 @@ mergeInto(LibraryManager.library, { } current = FS.lookupNode(current, parts[i]); - current_path = PATH.join(current_path, parts[i]); + current_path = PATH.join2(current_path, parts[i]); // jump to the mount's root node if this is a mountpoint if (FS.isMountpoint(current)) { @@ -94,9 +95,11 @@ mergeInto(LibraryManager.library, { var path; while (true) { if (FS.isRoot(node)) { - return path ? PATH.join(node.mount.mountpoint, path) : node.mount.mountpoint; + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path; } - path = path ? PATH.join(node.name, path) : node.name; + path = path ? node.name + '/' + path : node.name; node = node.parent; } }, @@ -158,44 +161,50 @@ mergeInto(LibraryManager.library, { return FS.lookup(parent, name); }, createNode: function(parent, name, mode, rdev) { - var node = { - id: FS.nextInode++, - name: name, - mode: mode, - node_ops: {}, - stream_ops: {}, - rdev: rdev, - parent: null, - mount: null - }; - if (!parent) { - parent = node; // root node sets parent to itself - } - node.parent = parent; - node.mount = parent.mount; - // compatibility - var readMode = {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}}; - var writeMode = {{{ cDefine('S_IWUGO') }}}; - // NOTE we must use Object.defineProperties instead of individual calls to - // Object.defineProperty in order to make closure compiler happy - Object.defineProperties(node, { - read: { - get: function() { return (node.mode & readMode) === readMode; }, - set: function(val) { val ? node.mode |= readMode : node.mode &= ~readMode; } - }, - write: { - get: function() { return (node.mode & writeMode) === writeMode; }, - set: function(val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; } - }, - isFolder: { - get: function() { return FS.isDir(node.mode); }, - }, - isDevice: { - get: function() { return FS.isChrdev(node.mode); }, - }, - }); - FS.hashAddNode(node); - return node; + if (!FS.FSNode) { + FS.FSNode = function(parent, name, mode, rdev) { + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.node_ops = {}; + this.stream_ops = {}; + this.rdev = rdev; + this.parent = null; + this.mount = null; + if (!parent) { + parent = this; // root node sets parent to itself + } + this.parent = parent; + this.mount = parent.mount; + FS.hashAddNode(this); + }; + + // compatibility + var readMode = {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}}; + var writeMode = {{{ cDefine('S_IWUGO') }}}; + + FS.FSNode.prototype = {}; + + // NOTE we must use Object.defineProperties instead of individual calls to + // Object.defineProperty in order to make closure compiler happy + Object.defineProperties(FS.FSNode.prototype, { + read: { + get: function() { return (this.mode & readMode) === readMode; }, + set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; } + }, + write: { + get: function() { return (this.mode & writeMode) === writeMode; }, + set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; } + }, + isFolder: { + get: function() { return FS.isDir(this.mode); }, + }, + isDevice: { + get: function() { return FS.isChrdev(this.mode); }, + }, + }); + } + return new FS.FSNode(parent, name, mode, rdev); }, destroyNode: function(node) { FS.hashRemoveNode(node); @@ -351,24 +360,28 @@ mergeInto(LibraryManager.library, { // object isn't directly passed in. not possible until // SOCKFS is completed. createStream: function(stream, fd_start, fd_end) { + if (!FS.FSStream) { + FS.FSStream = {}; + // compatibility + Object.defineProperties(FS.FSStream, { + object: { + get: function() { return this.node; }, + set: function(val) { this.node = val; } + }, + isRead: { + get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } + }, + isWrite: { + get: function() { return (this.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } + }, + isAppend: { + get: function() { return (this.flags & {{{ cDefine('O_APPEND') }}}); } + } + }); + } + stream.prototype = FS.FSStream; var fd = FS.nextfd(fd_start, fd_end); stream.fd = fd; - // compatibility - Object.defineProperties(stream, { - object: { - get: function() { return stream.node; }, - set: function(val) { stream.node = val; } - }, - isRead: { - get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } - }, - isWrite: { - get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } - }, - isAppend: { - get: function() { return (stream.flags & {{{ cDefine('O_APPEND') }}}); } - } - }); FS.streams[fd] = stream; return stream; }, @@ -771,7 +784,6 @@ mergeInto(LibraryManager.library, { }); }, open: function(path, flags, mode, fd_start, fd_end) { - path = PATH.normalize(path); flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags; mode = typeof mode === 'undefined' ? 0666 : mode; if ((flags & {{{ cDefine('O_CREAT') }}})) { @@ -780,13 +792,18 @@ mergeInto(LibraryManager.library, { mode = 0; } var node; - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & {{{ cDefine('O_NOFOLLOW') }}}) - }); - node = lookup.node; - } catch (e) { - // ignore + if (typeof path === 'object') { + node = path; + } else { + path = PATH.normalize(path); + try { + var lookup = FS.lookupPath(path, { + follow: !(flags & {{{ cDefine('O_NOFOLLOW') }}}) + }); + node = lookup.node; + } catch (e) { + // ignore + } } // perhaps we need to create the node if ((flags & {{{ cDefine('O_CREAT') }}})) { @@ -1079,6 +1096,11 @@ mergeInto(LibraryManager.library, { }; FS.ErrnoError.prototype = new Error(); FS.ErrnoError.prototype.constructor = FS.ErrnoError; + // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info) + [ERRNO_CODES.ENOENT].forEach(function(code) { + FS.genericErrors[code] = new FS.ErrnoError(code); + FS.genericErrors[code].stack = '<generic error, no stack>'; + }); }, staticInit: function() { FS.ensureErrnoError(); @@ -1173,7 +1195,7 @@ mergeInto(LibraryManager.library, { return ret; }, createFolder: function(parent, name, canRead, canWrite) { - var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); + var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(canRead, canWrite); return FS.mkdir(path, mode); }, @@ -1183,7 +1205,7 @@ mergeInto(LibraryManager.library, { while (parts.length) { var part = parts.pop(); if (!part) continue; - var current = PATH.join(parent, part); + var current = PATH.join2(parent, part); try { FS.mkdir(current); } catch (e) { @@ -1194,12 +1216,12 @@ mergeInto(LibraryManager.library, { return current; }, createFile: function(parent, name, properties, canRead, canWrite) { - var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); + var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(canRead, canWrite); return FS.create(path, mode); }, createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { - var path = name ? PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent; + var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent; var mode = FS.getMode(canRead, canWrite); var node = FS.create(path, mode); if (data) { @@ -1209,16 +1231,16 @@ mergeInto(LibraryManager.library, { data = arr; } // make sure we can write to the file - FS.chmod(path, mode | {{{ cDefine('S_IWUGO') }}}); - var stream = FS.open(path, 'w'); + FS.chmod(node, mode | {{{ cDefine('S_IWUGO') }}}); + var stream = FS.open(node, 'w'); FS.write(stream, data, 0, data.length, 0, canOwn); FS.close(stream); - FS.chmod(path, mode); + FS.chmod(node, mode); } return node; }, createDevice: function(parent, name, input, output) { - var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); + var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(!!input, !!output); if (!FS.createDevice.major) FS.createDevice.major = 64; var dev = FS.makedev(FS.createDevice.major++, 0); @@ -1272,7 +1294,7 @@ mergeInto(LibraryManager.library, { return FS.mkdev(path, mode, dev); }, createLink: function(parent, name, target, canRead, canWrite) { - var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); + var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name); return FS.symlink(target, path); }, // Makes sure a file's contents are loaded. Returns whether the file has @@ -1462,7 +1484,7 @@ mergeInto(LibraryManager.library, { Browser.init(); // TODO we should allow people to just pass in a complete filename instead // of parent and name being that we just join them anyways - var fullname = name ? PATH.resolve(PATH.join(parent, name)) : parent; + var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent; function processData(byteArray) { function finish(byteArray) { if (!dontCreateFile) { diff --git a/src/library_gl.js b/src/library_gl.js index cfdd800d..544a33db 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -506,6 +506,7 @@ var LibraryGL = { case 0x1F01 /* GL_RENDERER */: case 0x1F02 /* GL_VERSION */: ret = allocate(intArrayFromString(Module.ctx.getParameter(name_)), 'i8', ALLOC_NORMAL); + break; case 0x1F03 /* GL_EXTENSIONS */: var exts = Module.ctx.getSupportedExtensions(); var gl_exts = []; @@ -514,8 +515,10 @@ var LibraryGL = { gl_exts.push("GL_" + exts[i]); } ret = allocate(intArrayFromString(gl_exts.join(' ')), 'i8', ALLOC_NORMAL); + break; case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */: ret = allocate(intArrayFromString('OpenGL ES GLSL 1.00 (WebGL)'), 'i8', ALLOC_NORMAL); + break; default: throw 'Failure: Invalid glGetString value: ' + name_; } @@ -1800,13 +1803,16 @@ var LibraryGL = { var glGetString = _glGetString; _glGetString = function(name_) { + if (GL.stringCache[name_]) return GL.stringCache[name_]; switch(name_) { case 0x1F03 /* GL_EXTENSIONS */: // Add various extensions that we can support - return allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ') + + var ret = allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ') + ' GL_EXT_texture_env_combine GL_ARB_texture_env_crossbar GL_ATI_texture_env_combine3 GL_NV_texture_env_combine4 GL_EXT_texture_env_dot3 GL_ARB_multitexture GL_ARB_vertex_buffer_object GL_EXT_framebuffer_object GL_ARB_vertex_program GL_ARB_fragment_program GL_ARB_shading_language_100 GL_ARB_shader_objects GL_ARB_vertex_shader GL_ARB_fragment_shader GL_ARB_texture_cube_map GL_EXT_draw_range_elements' + (GL.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') + (GL.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '') ), 'i8', ALLOC_NORMAL); + GL.stringCache[name_] = ret; + return ret; } return glGetString(name_); }; diff --git a/src/library_glfw.js b/src/library_glfw.js index b0519e39..647d4bb6 100644 --- a/src/library_glfw.js +++ b/src/library_glfw.js @@ -355,7 +355,9 @@ var LibraryGLFW = { } var contextAttributes = { - antialias: (GLFW.params[0x00020013] > 1) //GLFW_FSAA_SAMPLES + antialias: (GLFW.params[0x00020013] > 1), //GLFW_FSAA_SAMPLES + depth: (GLFW.params[0x00020009] > 0), //GLFW_DEPTH_BITS + stencil: (GLFW.params[0x0002000A] > 0) //GLFW_STENCIL_BITS } Module.ctx = Browser.createContext(Module['canvas'], true, true, contextAttributes); return 1; //GL_TRUE diff --git a/src/library_glut.js b/src/library_glut.js index 722ea85c..fefe7bd3 100644 --- a/src/library_glut.js +++ b/src/library_glut.js @@ -427,7 +427,9 @@ var LibraryGLUT = { glutCreateWindow__deps: ['$Browser'], glutCreateWindow: function(name) { var contextAttributes = { - antialias: ((GLUT.initDisplayMode & 0x0080 /*GLUT_MULTISAMPLE*/) != 0) + antialias: ((GLUT.initDisplayMode & 0x0080 /*GLUT_MULTISAMPLE*/) != 0), + depth: ((GLUT.initDisplayMode & 0x0010 /*GLUT_DEPTH*/) != 0), + stencil: ((GLUT.initDisplayMode & 0x0020 /*GLUT_STENCIL*/) != 0) }; Module.ctx = Browser.createContext(Module['canvas'], true, true, contextAttributes); return Module.ctx ? 1 /* a new GLUT window ID for the created context */ : 0 /* failure */; diff --git a/src/library_idbfs.js b/src/library_idbfs.js index 9031bad8..ab55673f 100644 --- a/src/library_idbfs.js +++ b/src/library_idbfs.js @@ -130,7 +130,7 @@ mergeInto(LibraryManager.library, { }; var toAbsolute = function(root) { return function(p) { - return PATH.join(root, p); + return PATH.join2(root, p); } }; diff --git a/src/library_memfs.js b/src/library_memfs.js index 94fd767e..588bbabd 100644 --- a/src/library_memfs.js +++ b/src/library_memfs.js @@ -1,6 +1,8 @@ mergeInto(LibraryManager.library, { $MEMFS__deps: ['$FS'], $MEMFS: { + ops_table: null, + // content modes CONTENT_OWNING: 1, // contains a subarray into the heap, and we own it, without copying (note: someone else needs to free() it, if that is necessary) CONTENT_FLEXIBLE: 2, // has been modified or never set to anything, and is a flexible js array that can grow/shrink @@ -13,51 +15,71 @@ mergeInto(LibraryManager.library, { // no supported throw new FS.ErrnoError(ERRNO_CODES.EPERM); } + if (!MEMFS.ops_table) { + MEMFS.ops_table = { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + allocate: MEMFS.stream_ops.allocate, + mmap: MEMFS.stream_ops.mmap + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + }, + }; + } var node = FS.createNode(parent, name, mode, dev); if (FS.isDir(node.mode)) { - node.node_ops = { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }; - node.stream_ops = { - llseek: MEMFS.stream_ops.llseek - }; + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; node.contents = {}; } else if (FS.isFile(node.mode)) { - node.node_ops = { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }; - node.stream_ops = { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap - }; + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; node.contents = []; node.contentMode = MEMFS.CONTENT_FLEXIBLE; } else if (FS.isLink(node.mode)) { - node.node_ops = { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }; - node.stream_ops = {}; + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; } else if (FS.isChrdev(node.mode)) { - node.node_ops = { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }; - node.stream_ops = FS.chrdev_stream_ops; + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; } node.timestamp = Date.now(); // add the new node to the parent @@ -117,7 +139,7 @@ mergeInto(LibraryManager.library, { } }, lookup: function(parent, name) { - throw new FS.ErrnoError(ERRNO_CODES.ENOENT); + throw FS.genericErrors[ERRNO_CODES.ENOENT]; }, mknod: function(parent, name, mode, dev) { return MEMFS.createNode(parent, name, mode, dev); diff --git a/src/library_nodefs.js b/src/library_nodefs.js index 2be54076..7686f3f2 100644 --- a/src/library_nodefs.js +++ b/src/library_nodefs.js @@ -134,7 +134,7 @@ mergeInto(LibraryManager.library, { } }, lookup: function (parent, name) { - var path = PATH.join(NODEFS.realPath(parent), name); + var path = PATH.join2(NODEFS.realPath(parent), name); var mode = NODEFS.getMode(path); return NODEFS.createNode(parent, name, mode); }, @@ -156,7 +156,7 @@ mergeInto(LibraryManager.library, { }, rename: function (oldNode, newDir, newName) { var oldPath = NODEFS.realPath(oldNode); - var newPath = PATH.join(NODEFS.realPath(newDir), newName); + var newPath = PATH.join2(NODEFS.realPath(newDir), newName); try { fs.renameSync(oldPath, newPath); } catch (e) { @@ -165,7 +165,7 @@ mergeInto(LibraryManager.library, { } }, unlink: function(parent, name) { - var path = PATH.join(NODEFS.realPath(parent), name); + var path = PATH.join2(NODEFS.realPath(parent), name); try { fs.unlinkSync(path); } catch (e) { @@ -174,7 +174,7 @@ mergeInto(LibraryManager.library, { } }, rmdir: function(parent, name) { - var path = PATH.join(NODEFS.realPath(parent), name); + var path = PATH.join2(NODEFS.realPath(parent), name); try { fs.rmdirSync(path); } catch (e) { @@ -192,7 +192,7 @@ mergeInto(LibraryManager.library, { } }, symlink: function(parent, newName, oldPath) { - var newPath = PATH.join(NODEFS.realPath(parent), newName); + var newPath = PATH.join2(NODEFS.realPath(parent), newName); try { fs.symlinkSync(oldPath, newPath); } catch (e) { @@ -283,4 +283,4 @@ mergeInto(LibraryManager.library, { } } } -});
\ No newline at end of file +}); diff --git a/src/library_path.js b/src/library_path.js index 09808acd..f00a7586 100644 --- a/src/library_path.js +++ b/src/library_path.js @@ -59,26 +59,22 @@ mergeInto(LibraryManager.library, { } return root + dir; }, - basename: function(path, ext) { + basename: function(path) { // EMSCRIPTEN return '/'' for '/', not an empty string if (path === '/') return '/'; - var f = PATH.splitPath(path)[2]; - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; + var lastSlash = path.lastIndexOf('/'); + if (lastSlash === -1) return path; + return path.substr(lastSlash+1); }, extname: function(path) { return PATH.splitPath(path)[3]; }, join: function() { var paths = Array.prototype.slice.call(arguments, 0); - return PATH.normalize(paths.filter(function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); + return PATH.normalize(paths.join('/')); + }, + join2: function(l, r) { + return PATH.normalize(l + '/' + r); }, resolve: function() { var resolvedPath = '', @@ -134,4 +130,4 @@ mergeInto(LibraryManager.library, { return outputParts.join('/'); } } -});
\ No newline at end of file +}); diff --git a/src/library_sdl.js b/src/library_sdl.js index 857ab7d4..e652dfc8 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -254,9 +254,13 @@ var LibrarySDL = { } var webGLContextAttributes = { - antialias: ((SDL.glAttributes[13 /*SDL_GL_MULTISAMPLEBUFFERS*/] != 0) && (SDL.glAttributes[14 /*SDL_GL_MULTISAMPLESAMPLES*/] > 1)) + antialias: ((SDL.glAttributes[13 /*SDL_GL_MULTISAMPLEBUFFERS*/] != 0) && (SDL.glAttributes[14 /*SDL_GL_MULTISAMPLESAMPLES*/] > 1)), + depth: (SDL.glAttributes[6 /*SDL_GL_DEPTH_SIZE*/] > 0), + stencil: (SDL.glAttributes[7 /*SDL_GL_STENCIL_SIZE*/] > 0) }; + var ctx = Browser.createContext(canvas, useWebGL, usePageCanvas, webGLContextAttributes); + SDL.surfaces[surf] = { width: width, height: height, diff --git a/src/preamble.js b/src/preamble.js index ee273f6a..9e72e7b8 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -1107,19 +1107,21 @@ var Math_min = Math.min; // it happens right before run - run will be postponed until // the dependencies are met. var runDependencies = 0; -var runDependencyTracking = {}; var runDependencyWatcher = null; var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled +#if ASSERTIONS +var runDependencyTracking = {}; +#endif function addRunDependency(id) { runDependencies++; if (Module['monitorRunDependencies']) { Module['monitorRunDependencies'](runDependencies); } +#if ASSERTIONS if (id) { assert(!runDependencyTracking[id]); runDependencyTracking[id] = 1; -#if ASSERTIONS if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { // Check for missing dependencies every few seconds runDependencyWatcher = setInterval(function() { @@ -1136,10 +1138,10 @@ function addRunDependency(id) { } }, 10000); } -#endif } else { Module.printErr('warning: run dependency added without ID'); } +#endif } Module['addRunDependency'] = addRunDependency; function removeRunDependency(id) { @@ -1147,12 +1149,14 @@ function removeRunDependency(id) { if (Module['monitorRunDependencies']) { Module['monitorRunDependencies'](runDependencies); } +#if ASSERTIONS if (id) { assert(runDependencyTracking[id]); delete runDependencyTracking[id]; } else { Module.printErr('warning: run dependency removed without ID'); } +#endif if (runDependencies == 0) { if (runDependencyWatcher !== null) { clearInterval(runDependencyWatcher); diff --git a/src/shell.html b/src/shell.html index a33735d9..53a4fffb 100644 --- a/src/shell.html +++ b/src/shell.html @@ -63,8 +63,11 @@ }, canvas: document.getElementById('canvas'), setStatus: function(text) { - if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); + if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; + if (text === Module.setStatus.text) return; var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + var now = Date.now(); + if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon var statusElement = document.getElementById('status'); var progressElement = document.getElementById('progress'); if (m) { diff --git a/tests/aniso.c b/tests/aniso.c index e8d7bd3f..f1674cad 100644 --- a/tests/aniso.c +++ b/tests/aniso.c @@ -66,6 +66,9 @@ int main(int argc, char *argv[]) const char *exts = (const char *)glGetString(GL_EXTENSIONS); assert(hasext(exts, "GL_EXT_texture_filter_anisotropic")); + const char *vendor = (const char *)glGetString(GL_VENDOR); + printf("vendor: %s\n", vendor); + GLint aniso; glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso); printf("Max anisotropy: %d (using that)\n", aniso); diff --git a/tests/test_browser.py b/tests/test_browser.py index be23074a..2ff9106b 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -869,6 +869,48 @@ keydown(100);keyup(100); // trigger the end def test_glut_wheelevents(self): self.btest('glut_wheelevents.c', '1') + def test_webgl_context_attributes(self): + # Javascript code to check the attributes support we want to test in the WebGL implementation + # (request the attribute, create a context and check its value afterwards in the context attributes). + # Tests will succeed when an attribute is not supported. + open(os.path.join(self.get_dir(), 'check_webgl_attributes_support.js'), 'w').write(''' + mergeInto(LibraryManager.library, { + webglAntialiasSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {antialias: true}); + attributes = context.getContextAttributes(); + return attributes.antialias; + }, + webglDepthSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {depth: true}); + attributes = context.getContextAttributes(); + return attributes.depth; + }, + webglStencilSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {stencil: true}); + attributes = context.getContextAttributes(); + return attributes.stencil; + } + }); + ''') + + # Copy common code file to temporary directory + filepath = path_from_root('tests/test_webgl_context_attributes_common.c') + temp_filepath = os.path.join(self.get_dir(), os.path.basename(filepath)) + shutil.copyfile(filepath, temp_filepath) + + # perform tests with attributes activated + self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + + # perform tests with attributes desactivated + self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + def test_emscripten_get_now(self): self.btest('emscripten_get_now.cpp', '1') |