- From: Robert O'Callahan <robert@ocallahan.org>
- Date: Sat, 16 Jul 2011 23:29:31 +1200
- To: Henri Sivonen <hsivonen@iki.fi>
- Cc: Jonas Sicking <jonas@sicking.cc>, Steve Faulkner <faulkner.steve@gmail.com>, HTMLWG WG <public-html@w3.org>, Frank Olivier <Frank.Olivier@microsoft.com>, Richard Schwerdtfeger <schwer@us.ibm.com>, Cynthia Shelly <cyns@microsoft.com>, David Singer <singer@apple.com>, "Tab Atkins Jr." <jackalmage@gmail.com>, "Edward O'Connor" <hober0@gmail.com>, Canvas <public-canvas-api@w3.org>
- Message-ID: <CAOp6jLZG_AHxRazk9irhOjwfK9mWrENvHwsLnpbvkfJoN49DUg@mail.gmail.com>
On Sat, Jul 16, 2011 at 3:11 AM, Henri Sivonen <hsivonen@iki.fi> wrote: > Do you have examples of people choosing <canvas> over SVG for perf > reasons? Are the perf reasons data-based or merely assumed? Are the perf > reasons the kind of quality of implementation issues that can be > considered to be transient and addressed over the next couple of years? > > In theory, SVG should be able to outperform <canvas> for painting, > because the browser engine gets to control how often to repaint, what > parts to repaint and can avoid intermediate bitmaps when the path > stroking and filling can be performed nearer hardware and there are > guaranteed not to be readbacks because the browser knows there aren't > filters in use. > > So in theory, if SVG has performance issues, they should be attributable > to the DOM. If a sub-DOM is used for accessibility in the <canvas> case, > then the <canvas> case has a DOM, too. > heycam and I talked this through over lunch the other day as a thought experiment. Basically, we compared what the browser does with the IE FishTank demo vs what the browser would do with a hypothetical, naturally-written SVG FishTank demo. (Assuming 2000 fish since everyone maxes out at 60fps on 1000 fish on high-end systems these days.) First of all, animating the fishes is a pain in SVG. You either use an SVG element with an animated image, or an SVG element whose image href you change constantly. The former approach is hard because you want to be able to control the animation frame at which each fish starts, and there's no existing API for that. The latter approach would be hard to make fast since conceptually you'd be doing a full image load per fish per frame. In theory we could make it pretty fast, but you'll undoubtedly have more overhead than you do in canvas where you just pick the frame you want (by choosing the right source rectangle of the tiled image) and draw it. The IE FishTank uses tiling; all fish images are stored as subrectangles of a single large image. This actually translates into performance benefits in many cases because repeated drawing from the same source image is more easy to optimize on the GPU (you can just keep appending to a vertex buffer). Explicit tiling with SVG is a bit more clumsy. It would rule out the animated image approach above. You'd probably use a fill pattern (or in the future, media fragments) or possibly a new CSS image value like -moz-image-rect, extended for use as an SVG paint server (also in the future). That would all add overhead. Alternatively, we could try to automatically get the benefit of tiling by cache frequently drawn images into a single source texture. We'll probably need to do that, but it'll be quite complex. Handling transform changes could be an issue. If we unify CSS transforms with SVG transforms then transform changes would require some level of style reresolution, which would be significant overhead. If we don't, it's not so bad, but it still requires DOM manipulation that's heavier-weight than just varying the parameters to a canvas drawImage call. For canvas we improved performance noticeably by optimizing window invalidation. When lots of little things are changing you just want to redraw the whole window once per frame and not bother tracking invalidation. We'd need to extend that optimization to SVG and other DOM changes (doable). Your point about intermediate buffers doesn't really matter too much in IE FishTank, where we're drawing 2000 fish for every buffer draw, and the buffer draw is relatively fast (and pipelined). All that matters is how fast you can draw a given (sub)image with a given transform. We're doing 80,000 drawImages per second in FishTank on Firefox trunk on my laptop, so the overhead of each draw is significant. Even a single QueryInterface or dynamic memory allocation per draw can show up on profiles. Overall I'd say there's a lot we can do to make simple image-blitting workloads (which covers a lot of games for example) much faster in SVG, but I'm very doubtful they'll ever be as fast in SVG as in canvas, especially if the canvas code has been hand-optimized to use explicit tiling. But we can probably make SVG "fast enough" so that most of the things you would use canvas for are fast enough in SVG. Your point about the canvas sub-DOM is relevant. If you require the canvas implementation to be accessible (and I'm not sure what that would mean for FishTank), you'll be adding overhead. How much overhead is unclear. Rob -- "If we claim to be without sin, we deceive ourselves and the truth is not in us. If we confess our sins, he is faithful and just and will forgive us our sins and purify us from all unrighteousness. If we claim we have not sinned, we make him out to be a liar and his word is not in us." [1 John 1:8-10]
Received on Saturday, 16 July 2011 11:30:03 UTC