Friday, 29 February 2008

Platform Tilt

Vlad blogged about his work on Mac performance and how in the process he (re)discovered Webkit's back door to undocumented Apple framework APIs. This sucks.

Disassembly shows these WK functions are mostly just wrappers around undocumented framework functions. The source to the WK wrappers is not available; the implementations are in a binary blob library that you download with the Webkit sources. It appears the sole purpose of closing the source to this library is to conceal the signatures of the undocumented framework APIs used by Webkit, presumably so that ISVs like us can't use them.

These look like important APIs, especially to browser developers like us. For example, Vlad already blogged about WKDisableCGDeferredUpdates; we can work around the issue for Firefox, but if we had WKDisableCGDeferredUpdates we could avoid having to modify the plist of every application that embeds Gecko. I presume WKDrawFocusRing is used to draw 'outline:auto' in Webkit; we can't implement that feature without that API. WKCGContextIsBitmapContext would clean up some of our cairo code. There are a whole lot of font and text APIs; it's hard to know whether there's a performance benefit to using them or why else they're needed. A lot of the other APIs look like they could be useful but without documentation it's hard to be sure. Presumably in each case, these APIs were added because the Webkit developers found something they couldn't do (fast enough?) with the regular APIs, so of course we're likely to need them too. (With the exception of Apple frameworks we don't use at all, such as the HTTP stack.)

The worry is that the Mac playing field is tilted against us. Linking in the WK library is a losing proposition. We can reverse engineer the hidden APIs but that's painful and fragile. The best we can do is file feature requests with Apple to get hidden APIs exposed, or new functionality that we need exposed. We need to start doing that aggressively. It's hard though, because without knowledge of framework internals, we don't necessarily know when there's functionality we could use if only it was exposed (e.g. a fast path for a particular special case, or a special hidden feature that we can otherwise emulate in a less convenient way). It might not be productive to file requests for every bit of functionality we could possibly use in the hope that some of it's in there. This is where Apple's Webkit team has a permanent leg up on us.

Another implication is that a key part of Webkit on Mac is kept deliberately closed source by Apple. That's unfortunate. Instead of hiding the source, a much more friendly policy for Apple would be to make these APIs public as a matter of course. They may argue that there are unfrozen APIs that they don't want exposed, but there are ways around that, such as by tying symbol names to specific OS versions (CGContextFooBar_10_4?) and promising they'll just not be there in future versions.

It's worth reflecting that if Microsoft was doing this, they'd likely be hauled before a judge, in the EU if not the US. In fact I can't recall Microsoft ever pulling off an undocumented-API-fest of this magnitude.

Of course we will continue to do our best to make Firefox rock on Mac, and version 3 is excellent, even if we have to work harder to make up for lack of access to key APIs. We should be open to reducing our dependence on Apple frameworks where that make sense, although in key cases (graphics, window system) it's not possible. We need to push on Apple to make APIs public instead of concealing them. And we need to pray for open source platforms such as Linux to succeed, so one day we won't have to worry about this anymore.

Wednesday, 13 February 2008

Rounding Towards (Or Away From) Zero Considered Harmful

Operations that round towards zero are quite common. For example, C and C++ float-to-integer casts round towards zero. This means that -49.5 rounds to -49 and 49.5 rounds to 49. Operations that round away from zero are also quite common; the libc round function and its variants round away from zero, so -49.5 rounds to -50 and 49.5 rounds to 50.

Unfortunately both of these behaviours can get us into all kinds of trouble when we're rounding values for use in graphics. Suppose we're drawing an element that is an integer N pixels wide and its nominal position is X pixels from the origin, where X might be fractional, and we want to align it with pixel boundaries. Normally, if we round the left edge and right edges to their nearest pixel boundaries, we get something that's still exactly N pixels wide, no matter what X is. This is great, it means as long as elements have integer widths, they'll be consistently drawn with those widths on the screen.

But it falls down in one particular case: when we're rounding towards zero and the left edge ends up negative and the right edge is positive. Say the left edge is at -1.5 and the right edge is at 1.5. When we round them both towards zero we end up drawing an element 2 pixels wide instead of 3, just in this one unlucky region! If we round away from zero we draw 4 pixels wide instead. Oh dear.

Basically we need to avoid both of these behaviours and as much as possible just use floor(X + 0.5) or ceil(X + 0.5) to convert to integers.

(More formally, for a rounding function F, F(X + N) - F(X) = N for all real X and integer N is a very useful property to have...)

We recognized this issue in the general rendering code a little while ago, but it's just bitten me again in the SVG filter code so now I'm exasperated enough to blog about it.

Saturday, 9 February 2008

The Best Of Intentions

I've been working on SVG filters, trying to get the World Of Ecmascript SVG version to not suck when you load it in Firefox 3. There are some interesting lessons in how not to write a spec for the Web.

Basically, the SVG Working Group tried to "help" implementors by having the filter markup describe the bounds of the region that the filter will operate on (the filter effects region and the filter primitive subregions). This puts a burden on authors and their tools, but it should help us browser developers, right? Unfortunately no. What has happened is that some tools generate bad markup; in particular Omnigraffle has produced markup that basically says the shadow of every object in W.O.E. is the size of the viewport! Our naive filter implementation follows that "advice" and applies filter effects to enormous filter buffers, which is of course incredibly slow and wasteful.

Dealing with bad markup is what browsers do, and in this case it's not hard in principle. We just have to ignore the markup hints and compute reasonable bounding boxes for the temporary surfaces required by each filter effect. I have a patch that does just that, and it turns W.O.E. from "hangs the browser" to "almost snappy". The problem is that the filter attributes specifying the filter effects region are now an unnecessary burden on authors. In fact, it's worse than that; the spec says that the renderer must clip rendering to the filter effects region and the filter primitive subregions, so we have to go ahead and compute them from the markup (not trivial) just so we can clip filter effects as per spec ... clipping the author probably doesn't want anyway.

This is a classic case where well-intentioned spec authors have made life unnecessarily difficult for everyone. Specifying "hints for the implementation" can be useful --- e.g. CSS 'text-rendering' which we support in FF3 --- but you have to be sure that if the author (or her tools) gives the wrong hint, the results are not disastrous. You also have to be sure that implementations are allowed to completely ignore the hints if taking advantage of the hints would be more trouble than it's worth.

I should mention that although this is an example of where the SVG spec kinda sucks, it's also an example of the utility of SVG that we've able to render vector graphics exported by applications like Omnigraffle.

Tuesday, 5 February 2008

Recap Part 2: Foo/Baa Camp

Baa Camp was pretty good again. I have to admit I'm a cynic about a lot of Web companies so I'm not the most sympathetic attendee, but it's good to see what people are doing and of course there are a lot of interesting people there who aren't doing Web stuff.

I went to a talk on AIR by John Ballinger. The pitch seems to be "The best of Flash and Web apps, on the desktop". That's confusing because there are a bunch of different and mostly orthogonal features that tend to distinguish Web apps from desktop apps, and AIR addresses several of them at once and kind of conflates them. For example, we heard about offline usage, persistent local storage, users dragging files into the application window, client-side image compression, giving applications their own dock/taskbar icon, and handling local file types --- all features that can and should be provided by browsers too, possibly via extensions like Gears for the laggards, ideally via standard APIs like HTML5. There are few philosophical differences between AIR and the browser. The biggest one is that AIR doesn't sandbox apps, so users have to make a trust decision to use an AIR app. I don't know how high a barrier that is to AIR app adoption; I hope it's a high one, because users should be reluctant to let applications abuse them! Another, related difference is that AIR lets apps escape browser chrome such as the forward/back buttons and the address bar. I can see that app designers would love that --- yay for integrity of artistic vision! --- but I'm not sure users would. Browser navigation (back, forward, bookmarks, addresses and autocomplete) is a powerful mental model that is not only deeply entrenched but is actually very useful. Some people have suggested this issue is one reason why Flash Central didn't work out. It'll be interesting to see how it plays out this time.

One thing that came up a few times independently was that people really want vector graphics they can print out nicely --- so Flash currently doesn't cut it. Thanks to cairo our SVG printing is really nice in FF3. (It sucked on Mac for beta2 --- we took an image surface path for SVG on Mac to handle some edge cases --- but I mostly fixed that for beta3 by taking an optimistic approach and recovering with the image surface path only if we actually hit the edge case.) Of course recommending SVG is hard as long as IE ignores it. I just encourage people to ignore IE if they can get away with it and yell at Microsoft loudly if they can't (or even if they can).

At the camp I heard about Microsoft and Yahoo. It seems crazy to me; merging two losing operations isn't going to produce something that can beat Google. The infighting and integration difficulties will most likely push them even further backwards. Who knows how the technology chasm will be bridged; either Yahoo's FreeBSD/PHP/Hadoop etc stack gets replaced by MS infrastructure, at unbelievable disruption and cost, or it doesn't and they eat the cost of supporting dual architectures, leaving a lot of the putative cost savings on the table and in fact adding additional complexity. Lots of good Yahoo employees are bound to quit. I can hardly believe this, Steve Ballmer must be truly desperate.

On Friday night, before I arrived at the camp, a certain Ross Howard had "volunteered" me and Nigel Parker for a "WWF Smackdown" over the IE8 meta mode switch on Sunday morning. Of course I was up for that! It was a lot of fun ... for me at least. Most of the Web developers were pretty upset about the idea, more so than me actually, and Microsoft hasn't given Nigel much to work with. Anyway, I actually learned a few things, partly because we were able to question Nigel. I asked whether IE8 has an IE6 mode; the answer was no. That's as expected, but it's actually quite important because the motivation for the IE8 switch is the problems that prevent people from moving from IE6 to IE7. IE8 will actually do nothing to address those problems! The new mode switch will only help address any differences between IE7 and IE8. I'm not sure what giant IE7 standards-incompliance bugs IE8 will fix that require this big hammer.

I asked Nigel if IE8 will support any new CSS features. He said no, it's just CSS 2.1. That shocked me; I guess we'll have to wait and see.

I made it clear that non-IE browsers are just going to ignore the meta switch so it's really a Microsoft solution to a Microsoft problem, and as such, it doesn't bother me all that much. My biggest concern is that "IE8 mode" will actually be uniquely buggy while being nominally "more standards-compliant" --- i.e. that Microsoft will feel free to do random things where the standards are silent, instead of being careful about being backwards- and Web-compatible the way we and Webkit and Opera do.

Now I'm back at work grinding away at bugs again! I hope we can polish off FF3 soon so I can start working on and talking about new stuff. I also want to get FF3 into the hands of users because it's already quite excellent.

Recap Part 1: California

Phew! I'm finally back at home after ten frantic days, seven in California, two at the Foo (Baa) Camp in Warkworth and about one sacrificed to travel.

The California weather was lousy, especially in comparison to the amazing summer Auckland has been having. My trip to Berkeley was fun but hairy; the drive back to Mountain View down 880, an unfamiliar road, at night, in driving rain, on the wrong side of the road was especially challenging. It was well worthwhile, however, the BBQ at T-Rex was great, but better still were the discussions with Berkeley Par-Lab people. It's good to talk to architecture people once in a while about the shape of things to come.

It sounds like the future will look a lot like the Cell: many "fat cores" (traditional out-of-order multi-issue cores optimized for fastest possible execution of single-threaded code), each surrounded by a cluster of "thin cores" (in-order single-issue, optimized for regular code with big vector units). Unlike Cell all the cores will probably communicate through cache-coherent memory. A good and sobering slogan I heard was, "more transistors than you can afford to turn on". That means application-specific hardware could become a lot more attractive. For example, video decoding hardware that you can only use 5% of the time becomes a lot more attractive when transistors are free and power is the limiting factor.

Over the weekend I did some work, hung out with friends, and on Sunday me and some of the other NZ team went up to San Francisco for a little sightseeing even though the weather was terrible. Walking the Golden Gate Bridge was still fun, albeit in an unusually teeth-gritting manner.

Mozilla was fun, especially with most of the NZ team there. Some of the Berkeley people came down to talk at Mozilla on Monday. I think the talk was good but of the audience didn't understand what research is about --- it's not all supposed to make sense or lead to a product :-).

On Tuesday we froze for Firefox beta 3, which should be a great release. It was fun to be on hand for the freeze although I was too tired to stay up till midnight and then drive back to the hotel safely.

David Baron and I retriaged all the layout blockers. We've started prioritizing the remaining significant layout regressions higher than almost all other bugs to make sure they get fixed. The brutal truth is that obscure crash bugs can be ignored or fixed in a dot release but layout regressions are forever.

I got some virus which hit me pretty hard on Wednesday. Sorry Schrep, I lied when I said I was OK :-). That also happened to be the day I was sheriff although no-one noticed because the tree was very very quiet for beta3 freeze. We had a good graphics-oriented meeting where we identified and prioritized a bunch of post-FF3 projects. For the first time ever, we now actually have staffing for most of the things we want to do :-).

The work week was valuable but I think we probably could have made a bit better use of the face time. I need to reflect on that.

I didn't sleep well on my flight back, probably due to lingering virus effects, but nevertheless on Saturday morning I headed from the airport to home and then straight up to Foo/Baa Camp...