KTX2Transcoder.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import Check from "./Check.js";
  2. import CompressedTextureBuffer from "./CompressedTextureBuffer.js";
  3. import defined from "./defined.js";
  4. import TaskProcessor from "./TaskProcessor.js";
  5. /**
  6. * Transcodes KTX2 textures using web workers.
  7. *
  8. * @private
  9. */
  10. function KTX2Transcoder() {}
  11. KTX2Transcoder._transcodeTaskProcessor = new TaskProcessor(
  12. "transcodeKTX2",
  13. Number.POSITIVE_INFINITY // KTX2 transcoding is used in place of Resource.fetchImage, so it can't reject as "just soooo busy right now"
  14. );
  15. KTX2Transcoder._readyPromise = undefined;
  16. function makeReadyPromise() {
  17. const readyPromise = KTX2Transcoder._transcodeTaskProcessor
  18. .initWebAssemblyModule({
  19. modulePath: "ThirdParty/Workers/basis_transcoder.js",
  20. wasmBinaryFile: "ThirdParty/basis_transcoder.wasm",
  21. })
  22. .then(function () {
  23. return KTX2Transcoder._transcodeTaskProcessor;
  24. });
  25. KTX2Transcoder._readyPromise = readyPromise;
  26. }
  27. KTX2Transcoder.transcode = function (ktx2Buffer, supportedTargetFormats) {
  28. //>>includeStart('debug', pragmas.debug);
  29. Check.defined("supportedTargetFormats", supportedTargetFormats);
  30. //>>includeEnd('debug');
  31. if (!defined(KTX2Transcoder._readyPromise)) {
  32. makeReadyPromise();
  33. }
  34. return KTX2Transcoder._readyPromise
  35. .then(function (taskProcessor) {
  36. let parameters;
  37. if (ktx2Buffer instanceof ArrayBuffer) {
  38. const view = new Uint8Array(ktx2Buffer);
  39. parameters = {
  40. supportedTargetFormats: supportedTargetFormats,
  41. ktx2Buffer: view,
  42. };
  43. return taskProcessor.scheduleTask(parameters, [ktx2Buffer]);
  44. }
  45. parameters = {
  46. supportedTargetFormats: supportedTargetFormats,
  47. ktx2Buffer: ktx2Buffer,
  48. };
  49. return taskProcessor.scheduleTask(parameters, [ktx2Buffer.buffer]);
  50. })
  51. .then(function (result) {
  52. const levelsLength = result.length;
  53. const faceKeys = Object.keys(result[0]);
  54. const faceKeysLength = faceKeys.length;
  55. let i;
  56. for (i = 0; i < levelsLength; i++) {
  57. const faces = result[i];
  58. for (let j = 0; j < faceKeysLength; j++) {
  59. const face = faces[faceKeys[j]];
  60. faces[faceKeys[j]] = new CompressedTextureBuffer(
  61. face.internalFormat,
  62. face.datatype,
  63. face.width,
  64. face.height,
  65. face.levelBuffer
  66. );
  67. }
  68. }
  69. // Cleaning up parsed result if it's a single image
  70. if (faceKeysLength === 1) {
  71. for (i = 0; i < levelsLength; ++i) {
  72. result[i] = result[i][faceKeys[0]];
  73. }
  74. if (levelsLength === 1) {
  75. result = result[0];
  76. }
  77. }
  78. return result;
  79. })
  80. .catch(function (error) {
  81. throw error;
  82. });
  83. };
  84. export default KTX2Transcoder;