Speedup code. Draw and copyPixel alternatives.

Subscribe to Speedup code. Draw and copyPixel alternatives. 20 posts

avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Hi guys I am new here. I had a small doubt regarding something, my mentor is busy so he asked me to come here and ask the doubt. Please dont kill me if I do something wrong.

Okay so the thing is I searched today for trails behind objects. I was surprised to find that it was really easy. I dont understand it fully, just that a bitmapdata is being projected from the movieclip onto _container which is a bitmap and blur reduces the intensity after a while. Here is the code which does it all:-

//init

private var _container:Bitmap;
private var _containerData:BitmapData;
private var _colorMatrixFilter:ColorMatrixFilter;

_containerData = new BitmapData(550, 400, true, 0);
container = new Bitmap(containerData);
_colorMatrixFilter = new ColorMatrixFilter([ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.99, 0 ]);

addChild(_container);

var tempBmd:BitmapData;

//update in enter frame
for (var jj:int = 0; jj < bulletArr.length; jj++)
{
tempBmd = new BitmapData(6, 6);
tempBmd.draw(bulletArr[jj].getChildAt(0));
_containerData.copyPixels(tempBmd, tempBmd.rect, new Point(bulletArr[jj].x-3, bulletArr[jj].y-3));
Bullet(bulletArr[jj]).moveAndTest();
}

containerData.applyFilter(containerData, _containerData.rect, new Point(0, 0), new BlurFilter(5, 5, 2));
containerData.applyFilter(containerData, _containerData.rect, new Point(0, 0), _colorMatrixFilter);

The original code at activetutplus did it without draw function as they were using bitmaps directly. I am using movieclips. Am I doing it the right way? The game lags for a short while every so often after I wrote this piece of code. Is there any faster way.

 
avatar for Danishdragon Danishdragon 367 posts
Flag Post

Hey, and welcome to the forum. When posting code, you should follow this guide . It makes it so much easier to read the code :)

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post
//init

private var _container:Bitmap;
private var _containerData:BitmapData;
private var _colorMatrixFilter:ColorMatrixFilter;

_containerData = new BitmapData(550, 400, true, 0);
_container = new Bitmap(_containerData);
_colorMatrixFilter = new ColorMatrixFilter([ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.99, 0 ]);
			
addChild(_container);

var tempBmd:BitmapData;

//update in enter frame
for (var jj:int = 0; jj < bulletArr.length; jj++)
{
	tempBmd = new BitmapData(6, 6);
	tempBmd.draw(bulletArr[jj].getChildAt(0));
	_containerData.copyPixels(tempBmd, tempBmd.rect, new Point(bulletArr[jj].x-3, bulletArr[jj].y-3));
	Bullet(bulletArr[jj]).moveAndTest();
}
					
_containerData.applyFilter(_containerData, _containerData.rect, new Point(0, 0), new BlurFilter(5, 5, 2));
_containerData.applyFilter(_containerData, _containerData.rect, new Point(0, 0), _colorMatrixFilter);
 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

hmm I can read both code without any problem. The above one has some _ missing thats all. :)

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

And thanks for welcome. I hope I will be useful to someone here too. :)

 
avatar for Amibtious Amibtious 377 posts
Flag Post

When you say it lags ‘every so often’, is it a regular pattern? Can ya check taskmanager performance graph to see how long between each spike?

edit:also in many of your posts you talk about movieclips, you should look into the Sprite classs….often it’s a suitable less resource intensive alternative.

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

I do have SwfProfiler.. I have tested extensively for the cause but cant pin point. The lag appears every 10 sec or so and is more like a 40-80ms delay in operations which are run every frame. so the current fps drops to like 28 or so every 10 sec but otherwise stays at 30 fps constant.

 
avatar for Amibtious Amibtious 377 posts
Flag Post

I had a similar problem….suspected something to do with garbage collector & blur filters, was never exactly clear what caused it or why my ‘fix’ fixed it….I’ll try to find the thread, you might be able to see a similar bodge-fix.

Here it is:
www.kongregate.com/forums/4-game-programming/topics/244700-fixed-but-not-understood-blur-filter-cacheasbitmap-causing-cpu-spikes-every-10-seconds

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Thanks for the link. Err I am not sure what “fix” you talked about in that thread. I read through twice but didnt see any solution. Can you please explain?

 
avatar for Amibtious Amibtious 377 posts
Flag Post

Not really a solution, but I found that applying the filter to a bitmap, creating a new bitmapdata, drawing the the 1st now filtered bitmap to the new bitmapdata, and then having a new bitmap use the new bitmapdata, and adding the new bitmap to the game rather than the original bitmap the filter was applied to…..would prevent the lag occuring.

It’s a bit dodgy, but it worked…your situation is somewhat different though.

Here:

