Friday 29 February 2008
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.