Hi I’m testing a b3dm tiles contain crn textures.
I saw a strange thins : some textures were displayed and some textures were not displayed. It was not a particular texture problem.
And found a exception at worker side (occurs in createTaskProcessorWorker.js:57 line
function createTaskProcessorWorker(workerFunction) {
var postMessage;
var transferableObjects = ;
var responseMessage = {
id : undefined,
result : undefined,
error : undefined
};
return function(event) {
/*global self*/
var data = event.data;
transferableObjects.length = 0;
responseMessage.id = data.id;
responseMessage.error = undefined;
responseMessage.result = undefined;
try {
responseMessage.result = workerFunction(data.parameters, transferableObjects);
} catch (e) {
if (e instanceof Error) {
// Errors can't be posted in a message, copy the properties
responseMessage.error = {
name : e.name,
message : e.message,
stack : e.stack
};
} else {
responseMessage.error = e;
}
}
if (!defined(postMessage)) {
postMessage = defaultValue(self.webkitPostMessage, self.postMessage);
}
if (!data.canTransferArrayBuffer) {
transferableObjects.length = 0;
}
try {
postMessage(responseMessage, transferableObjects);
} catch (e) {
// something went wrong trying to post the message, post a simpler
// error that we can be sure will be cloneable
responseMessage.result = undefined;
responseMessage.error = 'postMessage failed with error: ' + formatError(e) + '\n with responseMessage: ' + JSON.stringify(responseMessage);
postMessage(responseMessage);
}
};
}
``
**Exception detail => **
"RangeError: Source is too large
at Uint8Array.set (native)
at transcodeCRNToDXT (Workers/transcodeCRNToDXT.js:136:23 )
at createTaskProcessorWorker.js:55:42"
**So I looked at transcodeCRNToDXT exception point( **transcodeCRNToDXT.js:136 line)
=> level0DXTData.set(dxtData, 0)
function transcodeCRNToDXT(arrayBuffer, transferableObjects) {
// Copy the contents of the arrayBuffer into emscriptens heap.
var srcSize = arrayBuffer.byteLength;
var bytes = new Uint8Array(arrayBuffer);
var src = crunch._malloc(srcSize);
arrayBufferCopy(bytes, crunch.HEAPU8, src, srcSize);
// Determine what type of compressed data the file contains.
var crnFormat = crunch._crn_get_dxt_format(src, srcSize);
var format = DXT_FORMAT_MAP[crnFormat];
if (!defined(format)) {
throw new RuntimeError('Unsupported compressed format.');
}
// Gather basic metrics about the DXT data.
var levels = crunch._crn_get_levels(src, srcSize);
var width = crunch._crn_get_width(src, srcSize);
var height = crunch._crn_get_height(src, srcSize);
// Determine the size of the decoded DXT data.
var dstSize = 0;
var i;
for (i = 0; i < levels; ++i) {
dstSize += PixelFormat.compressedTextureSizeInBytes(format, width >> i, height >> i);
}
// Allocate enough space on the emscripten heap to hold the decoded DXT data
// or reuse the existing allocation if a previous call to this function has
// already acquired a large enough buffer.
if(cachedDstSize < dstSize) {
if(defined(dst)) {
crunch._free(dst);
}
dst = crunch._malloc(dstSize);
dxtData = new Uint8Array(crunch.HEAPU8.buffer, dst, dstSize);
cachedDstSize = dstSize;
}
// Decompress the DXT data from the Crunch file into the allocated space.
crunch._crn_decompress(src, srcSize, dst, dstSize, 0, levels);
// Release the crunch file data from the emscripten heap.
crunch._free(src);
// Mipmaps are unsupported, so copy the level 0 texture
// When mipmaps are supported, a copy will still be necessary as dxtData is a view on the heap.
var length = PixelFormat.compressedTextureSizeInBytes(format, width, height);
var level0DXTData = new Uint8Array(length);
level0DXTData.set(dxtData, 0);
transferableObjects.push(level0DXTData.buffer);
return new CompressedTextureBuffer(format, width, height, level0DXTData);
}
``
I think cache buffer(dxtData) is too big to copy to result buffer(level0DXTData).
So I replaced
level0DXTData.set(dxtData, 0);
=>
level0DXTData = dxtData.slice(0, length);
And it works.
I’m not sure it is perfect solution. so I hope cesium team review my solution.
Thanks
Shyoo.