I understand it's often faster to pre-render graphics to an off-screen canvas. Is this the case for a shape as simple as a circle? Would it make a significant difference for rendering 100 circles at a game-like framerate? 50 circles? 25?
To break this into two slightly different problems, there are two aspects to what you're asking:
1) is drawing a shape off-screen and putting it on-screen faster
2) is drawing a shape one time and copying it to 100 different places faster than drawing a shape 100 times
The answer to the first one is "it depends".
That's a technique known as "buffering" and it's not really about speed.
The goal of buffering an image is to remove jerkiness from it.
If you drew everything on-screen, then as you loop through all of your objects and draw them, they're updating in real-time.
In the NES-days, that was normal, because there wasn't much room in memory, or much power to do anything about it, and because programmers didn't know much better, with the limited instructions they had to work with.
But that's not really the way games do things, these days.
Typically, they call all of the draw updates for one frame, then they take that whole frame as a finished image, and paste that whole thing on the screen.
The GPU (and GL/DirectX) takes care of this, by default, in a process called "double-buffering".
It's a double-buffer, because there's room for the "in-progress" buffer used for the updates, as well as the buffer that holds the final image from the last frame, that's being read by the monitor.
At the end of the frame processing, the buffers will "swap". The newly full frame will be sent to the monitor and the old frame will be overwritten with the new image data from the other draw calls.
Now, in HTML5, there isn't really access to the frame-buffer, so we do it ourselves; make every draw call to an offscreen canvas. When all of the updates are finished (the image is stable), then copy and paste that whole image to the onscreen canvas.
There is a large speed-optimization in here, called "blitting", which basically copies over only the parts that have changed, and reuses the old image.
There's a lot more to it than that, and there are a lot of caveats, these days, because of all of the special-effects we add, but there it is.
The second part of your question has to do with a concept called "instancing".
Instancing is similar to blitting, but while blitting is about only redrawing what's changed, instancing is about drawing the exact same thing several times in different places.
Say you're painting a forest in Photoshop.
You've got two options:
Draw every tree from scratch.
Draw one tree, copy it, paste it all over the image.
The downside of the second one is that each "instance" of the image looks exactly the same.
If your "template" image changes colour or takes damage, then all instances of the image do, too.
Also, if you had 87 different tree variations for an 8000 tree forest, making instances of them all would still be very fast, but it would take more memory, because you now need to save 87x more images than when it was just one tree, to reference on every draw call.
The upside is that it's still much, much faster.
To answer your specific question about X circles, versus instancing 1 circle:
Yes, it's still going to be a lot faster.
What a "lot" means, though, will change based on a lot of different things, because now you're talking about browsers on PCs.
How strong is the PC?
How good is the videocard?
How large is the canvas in software-pixels (not CSS pixels)?
How large are the circles? Do they have alpha-blending?
Is this written in WebGL or software?
If software is the canvas compositing in hardware mode?
For a typical PC, you should still be able to hit 60fps in Chrome, drawing 20 circles, I think (depending on what you're doing to them... ...just drawing them onscreen, every frame is simple), so in this case, the instances are still a "lot" faster, but it's not going to matter, because you've already passed the performance-ceiling of Canvas.
I don't know that the same would be true on phones/tablets, or battery-powered laptops/netbooks, though.
Yes, transferring from an offscreen canvas is faster than even primitive drawings like an arc-circle.
That's because the GPU just copies the pixels from the offscreen canvas (not much CPU effort required)
I am working on a game that uses HTML5 canvas 2D context drawing on a Chromecast device (which doesn't have hardware acceleration). I've noticed that drawing two objects in one frame will trigger a repaint of the entire region that contains both of them. As a "worst-case", imagine that I want to only change the color of the top-left and bottom-right pixels of a large canvas element. If I use two one-pixel fillRect calls to do this, it (WebKit/Blink, at least) will mark the entire canvas dirty, triggering a very expensive paint operation. I believe this should link to the code that performs this logic in Chromium:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp&l=218
Is there any way to convince the browser to actually perform two small paint operations instead of one (excessively) large one? Or would this always be slower, despite the fact that it's re-drawing significantly less? I have tried putting the elements on different canvas elements layered on top of each other, but the browser still seems to catch it and batch them together (at least as shown by the repaint regions in DevTools).
As far as I know, currently you can't do much better than that; one main drawback is that double buffering is not implemented either, which would have improved the performance. We will be seeing improvements in these areas moving forward.
I was wondering if anybody knows what does the grey color stands for in the Frame Timeline panel in Scout.
It is explained what are: blue, green, yellow and orange colors, but I can't find what does the grey is for? Other, non-flashplayer events? It is almost always higher than any other columns and often higher than my FPS limit so I was wondering if it is something that slows down my apps performance and if I can affect it.
Usually, it represents 'inactive' times between AVM's next time slice is processed. mostly consists of waiting GPU for rendering (only in rendermode=gpu or rendermode=direct) after uploading all data to GPU, or simply waiting for next frame, etc.
With proper load balance, the grey portion of frame time won't hurt your app's performance.
I'm working on a kind of 2d platform ARPG in Flashpunk, and have run into somewhat of a conundrum.
Ranged weapons are no big deal. They are a flat image that I move and rotate to emulate the feel of throwing or firing a ranged weapon. Melee weapons are a bit more of a pain, as I want to use a sprite map for different weapon animations.
The problem I run into is that I have to manually adjust the hitbox for every frame of the melee weapon. I would like to use the Pixelmask function included with Flashpunk, but it does not seem to work with Spritemap. Is there a way to force it to work, or a way to convert the current frame of the Spritemap into an Image so I can apply a Pixelmask?
It's a bit hacky, but what you could do is create a Vector of images separate from the animation itself, with indices equal to that of the corresponding animation, and create the pixelmask from there. If that ends up being too slow (dynamically allocated memory being slower than reusing preallocated), you could load the images, create pixelmasks from them, and push the pixelmasks to a vector instead. From there, all you would need to do is switch to the correct pixelmask during the attack animation.
I have many small, identical vector circles that move around the screen, but only appear for a defined period in defined areas. Currently, these circles are children of whatever parent object produces them, and each is given its own interframe handler for animation (move a few pixels, maybe change alpha). With hundreds on screen, this gets somewhat slow.
Would it be advisable to cache the circles as bitmaps? Would it be better to add them all to one array and have one interframe event handler run through the whole shebang, even if up to 90% aren't being animated in a specific frame?
Would it be faster to cache one circle as a bitmap and set all others to use the first shape's bitmapdata? Would it be even better to use a "CopyPixel" approach to erase and redraw ("blit") every circle at its new position every frame? I hear conflicting reports of the usefulness of CopyPixel on large mobile device canvases...
If the animation can be looped make a movie from the movie else try everything you can. Usually a CopyPixel approach is faster but I wouldn't expect much. I don't think it pays the bill either hence reduce the numbers of circles.