Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suboptimal SpriteSheet code #15

Open
download13 opened this issue Nov 7, 2011 · 3 comments
Open

Suboptimal SpriteSheet code #15

download13 opened this issue Nov 7, 2011 · 3 comments

Comments

@download13
Copy link

I was looking through the Jaws code to see how it worked when I noticed that you store sprites as canvas elements.

Curious, I wrote a quick test to see what sort of performance each type of drawImage will get, and here are the results. As you can see, canvas is by far the worst performer. The BlobURL method seem to work very well in Chrome, but createObjectURL isn't compatible with all browsers.

If compatibility doesn't matter as much as speed, you might want to switch to using createObjectURL. Otherwise, data: URLs are still looking good.

After that, I thought it might be good to look into the performance difference of pre-cutting spritesheets as opposed to just leaving them one image and using drawImage(Object image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh) to pick out pieces of them at blit-time. Here's that test which seems to indicate that it doesn't matter which you use. Since both are the same speed, I would go with the dynamic lift as it doesn't take up extra memory for all the individual sprites, it only needs a reference to the existing spritesheet image asset.

@ippa
Copy link
Owner

ippa commented Nov 9, 2011

Hey .. thanks for taking the time to give feedback, fix benchmarks and so on.

Regarding compability, I can't ignore IE9 as of now.

Regarding your first benchmark, canvas image wins for my current browser, chrome 15. But I can see it kind of sucks in chrome 16 and FF. Right now I convert all images to canvas as a designchoice cause chrome has always given me better performence like that... but it looks like that will change with chrome 16. I'll keep an eye on it to see if a change in jaws is warranted.

I guess it would be possible to browsersniff and use different methods depending on the browser to get ultimate performence. It would add complexity though.. and I wan't to wait with that until I release "1.0" with a settled API.

The spritesheet idea is intersting.. I think it would take some refactoring of various constructors, Sprite(), Animation(), SpriteSheet(). The functionallity of a standalone SpriteSheet()-constructor might become obsolete.

Except for eating less memory, there's another benefit. It would make Canvas and HTML animations more simular. Cause HTML animations are done with CSS background-offsets (currenty not supported by jaws) which is simular to how you suggest canvas-animations/spritesheets should work.

If this is something you would be interesting hacking on I would most likely accept a patch right away. I'm ippa @ freenode ircnetwork if you wanna chat about it.

@download13
Copy link
Author

I don't think it's something that I can do without making drastic changes to the API, so it really comes down to whether you like backwards compatibility. Some users might rely on getting a canvas back from functions that later return an image.

Plus, there's the need to completely refactor the way that animations are drawn. An update would just update the frame index while the draw function would need the current canvas or viewport passed as an argument so that it could draw directly from the CSS-style spritesheet to the canvas.

In my library the drawing system works by calling a static draw function on the main object and passing it an array of all sprites and animations to be drawn. That way there is very little getting between the spritesheet image and the drawImage that will be required to blit from it. It's easier there because it's a new library (I started it a few days ago, haven't even pushed yet) and no one is depending on it having a stable API.

PS: I've sent a pull request for something a little more immediately practical. Some simple modifications that make loops and float-to-int conversion faster. They're easy to implement, it's just a little mind-numbing to have to wade through all the code making the changes.

PPS: Something else to remember for performance purposes. Function calls in JS are very expensive and slow. Try to minimize the number of function calls you make during loops. That's why I use the static draw with an array of drawables passed to it. It's only one function call in total instead of one for each item to draw.

@izb
Copy link

izb commented Jun 3, 2013

I stumbled across this issue and the performance boost with createObjectURL seems a little hard to believe. It seems that this jsperf page has been looked at before in stackoverflow:

http://stackoverflow.com/questions/13328184/explain-massive-performance-difference-in-html-canvas-image-drawing

This seems to suggest that the performance boost is actually due to the test throwing errors in chrome rather than actually painting the image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants