(Please note that this article discusses the current trunk of QtWebKit, so some parts are not relevant for Qt 4.7.x)
Quick introduction
<canvas> is a new feature in HTML5 – a block element with an imperative painting API. It’s (somewhat hyperbolically) being hailed as a “Flash killer.” You can use it to create graphically rich web pages and new technology demos are popping up daily. The feature originates from WebKit, developed initially for Mac OS X’s Dashboard. Naturally QtWebKit supports it as well.
Compliance
Spec compliance is high – we’re passing over 90% of Philip Taylor’s test suite, and there are patches in the pipeline for many of the remaining failures. Furthermore, some of the tests have become invalid after changes to the spec. Most of the known misrenderings have been corrected and we’re approaching a pixel perfect match with Chromium and Safari.
The big exception is radial gradients; HTML5 defines its radial gradients based on the original CoreGraphics implementation which differs from the standard SVG gradients (which is what QRadialGradient implements.) I’ve tried convincing the WHATWG to adopt SVG-style gradients for canvas, but they felt it was too late in the game for such a change. Fortunately I have yet to see someone exploiting the additional possibilities of CoreGraphics-style gradients “in the wild.”
We recently got support for blurred shadows, thanks to Ariya Hidayat. This was the last big missing feature in our implementation.
Performance
Performance has been steadily improving since the release of Qt 4.6 and in Qt 4.7 you’ll see large speedups thanks to Benjamin Poulain’s efforts in vectorizing QPainter’s blending code. We’re still not where Skia (Chromium’s toolkit) is when blending scaled and/or transformed pixmaps, but Olivier Goffart is working on this right now and preliminary numbers are looking good.
Since there is no native “Color” object, stroke and fill colors are managed using CSS strings. Previously this would go through the (lex) generated CSS parser which is very slow. I recently landed an optimized “rgba()” color parser that helps boost any application that paints with many different colors.
Pixel manipulation speed is acceptable, though we’re not at our limits yet. Mostly because we’re forced to do RGB/BGR conversion on the fly in putImageData() and getImageData(). This could be alleviated by adding QImage::Format_ABGR32_Premultiplied but I feel this would be overkill right now. More realistically we could at least vectorize the format conversion inside WebKit.
Our biggest weakness is path stroking – Qt’s path stroker and rasterizer is slow compared to other toolkits. Some people from Google are working on GPU-accelerated paths and we’re watching this with great interest.
The second biggest weakness is gradient rendering. Qt caches the data for up to 60 gradients but it’s very common for canvas applications to use many more unique gradients which turns the caching mechanism into pure overhead. Optimization (and vectorization) of these operations is in the research queue.
Future work
Google engineers are working on a hardware accelerated canvas implementation for WebKit. Hopefully we’ll be able to take advantage of this work on platforms where it makes sense.
More immediately, we’re looking into optimizing our bilinear filtering code which currently sticks out in many performance profiles.
Demos!
All right, enough talk. Here are some of my favorite <canvas> demos for your viewing/poking pleasure:
* Parcycle
* Interferoplasma
* Monster
* Trail
* Canvas Cycle
Tons of more demos at canvasdemos.com
Possibly related posts:


18 comments
Good work! Can you tell us how QtWebKit’s release cycle will look like after QtWebKit 2.0 / Qt 4.7?
“Our biggest weakness is path stroking – Qt’s path stroker and rasterizer is slow compared to other toolkits.”
How come?
@Markus S: Thanks! I’m gonna let our WebKit PM (Henry Haverinen) answer your question.
Personally I hope for much more frequent releases after Qt 4.7 is out. It’s kind of a bummer seeing QtWebKit fly on my desktop every day while knowing “regular” Qt users won’t enjoy it for many more months.
@sas: Simply because no focused optimization effort has been made in that area yet. Rest assured though, we’ve got enough obsessive engineers around here that it won’t be an issue forever.
Very nice
Canvas is very cool!!!
WebGl will be supported by QtWebKit ??
Like i think these api are very good to be use in JS code,
i’ve begin (2-3 days) a plugin to porte canvas (use Context2D example) api and WebGl api to qml. If you want look video :
http://www.developpez.net/forums/d906429-2/c-cpp/bibliotheques/qt/qextend-sortie-v0-0-1-a/#post5459238
I’d like to add that I would also really like to see official QtWebKit binaries released more frequently. Perhaps updated QtWebKit modules could be shipped as a drop-in replacement for the one shipping with the Qt 4.7 SDK.
@Yan
We have some code for WebGL but it is not supported at the moment (see http://trac.webkit.org/wiki/QtWebKitWebGL ).
I think QML is a flash killer…
Sorry, just a quick optimization: in qmatrix4x4. at line 535 (inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2) )
if you replace the unrolled loop with this (or with the unrolled version)
for (i = 0; i
Is QtWebKit competitive in both rasterization speed and footprint? Seems QtGUI is a huge dead-weight around QtWebKit’s neck with lots of redundant and deadcode rasterization paths between software, OpenGL, OpenGLES without a clear “chassis” model; aka bloat. Can QtWebkit target 10MB ram footprint (as in a straight port of Webkit) or has to suck up the extra 10MB (20MB+ total) that the rest of Qt adds? That spells instant-death of QtWebkit viability in widespread embedded deployment.
For QtWebKit to succeed in competition against other native and focused Webkit implementations, sounds like could Qt almost needs a ground-up rewrite in order to clean the rasterization pipes.
Is this work being done through optimizations for the N900 and N9, or it falls on OEM implementators to figure this out themselves?
@NuShrike
This is out of scope for this post so I won’t detail but I suggest you to have a look at how to build Qt and how to strip down Qt for embedded system. In short: the graphic systems are pluggable, you don’t load everything. And you can choose which feature of Qt and WebKit you compile when you target embedded.
What’s the difference between the “hw accelerated canvas implementation” google’s working on and running QtWebkit though one of Qt’s hw accelerated paint engines (GLES/VG)?
@TomCooksey
We don’t know yet, it is not released. By the way, we have aweful results with the graphics system openGL on some canvas demos. Would you have the time/will to have a look?
@Benjamin: Depends, are the awful results on an ARM Mali GPU?
> Depends, are the awful results on an ARM Mali GPU?
I am sure we can engineer something awfull there if that help you improve canvas on openGL
@Markus: we’re now working on QtWebKit 2.1, which will be a short release that we’re expecting to be ready some time before Qt 4.8. Release 2.1 has already been branched, featuring HTML5 geolocation, tactile feedback support, transform action event among others. We haven’t scoped release 2.2 and we don’t yet know how QtWebKit 2.2 will relate to Qt release schedules.
yan: I would still have preferred that you contributed those changes you did to the official research project for Canvas in QML rather than fork it off and compete with it. This way we can push them as a core Qt component at some point.
The repository can be found here: http://qt.gitorious.org/qt-labs/qmlcanvas
Benjamin: sorry to be OT but what happens when qconfig has been tried, a lot of code regressions found (bc TT doesn’t test these paths anymore), and patch submissions through JIRA are sometimes deprioritized to the point of being ignored?
IMO, fork Qt or drop support.
Meantime, with even FF4 and Chrome exploring hwa of HTML5, Qt’s direction on this is fuzzy especially with continued focus on the software rasterizing core.
@NuShrike
Sorry but I am not gonna answer that. Over the last couple of days, you just wrote angry comments, and you are not being constructive in any way.
We have very nice contributors who make amazing stuff happening. We have users making amazing stuff with embedded platforms, and who contribute back their code so everybody can enjoy it (just look at gitorious). Being angry at us for whatever reason is not gonna help you to get anywhere.
Comments on this entry are closed.