Friday, 5 November 2010

Qt on Skia

The astute, regular readers I manage to have might have wondered why I have recently been playing with Skia, Google's 2D graphics rendering library, notably used in Chromium and Android. Well, now that my experiment is in a semi-usable state, I decided that it's probably about time I let the cat out of the bag and started talking about what I've been doing.

Over the past week, I've been diving into the Qt graphics stack a bit, for my own fun and amusement, to learn more about how it works and what makes it tick. This has been my first dive into graphics, so it's been a bit of a learning curve containing many gems like:
  • "transform? what's a transform"
  • "clipping? I know I need a haircut, but..."
  • "oh, you mean I actually have to store ARGB values for everything, and the order differs from toolkit to toolkit, and in some cases, from big/little endian?"
But I think I've made some progress in figuring things out slowly. And getting my project of choice, Qt rendering using Skia, to work, slowly but surely - a picture is worth a thousand words, so without further ado:
(Qt's demos/browser/, using Skia rendering)

Of course, it's still not done. There's a lot to implement (proper text rendering not using paths, clipping, supporting QBrush formats other than solid color fills...) and a lot of bugs to fix, as is visible in the screenshot above - and then the work starts in earnest to make this fast, but I'm happy with the progress so far over the past week.

As for my intentions? Well, I don't know. First, we'll have to see if I can get it finished, then, see how it performs vs Qt's own internal raster engine. If it's faster, then perhaps there's reasons to talk to the Qt graphics folks about whether it's worthwhile to include in Qt or not.

Even if this code doesn't make its way into Qt, I'm confident that there will be some valuable lessons and contributions from it. I do plan to write up another post on how to introduce a new graphics system into Qt, and I also have some notes to improve documentation for things like QPaintEngineEx.

If you're interested in tracking my progress, keep an eye on my skia-master branch on Gitorious. Note that if you want to try it yourself, for now you'll need the Qt branch of my Skia clone on github (note that this will only work on x86 with SSE2 support for now), because Skia's upstream SVN repository doesn't have an up to date/working buildsystem, and also contains a few problems that block compilation. I'm aware that this isn't really end-user-friendly, or a very sensible approach, but it will do for the short term. Just build it and copy libskia.a into /src/plugins/graphicssystems/skia/.

I'd like to thank a few people for their assistance:

  • Andreas Kling, for nudging me to indulge my insane self and actually try this
  • John Brooks, for giving me a crash course on how images are actually stored in memory
  • Samuel Rødal, for walking me through the internals of Qt's graphics guts
  • Zack Rusin, for his discussion/help with implementing complex non-joined sub-paths in QSkiaPaintEngine::fill()

I'll leave you with some screenshots showing the earlier work at getting things rendered, just for fun.




the first thing Qt on Skia drew, a test circle and a border. getting somewhere more useful, we rendered some blocks!




Qt on Skia manages to draw shapes in mostly the right place! Qt on Skia draws pixmaps for the first time

4 comments:

  1. Hah, nice hack. Why Skia and not, say, Cairo?

    ReplyDelete
  2. Isn't Nokia doing it in Qt-lighthouse?

    ReplyDelete
  3. Cool :D waiting for a stable release, one day we'll have qtcreator on the cloud

    ReplyDelete
  4. AFAIR, the integrated PDF rendering in Chromium uses Skia. Would be great to have PDF capabilities directly in Qt some day. It took me forever to build poppler-qt4 on Windows.

    ReplyDelete