From 18e0d11803def71b155d93139389099b10887405 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 2 May 2020 23:12:31 -0400 Subject: [PATCH] port rle encoding to wasm. deprecate js but preserve as legacy for debugging --- js/kiri-driver-sla.js | 189 ++++++++++++++++++++++++++---------------- wasm/kiri-sla.c | 55 +++++++++++- wasm/kiri-sla.wasm | Bin 1237 -> 1777 bytes 3 files changed, 172 insertions(+), 72 deletions(-) diff --git a/js/kiri-driver-sla.js b/js/kiri-driver-sla.js index 161ead02..b345e55e 100644 --- a/js/kiri-driver-sla.js +++ b/js/kiri-driver-sla.js @@ -32,7 +32,10 @@ let gs_kiri_sla = exports; preview, previewSmall, previewLarge, - fill_cache; + fill_cache, + legacy = false; + + if (legacy) console.log("SLA Driver in Legacy Mode"); /** * DRIVER SLICE CONTRACT - runs in worker @@ -48,9 +51,9 @@ let gs_kiri_sla = exports; work_total, work_remain; - // if (!self.OffscreenCanvas) { - // return ondone("browser lacks support for OffscreenCanvas",true); - // } + if (legacy && !self.OffscreenCanvas) { + return ondone("browser lacks support for OffscreenCanvas",true); + } // calculate % complete and call onupdate() function doupdate(work, msg) { @@ -594,7 +597,6 @@ let gs_kiri_sla = exports; device = settings.device, process = settings.process, output = print.output, - images = [], layermax = 0, width = 2560, height = 1440, @@ -602,26 +604,35 @@ let gs_kiri_sla = exports; height2 = height/2, scaleX = width / device.bedWidth, scaleY = height / device.bedDepth, - mark = Date.now(); + mark = Date.now(), + layers = process.slaAntiAlias || 1, + masks = [], + images = [], + slices = []; + + let d = 8 / layers; + for (let i=0; i { layermax = Math.max(widget.slices.length); }); - // let render = renderLayer; - let render = renderLayerWasm; + let render = legacy ? renderLayer : renderLayerWasm; // generate layer 8-bit bitaps using canvas for (let index=0; index < layermax; index++) { - let param = { index, width, height, widgets, scaleX, scaleY }; - let {data, end} = render(param); - images.push(data); + let param = { index, width, height, widgets, scaleX, scaleY, masks }; + let {image, layers, end} = render(param); + images.push(image); + slices.push(layers); // transfer images to browser main online({ - progress: (index / layermax) * 0.25, + progress: (index / layermax) * 0.85, message: "image_gen", - data: data + data: image }); if (end) break; } @@ -640,11 +651,12 @@ let gs_kiri_sla = exports; let file = exp_func(print, { width: width, height: height, - lines: images, small: previewSmall.data, - large: previewLarge.data + large: previewLarge.data, + lines: images, + slices: slices }, (progress, message) => { - online({progress: progress * 0.75 + 0.25, message}); + online({progress: progress * 0.15 + 0.85, message}); }); ondone({ @@ -833,42 +845,57 @@ let gs_kiri_sla = exports; layerBytes = width * height, small = conf.small, large = conf.large, + slices = conf.slices, subcount = process.slaAntiAlias || 1, - masks = []; + masks = [], + coded; - let d = 8 / subcount; - for (let i=0; i { - let count = line.length; - let lineDV = new DataView(line.buffer); - let bits = new Uint8Array(line.length); - let bitsDV = new DataView(bits.buffer); - let subs = [{ data: bits, view: bitsDV }]; - for (let sl=1; sl { + let count = line.length; + let lineDV = new DataView(line.buffer); + let bits = new Uint8Array(line.length); + let bitsDV = new DataView(bits.buffer); + let subs = [{ data: bits, view: bitsDV }]; + for (let sl=1; sl { + progress(pro * 0.4 + 0.4, "layer_encode"); + })); + } else { + let codedlen = slices.reduce((t,l) => { + return t + l.reduce((t,a) => { + return t + a.length + }, 0); + }, 0); + coded = { + layers: slices.map(slice => { return { sublayers: slice }}), + length: codedlen + }; + } - let coded = encodeLayers(converted, "photon", (pro => { - progress(pro * 0.4 + 0.4, "layer_encode"); - })); let buflen = 3000 + coded.length + (layerCount * subcount * 28) + small.byteLength + large.byteLength; let filebuf = new ArrayBuffer(buflen); let filedat = new DataWriter(new DataView(filebuf)); @@ -972,27 +999,41 @@ let gs_kiri_sla = exports; device = printset.device, width = conf.width, height = conf.height, + slices = conf.slices, layerCount = conf.lines.length, - layerBytes = width * height; + layerBytes = width * height, + coded; - let converted = conf.lines.map((line, index) => { - let count = line.length / 4; - let bits = new Uint8Array(line.length / 4); - let bitsDV = new DataView(bits.buffer); - let lineDV = new DataView(line.buffer); - // reduce RGB to R = 0||1 - for (let i = 0; i < count; i++) { - // defeat anti-aliasing for the moment - bitsDV.setUint8(i, lineDV.getUint8(i * 4) > 0 ? 1 : 0); - } - progress(index / conf.lines.length); - return { subs: [{ - exposureTime: process.slaLayerOn, - data: bits - }] }; - }); + if (legacy) { + let converted = conf.lines.map((line, index) => { + let count = line.length / 4; + let bits = new Uint8Array(line.length / 4); + let bitsDV = new DataView(bits.buffer); + let lineDV = new DataView(line.buffer); + // reduce RGB to R = 0||1 + for (let i = 0; i < count; i++) { + // defeat anti-aliasing for the moment + bitsDV.setUint8(i, lineDV.getUint8(i * 4) > 0 ? 1 : 0); + } + progress(index / conf.lines.length); + return { subs: [{ + exposureTime: process.slaLayerOn, + data: bits + }] }; + }); + coded = encodeLayers(converted, "photons"); + } else { + let codedlen = slices.reduce((t,l) => { + return t + l.reduce((t,a) => { + return t + a.length + }, 0); + }, 0); + coded = { + layers: slices.map(slice => { return { sublayers: slice }}), + length: codedlen + }; + } - let coded = encodeLayers(converted, "photons"); let filebuf = new ArrayBuffer(75366 + coded.length + 28 * layerCount); let filedat = new DataView(filebuf); let filePos = 0; @@ -1282,13 +1323,14 @@ let gs_kiri_sla = exports; self.wasm = { heap, memory: exports.memory, - render: exports.render + render: exports.render, + rle_encode: exports.rle_encode }; // console.log({heap}); }); self.renderLayerWasm = function renderLayer(params) { - let { width, height, index, widgets, scaleX, scaleY } = params; + let { width, height, index, widgets, scaleX, scaleY, masks } = params; let width2 = width / 2, height2 = height / 2; let array = []; let count = 0; @@ -1359,10 +1401,15 @@ let gs_kiri_sla = exports; writePoly(writer, poly); } - let out = wasm.render(0, imagelen, 0); - let data = wasm.heap.slice(0, imagelen); + wasm.render(0, imagelen, 0); + let image = wasm.heap.slice(0, imagelen), layers = []; - return { data: data, end: count === 0 }; + for (let l=0; lheight); } - return 1; + return readoff; +} + +Uint8 rle_byte(Uint8 color, Uint8 count, Uint8 type) { + if (type == 0) { + return (count & 0x7f) | ((color << 7) & 0x80); + } else { + Uint8 run = count - 1; + return + (run & 1 ? 128 : 0) | + (run & 2 ? 64 : 0) | + (run & 4 ? 32 : 0) | + (run & 8 ? 16 : 0) | + (run & 16 ? 8 : 0) | + (run & 32 ? 4 : 0) | + (run & 64 ? 2 : 0) | color; + } +} + +/** + * mem = memory base pointer + * in = input memory location (raster) + * ilen = input raster length in bytes + * out = output memory location (for rle-encoded image) + * type = 0=photon, 1=photons + * returns length of rle-encoded image + */ +EMSCRIPTEN_KEEPALIVE +Uint32 rle_encode(unsigned char *mem, Uint32 in, Uint32 ilen, Uint8 mask, Uint32 out, Uint8 type) { + Uint8 color = (mem[in++] & mask) ? 1 : 0; // current color + Uint8 count = 1; // number of color matches + Uint8 cmax = type == 0 ? 125 : 128; // count max + Uint8 next; // next color + Uint32 opos = out; + while (--ilen > 0) { + next = (mem[in++] & mask) ? 1 : 0; + if (color != next || count == cmax) { + mem[opos++] = rle_byte(color, count, type); + count = 0; + } + count++; + color = next; + } + + if (count > 0) { + mem[opos++] = rle_byte(color, count, type); + } + return opos - out; } diff --git a/wasm/kiri-sla.wasm b/wasm/kiri-sla.wasm index 9f08aa3884643f48f7c80c8bebffa0823e9dcc0a..7989e1181d8efcee2f9d1f64c2395a10cafea632 100644 GIT binary patch delta 687 zcmZ9Jv2N5r5Qb;QyKCRAPfCBy*cB9r0*QjkQ-p|;h6*Vc5f>OPk$u)lRO@%(J&+JD zz)Mi^6e&T9V0L|05H9Rl??3;1`|pp{-R3=99rg$S$aV*?qYz-1h2@Q5=X9YDhRj(& zlaY0Z6HSyqHg4bUZ--9=ZfI|=+X1rm@UgvYZ{FQrw?OXlFkTHK!1}(lUthn)@GHYS z2v#`*WA_ArvtHn$a@0`6B%!NU=cZv(73?Z1(aVH#4{W!UXB6xzRG~d-vgRM3dL5l; zQ3cg`&gBpGFE_x%?jQksEpxTizM_k}(90AA*a`OA;RWdbIHeHq@tZSMj#mk61D?|i z7Y$~_GHbLsO<{k*<^Mc29inmMRp-#LQ?Z`XNj?rb)Q<8U`dDS7a4K+=vs5U#>hLJV zEI5iug*^)O5mi9>X51y56QB+`!Iuy4oT-<5*{ delta 144 zcmey!dzCYgA+b1@k%57MQH&*lfgypZzMdh0xgJI`)-$uRFfcMRv9d8THZV0XvCA;C z<)-H57gaJbuob1|rKA=yFtNoKmn0UIFfefaeh#!~&M`