Browse Source

Merge pull request #19541 from upisfree/feat-basistextureloader-taskcache

BasisTextureLoader: Support repeated loading of same texture
Mr.doob 5 years ago
parent
commit
43d0031783

+ 26 - 4
examples/js/loaders/BasisTextureLoader.js

@@ -3,6 +3,7 @@ console.warn( "THREE.BasisTextureLoader: As part of the transition to ES6 Module
  * @author Don McCurdy / https://www.donmccurdy.com
  * @author Don McCurdy / https://www.donmccurdy.com
  * @author Austin Eng / https://github.com/austinEng
  * @author Austin Eng / https://github.com/austinEng
  * @author Shrek Shao / https://github.com/shrekshao
  * @author Shrek Shao / https://github.com/shrekshao
+ * @author Senya Pugach / https://upisfr.ee
  */
  */
 
 
 /**
 /**
@@ -40,6 +41,8 @@ THREE.BasisTextureLoader = function ( manager ) {
 
 
 };
 };
 
 
+THREE.BasisTextureLoader.taskCache = new WeakMap();
+
 THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
 THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
 
 
 	constructor: THREE.BasisTextureLoader,
 	constructor: THREE.BasisTextureLoader,
@@ -109,7 +112,17 @@ THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.
 
 
 		loader.load( url, ( buffer ) => {
 		loader.load( url, ( buffer ) => {
 
 
-			this._createTexture( buffer )
+			// Check for an existing task using this buffer. A transferred buffer cannot be transferred
+			// again from this thread.
+			if ( THREE.BasisTextureLoader.taskCache.has( buffer ) ) {
+
+				var cachedTask = THREE.BasisTextureLoader.taskCache.get( buffer );
+
+				return cachedTask.promise.then( onLoad ).catch( onError );
+
+			}
+
+			this._createTexture( buffer, url )
 				.then( onLoad )
 				.then( onLoad )
 				.catch( onError );
 				.catch( onError );
 
 
@@ -118,10 +131,11 @@ THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.
 	},
 	},
 
 
 	/**
 	/**
-	 * @param  {ArrayBuffer} buffer
+	 * @param	{ArrayBuffer} buffer
+	 * @param	{string} url
 	 * @return {Promise<THREE.CompressedTexture>}
 	 * @return {Promise<THREE.CompressedTexture>}
 	 */
 	 */
-	_createTexture: function ( buffer ) {
+	_createTexture: function ( buffer, url ) {
 
 
 		var worker;
 		var worker;
 		var taskID;
 		var taskID;
@@ -200,6 +214,14 @@ THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.
 
 
 			} );
 			} );
 
 
+		// Cache the task result.
+		THREE.BasisTextureLoader.taskCache.set( buffer, {
+
+			url: url,
+			promise: texturePending
+
+		} );
+
 		return texturePending;
 		return texturePending;
 
 
 	},
 	},
@@ -466,7 +488,7 @@ THREE.BasisTextureLoader.BasisWorker = function () {
 		if ( ! width || ! height || ! levels ) {
 		if ( ! width || ! height || ! levels ) {
 
 
 			cleanup();
 			cleanup();
-			throw new Error( 'THREE.BasisTextureLoader:  Invalid .basis file' );
+			throw new Error( 'THREE.BasisTextureLoader:	Invalid .basis file' );
 
 
 		}
 		}
 
 

+ 26 - 4
examples/jsm/loaders/BasisTextureLoader.js

@@ -2,6 +2,7 @@
  * @author Don McCurdy / https://www.donmccurdy.com
  * @author Don McCurdy / https://www.donmccurdy.com
  * @author Austin Eng / https://github.com/austinEng
  * @author Austin Eng / https://github.com/austinEng
  * @author Shrek Shao / https://github.com/shrekshao
  * @author Shrek Shao / https://github.com/shrekshao
+ * @author Senya Pugach / https://upisfr.ee
  */
  */
 
 
 import {
 import {
@@ -53,6 +54,8 @@ var BasisTextureLoader = function ( manager ) {
 
 
 };
 };
 
 
+BasisTextureLoader.taskCache = new WeakMap();
+
 BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 
 	constructor: BasisTextureLoader,
 	constructor: BasisTextureLoader,
@@ -122,7 +125,17 @@ BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 
 
 		loader.load( url, ( buffer ) => {
 		loader.load( url, ( buffer ) => {
 
 
-			this._createTexture( buffer )
+			// Check for an existing task using this buffer. A transferred buffer cannot be transferred
+			// again from this thread.
+			if ( BasisTextureLoader.taskCache.has( buffer ) ) {
+
+				var cachedTask = BasisTextureLoader.taskCache.get( buffer );
+
+				return cachedTask.promise.then( onLoad ).catch( onError );
+
+			}
+
+			this._createTexture( buffer, url )
 				.then( onLoad )
 				.then( onLoad )
 				.catch( onError );
 				.catch( onError );
 
 
@@ -131,10 +144,11 @@ BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 	},
 	},
 
 
 	/**
 	/**
-	 * @param  {ArrayBuffer} buffer
+	 * @param	{ArrayBuffer} buffer
+	 * @param	{string} url
 	 * @return {Promise<CompressedTexture>}
 	 * @return {Promise<CompressedTexture>}
 	 */
 	 */
-	_createTexture: function ( buffer ) {
+	_createTexture: function ( buffer, url ) {
 
 
 		var worker;
 		var worker;
 		var taskID;
 		var taskID;
@@ -213,6 +227,14 @@ BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 
 
 			} );
 			} );
 
 
+		// Cache the task result.
+		BasisTextureLoader.taskCache.set( buffer, {
+
+			url: url,
+			promise: texturePending
+
+		} );
+
 		return texturePending;
 		return texturePending;
 
 
 	},
 	},
@@ -479,7 +501,7 @@ BasisTextureLoader.BasisWorker = function () {
 		if ( ! width || ! height || ! levels ) {
 		if ( ! width || ! height || ! levels ) {
 
 
 			cleanup();
 			cleanup();
-			throw new Error( 'THREE.BasisTextureLoader:  Invalid .basis file' );
+			throw new Error( 'THREE.BasisTextureLoader:	Invalid .basis file' );
 
 
 		}
 		}