I need to move from original idea to put some heavy BitmapData manipulation and upload to GPU in BackWorker and draw in MainWorker, cos didn't found way to share context or native texture thru AMF channel, so I let just original regeneration of displayBitmapData on the BackWorker. Now problem was how to pass BitmapData to AMF. AMF require classes to have constructors with default values and to implement IExternalizable interface in order to handle complex data types. BitmapData Class doesn't comply to both and solution is to transfer from back to main by use of ByteArray.
If you plan to use with Texture.uploadFromBitmapData you need to encode (JPG,PNG...) in order that Loader.loadBytes to be able to load bytes from ByteArray and recreate BitmapData. Also good cos less bytes would go over the channel.
I was stubborn and wanted to use uploadFromByteArray.
I saw some guy was talking on Starling forums about Texture.uploadFromByteArray but found out that even in Starling 1.2 isn't supported. So I added this function to Texture.as to fill that gap.
/** Creates a texture from Byte array.
* */
public static function fromByteArray(data:ByteArray,width:int,height:int, byteArrayOffset:uint,miplevel:uint=0,
optimizeForRenderTexture:Boolean=false,
scale:Number=1):starling.textures.Texture
{
var origWidth:int = width;
var origHeight:int = height;
var legalWidth:int = getNextPowerOfTwo(width);
var legalHeight:int = getNextPowerOfTwo(height);
var context:Context3D = Starling.context;
if (context == null) throw new MissingContextError();
var nativeTexture:flash.display3D.textures.Texture = context.createTexture(
legalWidth, legalHeight, Context3DTextureFormat.BGRA, optimizeForRenderTexture);
nativeTexture.uploadFromByteArray(data,byteArrayOffset,miplevel);
var concreteTexture:ConcreteTexture = new ConcreteTexture(
nativeTexture, legalWidth, legalHeight, false, true,
optimizeForRenderTexture, scale);
if (Starling.handleLostContext)
concreteTexture.restoreOnLostContext(data);
if (origWidth == legalWidth && origHeight == legalHeight)
return concreteTexture;
else
return new SubTexture(concreteTexture,
new Rectangle(0, 0, origWidth/scale, origHeight/scale),
true);
}
While creating native texture in the code, you can see that format Context3DTextureFormat.BGRA and BitmapData is ARGB, so it need conversion before placing into ByteArray
for ( var j : int = 0 ; j < displayBitmapData.height; j ++ ) {
for ( var i : int = 0 ; i < displayBitmapData.width; i ++ ) {
//memory is ByteArray
memory.writeUnsignedInt((displayBitmapData.getPixel32(i,j) & 0x000000ff) << 16 | (displayBitmapData.getPixel32(i,j) & 0x0000FF00) | (displayBitmapData.getPixel32(i,j) & 0x00FF0000) >> 16);
}
You need also to watch that your BitmapData is size of power of 2.
Download: source
The example http://www.winx.ws/blog/bin/BitmapUploadWorkers.html shows nothing ...
ReplyDeleteBe sure you are using Flash Player 11.4.
ReplyDeleteYou will see the page. Still having issue for online setup of worker but you have source so you can run it at home :)
Hi, tried your sample wit flash player 11,4,402,287, standalone or plugin version, and the worker scene is always empty...
ReplyDeleteIt's the only attempt to run part of starling in a worker I've found so far..
Have you checked if the Worker class gets into context lost situation? I'm having same trouble also in Worker class and have no idea how this would get restored. I'm stuck.
ReplyDelete