From 54e12d835812d236ff3b09b592cbf61c894a7d58 Mon Sep 17 00:00:00 2001 From: stepan-beresnev Date: Fri, 10 Oct 2014 16:14:17 +0100 Subject: [PATCH] Fix for Error #3694 thrown, if Texture is created, when context is lost --- .../src/starling/textures/ConcreteTexture.as | 19 +++++++-- starling/src/starling/textures/Texture.as | 42 +++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/starling/src/starling/textures/ConcreteTexture.as b/starling/src/starling/textures/ConcreteTexture.as index b28e022af..5e2eb47c9 100644 --- a/starling/src/starling/textures/ConcreteTexture.as +++ b/starling/src/starling/textures/ConcreteTexture.as @@ -40,6 +40,7 @@ package starling.textures private var mOptimizedForRenderTexture:Boolean; private var mScale:Number; private var mRepeat:Boolean; + private var mUseRectTexture:Boolean; private var mOnRestore:Function; private var mDataUploaded:Boolean; @@ -47,11 +48,16 @@ package starling.textures private static var sOrigin:Point = new Point(); /** Creates a ConcreteTexture object from a TextureBase, storing information about size, - * mip-mapping, and if the channels contain premultiplied alpha values. */ + * mip-mapping, and if the channels contain premultiplied alpha values. + * If Starling.handleLostContext is true and onRestore is set, then base texture will be recreated. + * Its type will be determined by the type of the base parameter + * (either flash.display3D.textures.RectangleTexture or flash.display3D.textures.Texture). + * If the base parameter is null, then the useRectTexture flag determines + * whether to create a RectangleTexture or a Texture instance. */ public function ConcreteTexture(base:TextureBase, format:String, width:int, height:int, mipMapping:Boolean, premultipliedAlpha:Boolean, optimizedForRenderTexture:Boolean=false, - scale:Number=1, repeat:Boolean=false) + scale:Number=1, repeat:Boolean=false, useRectTexture:Boolean=false) { mScale = scale <= 0 ? 1.0 : scale; mBase = base; @@ -62,6 +68,7 @@ package starling.textures mPremultipliedAlpha = premultipliedAlpha; mOptimizedForRenderTexture = optimizedForRenderTexture; mRepeat = repeat; + mUseRectTexture = useRectTexture; mOnRestore = null; mDataUploaded = false; } @@ -89,6 +96,8 @@ package starling.textures * cropped or filled up with transparent pixels */ public function uploadBitmapData(data:BitmapData):void { + if (mBase == null) return; + var potData:BitmapData; if (data.width != mWidth || data.height != mHeight) @@ -149,6 +158,8 @@ package starling.textures */ public function uploadAtfData(data:ByteArray, offset:int=0, async:*=null):void { + if (mBase == null) return; + const eventType:String = "textureReady"; // defined here for backwards compatibility var self:ConcreteTexture = this; @@ -198,7 +209,7 @@ package starling.textures { var context:Context3D = Starling.context; - if (mBase is flash.display3D.textures.Texture) + if (mBase is flash.display3D.textures.Texture || (mBase == null && !mUseRectTexture)) mBase = context.createTexture(mWidth, mHeight, mFormat, mOptimizedForRenderTexture); else // if (mBase is RectangleTexture) @@ -213,6 +224,8 @@ package starling.textures * don't call it from within a render method. */ public function clear(color:uint=0x0, alpha:Number=0.0):void { + if (mBase == null) return; + var context:Context3D = Starling.context; if (context == null) throw new MissingContextError(); diff --git a/starling/src/starling/textures/Texture.as b/starling/src/starling/textures/Texture.as index c131e7f20..4e44f541a 100644 --- a/starling/src/starling/textures/Texture.as +++ b/starling/src/starling/textures/Texture.as @@ -276,17 +276,31 @@ package starling.textures if (context == null) throw new MissingContextError(); var atfData:AtfData = new AtfData(data); - var nativeTexture:flash.display3D.textures.Texture = context.createTexture( - atfData.width, atfData.height, atfData.format, false); + var nativeTexture:flash.display3D.textures.Texture = Starling.current.contextValid ? + context.createTexture(atfData.width, atfData.height, atfData.format, false) : null; var concreteTexture:ConcreteTexture = new ConcreteTexture(nativeTexture, atfData.format, atfData.width, atfData.height, useMipMaps && atfData.numTextures > 1, false, false, scale, repeat); - concreteTexture.uploadAtfData(data, 0, async); - concreteTexture.onRestore = function():void + if (nativeTexture == null) { - concreteTexture.uploadAtfData(data, 0); - }; + concreteTexture.onRestore = function():void + { + concreteTexture.uploadAtfData(data, 0, async); + concreteTexture.onRestore = function():void + { + concreteTexture.uploadAtfData(data, 0); + }; + }; + } + else + { + concreteTexture.uploadAtfData(data, 0, async); + concreteTexture.onRestore = function():void + { + concreteTexture.uploadAtfData(data, 0); + }; + } return concreteTexture; } @@ -356,23 +370,25 @@ package starling.textures actualWidth = Math.ceil(origWidth - 0.000000001); // avoid floating point errors actualHeight = Math.ceil(origHeight - 0.000000001); - // Rectangle Textures are supported beginning with AIR 3.8. By calling the new - // methods only through those lookups, we stay compatible with older SDKs. - nativeTexture = context["createRectangleTexture"]( - actualWidth, actualHeight, format, optimizeForRenderToTexture); + if (Starling.current.contextValid) + // Rectangle Textures are supported beginning with AIR 3.8. By calling the new + // methods only through those lookups, we stay compatible with older SDKs. + nativeTexture = context["createRectangleTexture"]( + actualWidth, actualHeight, format, optimizeForRenderToTexture); } else { actualWidth = getNextPowerOfTwo(origWidth); actualHeight = getNextPowerOfTwo(origHeight); - nativeTexture = context.createTexture(actualWidth, actualHeight, format, - optimizeForRenderToTexture); + if (Starling.current.contextValid) + nativeTexture = context.createTexture(actualWidth, actualHeight, format, + optimizeForRenderToTexture); } var concreteTexture:ConcreteTexture = new ConcreteTexture(nativeTexture, format, actualWidth, actualHeight, mipMapping, premultipliedAlpha, - optimizeForRenderToTexture, scale, repeat); + optimizeForRenderToTexture, scale, repeat, useRectTexture); concreteTexture.onRestore = concreteTexture.clear;