aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-03-15 18:15:12 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-03-15 18:15:12 -0700
commit3fc8b5c9b7fd5393d936caad6a9ceb1923509fe6 (patch)
treee4ea021dc7a2bd88bc2b19223800e3ba9a2687e0
parent7e78583ff2d44d669d969054e46167a0fb865b21 (diff)
preload images for SDL
-rwxr-xr-xemcc58
-rw-r--r--src/library_sdl.js10
-rw-r--r--src/preamble.js4
-rwxr-xr-xtests/runner.py7
4 files changed, 52 insertions, 27 deletions
diff --git a/emcc b/emcc
index 96d8a8a4..50c83993 100755
--- a/emcc
+++ b/emcc
@@ -208,6 +208,12 @@ Options that are modified or new in %s include:
similar to --embed-file, except that this
option is only relevant when generating
HTML (it uses asynchronous binary XHRs).
+ Note that files with typical image suffixes
+ (png, jpg, bmp) will be preloaded as images.
+ Their pixel data will be available for SDL_image
+ to load (IMG_Load), but they will not be
+ available as normal data files (if you need
+ the alternative, change the suffix).
--ignore-dynamic-linking Normally emcc will treat dynamic linking like
static linking, by linking in the code from
the dynamic library. This fails if the same
@@ -283,6 +289,8 @@ STATICLIB_SUFFIXES = ('.a',)
ASSEMBLY_SUFFIXES = ('.ll',)
LIB_PREFIXES = ('', 'lib')
+IMAGE_SUFFIXES = ('.jpg', '.png', '.bmp')
+
def suffix(name):
return name.split('.')[:-1]
@@ -756,25 +764,47 @@ try:
partial_dirs.append(partial)
for filename in embed_files:
+ if filename.endswith(IMAGE_SUFFIXES):
+ print >> sys.stderr, 'emcc: warning: embedding file %s, but not making sure it decodes synchronously. consider using --preload-file' % filename
code += '''FS.createDataFile('/', '%s', %s, true, true);\n''' % (os.path.basename(filename), str(map(ord, open(filename, 'rb').read())))
+
counter = 0
for filename in preload_files:
varname = 'filePreload%d' % counter
counter += 1
- code += '''
- var %(varname)s = new XMLHttpRequest();
- %(varname)s.open("GET", "%(filename)s", true);
- %(varname)s.responseType = 'arraybuffer';
- addRunDependency();
- %(varname)s.onload = function() {
- var arrayBuffer = %(varname)s.response; // Note: not X.responseText
- assert(arrayBuffer, 'Loading file %(filename)s failed.');
- var byteArray = new Uint8Array(arrayBuffer);
- FS.createDataFile('/%(dirname)s', '%(basename)s', byteArray, true, true);
- removeRunDependency();
- };
- %(varname)s.send(null);
-''' % { 'varname': varname, 'filename': filename, 'dirname': os.path.dirname(filename), 'basename': os.path.basename(filename) }
+ image = filename.endswith(IMAGE_SUFFIXES)
+ if not image:
+ code += '''
+ var %(varname)s = new XMLHttpRequest();
+ %(varname)s.open('GET', '%(filename)s', true);
+ %(varname)s.responseType = 'arraybuffer';
+ %(varname)s.onload = function() {
+ var arrayBuffer = %(varname)s.response; // Note: not X.responseText
+ assert(arrayBuffer, 'Loading file %(filename)s failed.');
+ var byteArray = new Uint8Array(arrayBuffer);
+ FS.createDataFile('/%(dirname)s', '%(basename)s', byteArray, true, true);
+ removeRunDependency();
+ };
+ addRunDependency();
+ %(varname)s.send(null);
+ ''' % { 'varname': varname, 'filename': filename, 'dirname': os.path.dirname(filename), 'basename': os.path.basename(filename) }
+ else:
+ print >> sys.stderr, 'emcc: warning: preloading file %s as image because of suffix. it will not be available to load as a normal file' % filename
+ code += '''
+ var %(varname)s = new Image();
+ %(varname)s.src = '%(filename)s';
+ %(varname)s.onload = function() {
+ assert(%(varname)s.complete, 'Image could not be decoded');
+ var canvas = document.createElement('canvas');
+ canvas.width = %(varname)s.width;
+ canvas.height = %(varname)s.height;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(%(varname)s, 0, 0);
+ preloadedImages['%(filename)s'] = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ removeRunDependency();
+ };
+ addRunDependency();
+ ''' % { 'varname': varname, 'filename': filename }
src = open(final).read().replace('// {{PRE_RUN_ADDITIONS}}', code)
final += '.files.js'
diff --git a/src/library_sdl.js b/src/library_sdl.js
index e741faeb..3f5a8a87 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -478,14 +478,8 @@ mergeInto(LibraryManager.library, {
IMG_Load: function(filename) {
filename = Pointer_stringify(filename);
- var format = filename.split('.').slice(-1)[0];
- var file = FS.analyzePath(filename);
- if (!file || !file.object) {
- console.log('Cannot find file: ' + filename);
- return 0;
- }
- var data = file.object.contents;
- var raw = Browser.decodeImage(data, format);
+ var raw = preloadedImages[filename];
+ assert(raw, 'Cannot find preloaded image ' + filename);
var surf = SDL.makeSurface(raw.width, raw.height, 0);
// XXX Extremely inefficient!
for (var i = 0; i < raw.width*raw.height*4; i++) {
diff --git a/src/preamble.js b/src/preamble.js
index 1e68295f..1c599836 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -892,5 +892,9 @@ function removeRunDependency() {
if (runDependencies == 0) run();
}
+// Preloading
+
+var preloadedImages = {}; // maps url to image data
+
// === Body ===
diff --git a/tests/runner.py b/tests/runner.py
index 0eca1598..4fc8cfa9 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -6280,14 +6280,11 @@ f.close()
def test_emcc_sdl_image(self):
# load an image file, get pixel data
-
- return self.skip('decoding is async, we need sync...')
-
shutil.copyfile(path_from_root('tests', 'screenshot.jpg'), os.path.join(self.get_dir(), 'screenshot.jpg'))
- shutil.copyfile(path_from_root('tests', 'sdl_image.c'), os.path.join(self.get_dir(), 'sdl_image.c'))
+ open(os.path.join(self.get_dir(), 'sdl_image.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_image.c')).read()))
Popen([EMCC, os.path.join(self.get_dir(), 'sdl_image.c'), '--preload-file', 'screenshot.jpg', '-o', 'page.html']).communicate()
- self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?1')
+ self.run_browser('page.html', 'You should see |load me right before|.', '/report_result?600')
def test_emcc_compression(self):
pass # test compression of both the compiled code itself in a side file, and of data files