draco/javascript/time_draco_decode.html
Frank Galligan c61ddb67f3 Update Draco snapshot.
-Increase version to 1.0.1
-Update Javascript decode timing example
-Fix async creation of DracoDecoderModule
-fixes wasm parallel decoding
-Introduce base class for geometric normal predictor
-Added integer attribute interface to JavaScript decoder
-Move loading Draco decoder into three.js Draco loader
-Add compiler launcher support to CMake build
-Add sanitizer support via CMake build
-Check we are not reading past the end of the attribute buffer
2017-08-21 16:04:57 -07:00

207 lines
6.2 KiB
HTML

<html>
<head>
<title>Draco Decode Timing</title>
<script type="text/javascript">
'use strict';
// Global Draco decoder.
let dracoDecoder = {};
let dracoDecoderType = {};
// This function loads a JavaScript file and adds it to the page. "path" is
// the path to the JavaScript file. "onLoadFunc" is the function to be called
// when the JavaScript file has been loaded.
function loadJavaScriptFile(path, onLoadFunc) {
const head = document.getElementsByTagName('head')[0];
const element = document.createElement('script');
element.type = 'text/javascript';
element.src = path;
if (onLoadFunc !== null)
element.onload = onLoadFunc;
head.appendChild(element);
}
function loadWebAssemblyDecoder() {
dracoDecoderType['wasmBinaryFile'] = 'draco_decoder.wasm';
const xhr = new XMLHttpRequest();
xhr.open('GET', 'draco_decoder.wasm', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
// For WebAssembly the object passed into DracoModule() must contain a
// property with the name of wasmBinary and the value must be an
// ArrayBuffer containing the contents of the .wasm file.
dracoDecoderType['wasmBinary'] = xhr.response;
createDracoDecoder();
};
xhr.send(null)
}
function createDracoDecoder() {
// draco_decoder.js or draco_wasm_wrapper.js must be loaded before
// DracoModule is created.
if (typeof dracoDecoderType === 'undefined')
dracoDecoderType = {};
dracoDecoderType['onModuleLoaded'] = function(module) {
enableButtons();
};
const create_t0 = performance.now();
dracoDecoder = DracoDecoderModule(dracoDecoderType);
const create_t1 = performance.now();
addCell('DracoModule', true);
addCell(' ' + (create_t1 - create_t0), false);
}
// This function will test if the browser has support for WebAssembly. If it
// does it will download the WebAssembly Draco decoder, if not it will download
// the asmjs Draco decoder.
function loadDracoDecoder() {
if (typeof WebAssembly !== 'object') {
// No WebAssembly support. DracoModule must be called with no parameters
// or an empty object to create a JavaScript decoder.
loadJavaScriptFile('draco_decoder.js', createDracoDecoder);
} else {
loadJavaScriptFile('draco_wasm_wrapper.js', loadWebAssemblyDecoder);
}
}
// Functions to handle logging output.
// String to hold table output.
let dt = '';
function startTable() {
dt += '<table><tr>';
dt += '<td>Filename</td>';
dt += '<td>Total milli</td>';
dt += '<td>Decode milli</td>';
dt += '<td>Size bytes</td>';
dt += '<td>Num points</td>';
}
function addCell(str, newRow) {
if (newRow)
dt += '</tr><tr>';
dt += '<td>' + str + '</td>';
}
function finishTable() {
dt += '</table>';
document.getElementById('tableOutput').innerHTML = dt;
}
function s_log(str, end_line, reset) {
if (reset)
document.getElementById('status').innerHTML = '';
document.getElementById('status').innerHTML += str;
if (end_line)
document.getElementById('status').innerHTML += "<br/>";
}
// Functions to handle the input from the buttons.
function enableButtons() {
document.getElementById('decodeOne').disabled = false;
document.getElementById('decodeMult').disabled = false;
}
function onDecodeClick() {
startTable();
const inputs = document.getElementById('u').value.split(',');
const build =
(typeof WebAssembly !== 'object') ? 'JavaScript' : 'WebAssembly';
s_log('Decoding ' + inputs.length + ' files... using ' + build, true, true);
testMeshDecodingAsync(inputs, 0);
}
function onDecodeMultipleClick() {
startTable();
const inputs = document.getElementById('u').value.split(',');
const decode_count = parseInt(document.getElementById('decode_count').value);
const build =
(typeof WebAssembly !== 'object') ? 'JavaScript' : 'WebAssembly';
s_log('Decoding ' + (decode_count * inputs.length) + ' files... using ' +
build, true, true);
let fileList = [];
for (let i = 0; i < decode_count; ++i) {
fileList = fileList.concat(inputs);
}
testMeshDecodingAsync(fileList, 0);
}
// Decode geometry.
function testMeshDecodingAsync(filenameList, index) {
const xhr = new XMLHttpRequest();
xhr.open("GET", filenameList[index], true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
const arrayBuffer = xhr.response;
if (arrayBuffer) {
const byteArray = new Uint8Array(arrayBuffer);
const total_t0 = performance.now();
const buffer = new dracoDecoder.DecoderBuffer();
buffer.Init(byteArray, byteArray.length);
const decoder = new dracoDecoder.Decoder();
const decode_t0 = performance.now();
const geometryType = decoder.GetEncodedGeometryType(buffer);
let dracoGeometry;
let decodingStatus;
if (geometryType == dracoDecoder.TRIANGULAR_MESH) {
dracoGeometry = new dracoDecoder.Mesh();
decodingStatus = decoder.DecodeBufferToMesh(buffer, dracoGeometry);
} else {
dracoGeometry = new dracoDecoder.PointCloud();
decodingStatus =
decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);
}
const t1 = performance.now();
addCell(filenameList[index], true);
addCell('' + (t1 - total_t0), false);
addCell('' + (t1 - decode_t0), false);
addCell('' + byteArray.length, false);
addCell('' + dracoGeometry.num_points(), false);
dracoDecoder.destroy(dracoGeometry);
dracoDecoder.destroy(decoder);
dracoDecoder.destroy(buffer);
if (index < filenameList.length - 1) {
index = index + 1;
testMeshDecodingAsync(filenameList, index);
} else {
finishTable();
}
}
};
xhr.send(null);
}
loadDracoDecoder();
</script>
</head>
<body>
<H1>Draco Decode Timing</H1>
Draco file to be decoded. If more than one file, add as comma separated list. E.g. "file1.drc,file2.drc,file3.drc"</br>
<input id="u" type="text" size="80" value="input.drc"/>
<input type="button" value="Decode" id="decodeOne" onClick="onDecodeClick();" disabled>
<input id="decode_count" type="text" size="10" value="10"/>
<input type="button" value="Decode Multiple" id="decodeMult" onClick="onDecodeMultipleClick();" disabled>
<br/>
<div id="status"> </div></br>
<div id="tableOutput"> </div>
</body>
</html>