1
\$\begingroup\$

My current solution is to clear the entire canvas and redraw all sprites on every requestFrame(). This works but feels inefficient:

  1. I only need to clear the part of the canvas made invalid by animations.
  2. I only need to redraw objects that intersect the invalid part of the canvas.

I can track invalidated sections, and during requestFrame() I can find out which objects intersect an invalid section and redraw only them, but I'm not sure if that's an improvement or a step back. If I have 100 sprites and 10 of them are moving, that means I need to do 10 searches through all 100 sprites. Tall order for every request frame.

I can also put every sprite on its own canvas and remove sprite interaction from the equation, but I haven't been able to find insight into how many canvases is too many.

This seems like a problem that's been solved already, but I haven't found any resources on the topic.

\$\endgroup\$
4
  • \$\begingroup\$ These kinds of algorithms were common back in prehistoric java mobile games, you might have some luck finding resources how they were done. \$\endgroup\$
    – wondra
    Feb 28, 2016 at 1:00
  • 1
    \$\begingroup\$ The technique you're asking about is called "dirty rectangles". I haven't implemented this but this SO link is one place to start: stackoverflow.com/questions/76651/dirty-rectangles \$\endgroup\$ Feb 28, 2016 at 6:13
  • \$\begingroup\$ Thanks, @NoobsArePeople2. Knowing the name of what I was describing will help me continue my research. \$\endgroup\$
    – Mark
    Feb 28, 2016 at 13:23
  • \$\begingroup\$ I made some benchmarking tests in Firefox once, and noticed that calling drawImage outside of the canvas bounds is extremely fast. So it's not that much of a problem unless you have a really large amounts of sprites so that the function call overhead alone eats too many CPU cycles. I didn't test it in all major rendering engines, though. \$\endgroup\$
    – Philipp
    Mar 1, 2016 at 18:26

1 Answer 1

3
\$\begingroup\$

The first thing you should do is figure out if you actually have a problem.

Is the way you're clearing the canvas now slow? Are you dropping frames because of how you clear the canvas? Regardless of how it looks (for now), remove the call that clears the canvas and measure again. Are your paint cycles a lot faster now?

Basically, I wouldn't worry about this until you know it is a problem. The technique you're looking for is dirty rectangle updating, but it is computationally more expensive and until you know what it saves you it's hard to make the proper engineering decision here.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ True that : measure first. Moreover : 1) Javascript's overhead is especially high (vs the same draw load in C++ for instance) and 2) both context2D and webGL are using the GPU to draw, so good luck beating a GPU with a dirty rect algorithm made in JS. \$\endgroup\$ Mar 1, 2016 at 20:57
  • \$\begingroup\$ That makes sense, d-hayes. I was thinking this was a problem with a common one-size-fits-all solution, but it sounds like it can go either way. Your advice makes good sense. \$\endgroup\$
    – Mark
    Mar 1, 2016 at 23:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .