From ab082692769e2ebee3c34cccf66443d8060fd9cc Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Wed, 25 Apr 2018 22:39:51 +0200 Subject: [PATCH] Clarify the use of RGBA vs ABGR in the game-of-life example --- examples/game-of-life/assembly/index.ts | 18 +- examples/game-of-life/build/optimized.wasm | Bin 920 -> 904 bytes examples/game-of-life/build/optimized.wat | 491 +++++++-------- examples/game-of-life/build/untouched.wat | 661 ++++++++------------- examples/game-of-life/index.html | 7 +- 5 files changed, 492 insertions(+), 685 deletions(-) diff --git a/examples/game-of-life/assembly/index.ts b/examples/game-of-life/assembly/index.ts index 3b1dee1e..66d96e76 100644 --- a/examples/game-of-life/assembly/index.ts +++ b/examples/game-of-life/assembly/index.ts @@ -1,8 +1,10 @@ // see: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life -// Configuration imported from JS. -declare const RGB_ALIVE: u32; -declare const RGB_DEAD: u32; +// Configuration imported from JS. On the WASM side, colors are handled in ABGR order (alpha, blue, +// green, red) because WASM is little endian. Doing so makes it possible to just copy the entire +// ABGR memory in little endian byte order to the RGBA image buffer in big endian byte order. +declare const BGR_ALIVE: u32; +declare const BGR_DEAD: u32; declare const BIT_ROT: u32; var w: i32, h: i32, s: i32; @@ -35,7 +37,7 @@ export function init(width: i32, height: i32): void { // Start by filling output with random live cells. for (let y = 0; y < h; ++y) { for (let x = 0; x < w; ++x) { - set(x, y, Math.random() > 0.1 ? RGB_DEAD & 0x00ffffff : RGB_ALIVE | 0xff000000); + set(x, y, Math.random() > 0.1 ? BGR_DEAD & 0x00ffffff : BGR_ALIVE | 0xff000000); } } } @@ -67,10 +69,10 @@ export function step(): void { // A live cell with 2 or 3 live neighbors rots on to the next generation. if ((aliveNeighbors & 0b1110) == 0b0010) rot(x, y, self); // A live cell with fewer than 2 or more than 3 live neighbors dies. - else set(x, y, RGB_DEAD | 0xff000000); + else set(x, y, BGR_DEAD | 0xff000000); } else { // A dead cell with exactly 3 live neighbors becomes a live cell. - if (aliveNeighbors == 3) set(x, y, RGB_ALIVE | 0xff000000); + if (aliveNeighbors == 3) set(x, y, BGR_ALIVE | 0xff000000); // A dead cell with fewer or more than 3 live neighbors just rots. else rot(x, y, self); } @@ -81,9 +83,9 @@ export function step(): void { /** Fills the row and column indicated by `x` and `y` with random live cells. */ export function fill(x: u32, y: u32, p: f64): void { for (let ix = 0; ix < w; ++ix) { - if (Math.random() < p) set(ix, y, RGB_ALIVE | 0xff000000); + if (Math.random() < p) set(ix, y, BGR_ALIVE | 0xff000000); } for (let iy = 0; iy < h; ++iy) { - if (Math.random() < p) set(x, iy, RGB_ALIVE | 0xff000000); + if (Math.random() < p) set(x, iy, BGR_ALIVE | 0xff000000); } } diff --git a/examples/game-of-life/build/optimized.wasm b/examples/game-of-life/build/optimized.wasm index 98888cfe522bf2f56206e158590494b89649687b..db5cf7713f73f31e471ab04e4a4290fb58c5d94f 100644 GIT binary patch literal 904 zcmaJ=!EVz)5S`gs$0>_YR4$b`u#R)!)FW52Roc?3Ri#k4HdbT6Zk#xdDW$69{04jp zd;(t;W*s+i2*L+@XLjDanR#OfW(fiSK9>Vg6fgjM7yt~YC>}suI24X=cMgvGSLW>G z!yy%59Zl=#9hzQcy9XziSN)4iHXEn!&V&4OBMZjENdjoY8%dZeQdsM#( zcM4w`yzyM0?5DXR)gZYj_Bq;Bo~_G0l7#_I&Iy!fOI%l_B{OPd2s1IHsoG@OUkQ$$ zR<~-A#5h|qrKfCsNgeCbQ%8AXndvdA&7DtWR}1rO zYQ&N3{xv`{d$+#0X$u1!1E(*{Uao05_l$?@Y{s)Br4oFj90t%<#z(ETv7Gk*T&&-} zrObGTSUakAM2qXP58fGGgmQ{CR>eHL1Z03#ofcar8&65WTx{jdE0?I%I{2ll$I0RR91 delta 452 zcmY+AO-jT-5QVF&I>|Tz6;WnHl>R~V1Ox8Ug5wXaT(}hxHyKeP<7`}H>(bC0ui!CU z=@qN)zOpqsXkxJUlJ>& zl}=1_WGS?mGKE&2Np7-K$XcYLR3{2mG?t}b?&`rxRI@)d6DrNA~0 onmDc;2mTv(<8VEV{tw+2@%gAZ_Bzjd*Gxq|qk-R}zQ3h|f0MvceE response.arrayBuffer()) .then(buffer => WebAssembly.instantiate(buffer, { env: { - RGB_ALIVE : rgb2le(RGB_ALIVE) | 1, // little endian, LSB must be set - RGB_DEAD : rgb2le(RGB_DEAD) & ~1, // little endian, LSB must not be set + BGR_ALIVE : rgb2bgr(RGB_ALIVE) | 1, // little endian, LSB must be set + BGR_DEAD : rgb2bgr(RGB_DEAD) & ~1, // little endian, LSB must not be set BIT_ROT, memory, abort: function() {} @@ -125,7 +125,8 @@ fetch("build/optimized.wasm") console.log(err.stack); }); -function rgb2le(rgb) { +// see comment in assembly/index.ts on why this is useful +function rgb2bgr(rgb) { return ((rgb >>> 16) & 0xff) | (rgb & 0xff00) | (rgb & 0xff) << 16; }