var bdata:BitmapData = new BitmapData(2000, 2000, true, 0xFFFFFF);
var bdatadub:BitmapData = new BitmapData(2000, 2000, true, 0xFFFFFF);
var bdatab:Bitmap = new Bitmap(bdata);
var bdatabdub:Bitmap = new Bitmap(bdatadub);

...

bdatab.filters = [iceblur];
bdatadub.draw(bdatab);
addChild(bdatabdub);

The problem occured when I added bdatab, making the double ‘dub’ bitmap&bitmapdata and adding that instead fixed it.

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Thanks for the explanation. I really appreciate it.

Haha in my opinion that code should have caused a bit more lag. creating 2000×2000 bitmapdata twice. but I am new to this so I dunno.

In the other thread it was mentioned that it might be garbage collector.

Oh shit. I am sorry but my problem seems to have fixed. I was previously testing in the flash IDE. In there the game was using around 26-30Megs. I just tested in standalone. The game hardly uses 6Megs and runs smoothly through out. Maybe fall down to 29.870FPS occasionally but mostly stays on 30FPS.

Lesson learnt never test in flash IDE itself.

 
avatar for Amibtious Amibtious 377 posts
Flag Post

The debug player is a lot slower because it’s checking your code while it runs it, the lag is probably still there in release version, just much reduced. I try to make my stuff run fine even in debug player to account for some players having slower computers than me.

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Oh. so I am back to square one. And I dont even know how to make the above code faster… sigh

 
avatar for UnknownGuardian UnknownGuardian 8143 posts
Flag Post

Derp.

Many draws and many copy pixels? Something must be wrong. AND 2 filters. That’s kinda alot of stuff to do…

 
avatar for JWBSoftware JWBSoftware 106 posts
Flag Post

Filters are slow. I’ve found if you are doing them continuously you should find a way to minimise the area affected or to frame-span the effect, i.e. do it only every other frame (maybe alternate them).

Do you really need a ColorMatrixFilter? For that particular filter a ColorTransform, applied using the BitmapData’s colorTransform function, would I think look identical and much quicker. A ColorMatrix is overkill.

Another thing is you’ve a lot of calls to new to create new objects in your update loop. You don’t need any. You can e.g. create tempBmd once and call fillRect to empty it for re-use. your Point(0, 0) can be created once at startup and used wherever it’s needed, as can the BlurFilter. _containerData.rect and tempBmd.rect can also be got once and stored.

Finally dereference bulletArr[jj] for a minor speedup; i.e. do bullet = bulletArr[jj] and then use bullet in place of bulletArr[jj]. bulletArr[jj] is actually a function call and you should not call a function repeatedly to get the same result if you can get away with doing so once.

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Awesome post JWBSoftware. Puts me in right direction. I will implement all the stuff you have mentioned. Now I am thinking why the hell didnt I make that new Point(0,0) global previously. Thanks for pointing that out. Omigosh I didnt knew bulletArr[jj] is a function call, I thought it was just a reference. :) Can you please elaborate on ColorTranform which should be used instead of ColorMatrix. Thanks.

UnknownGuardian: Err, I get the drift that you want me to remove all that. What else can I do instead?

 
avatar for JWBSoftware JWBSoftware 106 posts
Flag Post

It looks like your ColorMatrixFilter is just doing a 0.99 fade, i.e. it’s multiplying the alpha channel by 0.99. The following ColorTransform should do the same

ct = new ColorTransform();
ct.alphaMultiplier = 0.99;

ColorMatrixFilter is only needed for transformations between channels, for e.g. recolouring art. But you aren’t doing that, that I can see.

 
avatar for ErlendHL ErlendHL 1313 posts
Flag Post

See if you can cache any of the things being drawn. Do the elements in bulletArr look all the same? Then you can cache it to a temporary BitmapData before looping, or eventually cache it when the program starts, and copyPixels to _containerData.
Also, I see you are drawing, then copyPixeling, to set coordinates. Instead, use a Matrix, like this:

var m:Matrix = new Matrix();
m.translate(xPosition, yPosition);
_containerData.draw(bulletArr[jj].getChildAt(0), m);

Passing the matrix as the second argument of draw.

But if you cache it first (if the graphics of the elements in bulletArr are the same), which is much more efficient, of course you would not use a matrix because you would cache it by drawing it to a temprary bitmapdata ouside the loop anyway, then do exactly what you do in line 3 inside the loop (_containerData.copyPixels....).

Edit: might not solve the lagspikes every 10 seconds but improves overall performance.

 
avatar for LearningAS3 LearningAS3 83 posts
Flag Post

Thanks to you both. I am fixing these things currently.

 
avatar for Draco18s Draco18s 6860 posts
Flag Post

You’d also be better off blurring your cached bitmap, and then drawing that in the right place instead of post-computing the blur.

The draw actions will be a little slower, but it’d still be faster than blurring a million pixels.