AS3的Stage3D存在设备丢失的问题;会带来的问题就是,已经上传到显存的所有数据丢失,当遇到该问题后唯一的解决方法就是在设备丢失后重新上传一次数据;
Starling提供了一个静态属性handleLostContext,设置为true则会自动处理设备丢失的问题;那么Starling会如何进行处理呢?
我们可以看看Texture类,其提供的4个静态方法用来创建Texture,分别为fromBitmap、fromBitmapData、fromAtfData和fromColor,其中可以找到的逻辑就是,如果handleLostContext为true,则ConcreteTexture对象会记录对应的BitmapData或ATFData的数据,并侦听Event.CONTEXT3D_CREATE事件,在下一次Event.CONTEXT3D_CREATE事件中重新上传数据到显存,处理了设备丢失问题。
Texture类:
1 public static function fromAtfData(data:ByteArray, scale:Number=1, useMipMaps:Boolean=true, 2 loadAsync:Function=null):Texture 3 { 4 const eventType:String = "textureReady"; // defined here for backwards compatibility 5 6 var context:Context3D = Starling.context; 7 if (context == null) throw new MissingContextError(); 8 9 var async:Boolean = loadAsync != null; 10 var atfData:AtfData = new AtfData(data); 11 var nativeTexture:flash.display3D.textures.Texture = context.createTexture( 12 atfData.width, atfData.height, atfData.format, false); 13 14 uploadAtfData(nativeTexture, data, 0, async); 15 16 var concreteTexture:ConcreteTexture = new ConcreteTexture(nativeTexture, atfData.format, 17 atfData.width, atfData.height, useMipMaps && atfData.numTextures > 1, 18 false, false, scale); 19 20 if (Starling.handleLostContext) 21 concreteTexture.restoreOnLostContext(atfData); 22 23 if (async) 24 nativeTexture.addEventListener(eventType, onTextureReady); 25 26 return concreteTexture; 27 28 function onTextureReady(event:Event):void 29 { 30 nativeTexture.removeEventListener(eventType, onTextureReady); 31 if (loadAsync.length == 1) loadAsync(concreteTexture); 32 else loadAsync(); 33 } 34 }
ConcreteTexture类:
1 public function restoreOnLostContext(data:Object):void 2 { 3 if (mData == null && data != null) 4 Starling.current.addEventListener(Event.CONTEXT3D_CREATE, onContextCreated); 5 else if (data == null) 6 Starling.current.removeEventListener(Event.CONTEXT3D_CREATE, onContextCreated); 7 8 mData = data; 9 } 10 11 private function onContextCreated(event:Event):void 12 { 13 var context:Context3D = Starling.context; 14 var bitmapData:BitmapData = mData as BitmapData; 15 var atfData:AtfData = mData as AtfData; 16 var nativeTexture:flash.display3D.textures.Texture; 17 18 if (bitmapData) 19 { 20 nativeTexture = context.createTexture(mWidth, mHeight, 21 Context3DTextureFormat.BGRA, mOptimizedForRenderTexture); 22 Texture.uploadBitmapData(nativeTexture, bitmapData, mMipMapping); 23 } 24 else if (atfData) 25 { 26 nativeTexture = context.createTexture(atfData.width, atfData.height, atfData.format, 27 mOptimizedForRenderTexture); 28 Texture.uploadAtfData(nativeTexture, atfData.data); 29 } 30 31 mBase = nativeTexture; 32 }
基于上面源码实现的功能来看,在handleLostContext为true时,我们是不能对BitmapData和ATFData调用dispose方法,但是可以置空,该对象已被ConcreteTexture对象引用,所以不会被垃圾回收。
对于不会出现3D设备丢失的设备,如IOS上,handleLostContext可设为false,同时在数据上传到显存后可销毁数据,释放内存;但是其它设备由于可能会出现3D设备丢失的情况,所以内存中应保有数据的信息,在设备丢失后可以重新上传,否则将会出现问题。