Wednesday, 21 December 2005

Port Waikato

One of the great things about living in New Zealand is having easy access to a variety of astonishing landscapes. I took a day off today and we decided to go on a bit of a road trip. On the spur of the moment I decided to go to Port Waikato, where the Waikato River (NZ's largest) meets the sea.

It's less than 1.5 hour's drive from Auckland city. Along the way you see plenty of amazing, yet typically NZ, green, rugged farmland mixed with bush. There's a point on the motorway as you come over the Bombay Hills where the plains and hills of the Waikato region open up before you which is quite breathtaking. I was tempted to keep on going for a few hours, to cross the plains and ascend the far side of those hills to the central volcanic plateau, and see again the magnificent Lake Taupo and the great volcanoes, but that will have to wait. We turned west and followed the river out to the coast.

We missed the turnoff to the town of Port Waikato and drove on for a while mesmerized by the limestone country. The location used for "Weathertop" in The Fellowship Of The Ring is around here.


Along the way we encountered a flock of sheep being driven along the road. The farmer whistled his dog to move the sheep away from our car so we could drive on. It was brilliant.


We eventually got back to Port Waikato. The beach is much like the west coast beaches closer to Auckland --- ironsand, sea spray, chaotic surf and a distinctly wild feel. Behind, there's a huge expanse of picturesque sand dunes. We entered them from the other side away from the beach and headed towards the beach, but we eventually had to turn back not knowing how far from the beach we were. In that forbidding place, and carrying two kids much of the time, I wasn't in the mood to push our luck.


On the way home we diverted to Somerville Shopping Court in Howick, a complex of a few dozen Asian shops and restaurants. We've been working our way through the restaurants gradually over the last year. This time we went to a Taiwanese cafe which served cheap, tasty and slightly odd food ... unfortunately I didn't catch the name! All in all, a wonderful day. We are very blessed.

Friday, 16 December 2005

Frame Display Lists And Next Steps

After extensive testing, I've submitted the frame display list patch for review. It's huge so that might take some time... The results are pretty good; it seems to be a little faster than today's code in Trender benchmarks, the code is smaller and cleaner and much more correct and extensible and better documented. It will also make it relatively easy to fix longstanding issues like caret drawing and visual merging of multiple outlines for the same element. It fixes two acid2 bugs (which I think leaves two left, both of which should be fixed by the reflow branch).

The question is where to go from here. I know where I want to get to:

  1. No view system
  2. Only toplevel windows, popups, and embedding widgets have native widgets.
  3. ... except for plugins, which have platform-specific solutions, but at least initially on each platform we'll hang each plugin off the top-level widget, wrapped in its own container specifically so that we can clip the plugin to an arbitrary rectangle.
  4. Optimize window updates (repaints, scrolls, plugin geometry changes) as follows:

    1. First, compute the area that will be need to be repainted. This includes areas under plugins that will be moved/resized.
    2. Render that area into an offscreen buffer.
    3. Perform the scroll and/or plugin widget changes.
    4. Copy the repaint area from the offscreen buffer to the screen.

    This should keep flicker to a minimum. Control over this process should actually be moved down into toolkit-specific code because platforms need different approaches here. The above is merely the most generic and something that can be implemented with few changes to our cross-platform nsIWidget API, and therefore is a good first step.

Getting rid of child widgets in Gecko content will eliminate a bunch of nasty per-platform code and associated platform-specific bugs, plus improve performance. In the short term it will break accessibility, at least on Windows.

Removing widgets from subdocuments and scroll areas can't happen until the plugin work happens (otherwise plugins will stop being clipped when they're outside the scrolling area ... eww!). Removing views will be easier when widgets are removed (otherwise we'll have to port a bunch of widget management code to the frame system). The plugin work will create significant flicker until the optimized window update is implemented, but the optimized window update would be a lot easier after the widget removal. Also it would be good to do optimized window update after view removal, otherwise we'll have to implement it in the view system and then reimplement in the frame system soon afterward.

So it's a bit of a conundrum. Currently I think the best approach is to do the plugin work first, then widget removal, then view removal, then optimized window update. We can live with flickery plugin scrolling on the trunk for a while. The main argument against this approach is that we might get to the end and discover that optimized window update hasn't really fixed flickery plugins, but I think we'll just have to chance our arm. We really need to move to platform-specific solutions to get plugins rendering into offscreen buffers, anyway.

Night Of The Living Threads

Every so often someone encounters a temporary hang in the Firefox UI or an extension and declares that the solution is to use more threads. They are wrong.

The standard threads-and-locks shared-memory programming model that everyone uses today just sucks. Large numbers of possible interleavings make it difficult for programmers to reason about, and therefore code is prone to deadlocks and race conditions ... catastrophic bugs that are often hard to reproduce, diagnose, and fix. Threads-and-locks forces you to violate abstraction and/or design very complicated specifications for how synchronization works across modules. It is very difficult to get good performance; locking schemes don't scale well, and locking has considerable overhead. Maurice Herlihy says it all better than I can.

Many efforts have been made over decades to design better programming models for threads, including one that I was recently part of at IBM. You can make life better by restricting the possible interleavings or providing transactional semantics. These are promising but are not yet available in forms we can use. Even when they become available, they still add complexity over a single-threaded programming model, and fail to solve some important problems. For example, safely killing a running, non-cooperating thread is terribly difficult to get right in every system I know of.

It's important to recognize that threads solve two different problems:

  • Allowing asynchronous execution so one long-running activity does not block another activity
  • Allowing concurrent execution of multiple activities, to take advantage of multiple CPU cores

The problems that people complain about today in Firefox are entirely of the first kind. These problems can be solved without using threads. Here are some specific examples:

  • Loading a big page hangs the browser while we lay out the page. The solution here is to make it possible to interrupt the reflow, process UI and other activity, and then resume layout. This should not be very hard because we support incremental reflow already.
  • The UI hangs while some extension does I/O. The solution here is for the extension to use asynchronous I/O.
  • The UI hangs while we instantiate a plugin. The solution here is to put plugins in their own processes and communicate with them over a channel which we don't block on.

The second problem, taking advantage of multiple CPU cores, is not so easy to get around, because threads are exactly what CPUs provide (today). Therefore we will end up using multiple threads inside Gecko --- carefully, only where it makes sense because we can get significant performance benefits without great complexity; e.g., page drawing should be fairly easy to parallelize. But I will fight tooth and nail to avoid exposing threads to Web/extension developers.

Thursday, 15 December 2005

The BBC Gets It Wrong

The BBC has made a terrible hash of their article on the latest IE update. They make it appear that Firefox was in just the same situation as IE, which is completely untrue --- even fully updated IE users have been vulnerable for many days while exploit code has been circulating, but fully updated Firefox users have had the fix for nearly six months, long before any exploit code circulated. Grrrrr!

Friday, 9 December 2005

Web Standards, Mozilla Extensions And Other Ranting

I belatedly read a few blog comments complaining that Firefox is corrupting the Web by implementing nonstandard tags like <canvas> and prematurely implementing CSS3 columns.

Bollocks. You can't make good standards without implementation experience and you don't know you have a good implementation until a lot of people have used it. We take what safeguards we can to avoid poisoning the Web with a nonconformant implementation. In particular with CSS3 columns, we currently only honour -moz-column-* properties. When the standard is settled and we implement it well enough, then we'll start supporting the standard column-* properties. In the meantime anyone using -moz-column-* knows they're off the standards map. This approach will help us get a solid columns spec --- and conformant implementations --- faster.

With <canvas> the situation is a little different. It may not be blessed by the W3C (yet) but it has everything else going for it: a good spec developed in the open; interoperable, independent implementations from three vendors (two of which are open source); and it doesn't interfere with any existing standard. In short it's a fine quasi-standard.

A larger point is that work like CSS3 columns and <canvas> is required to move the Web forward. If the Web does not move forward --- if we spend all our energy refining existing specifications with fixed functionality, and developing perfect implementations of them --- then it will be replaced by something that is moving forward, which won't be based on standards, and then all our magnificent standards won't do us any good at all.

On another tack, Jim Ley writes:
I'm not convinced by canvas, IE has had 2D and 3D drawing API's and the ability to redirect HTML to an image since IE4, no-one used them, the use cases aren't really there, it's just gimicky effects, and single threaded javascript is way too slow, and bad an authoring environment for creating anything but toys.

That's an interesting suggestion. I could quibble with the facts (IE has a 3D drawing API?) but I'd rather counter with the observation that we've been able to do AJAX-style applications since before IE4, so why did it only explode over the last couple of years? I think for a long time we laboured under preconceived ideas about what Web apps could and should be. It took some adventurous coding from people like Google for everyone to raise their ambitions. I hope that with these new Web features people raise their ambitions some more.

Friday, 2 December 2005

Means And Ends

For me, Firefox is a means, not an end. I want the world's information and applications to run on a broad variety of platforms, beyond the control of a single organization. A competitive, standards-based, cross-platform Web is the best way towards that, and Firefox is doing a lot to help us get there, so every day I'm pleased to be doing my part. With its market share, its brand, its standards compliance, its expanding feature set for Web developers, and its open-source nature and non-profit masters (which guard against Gecko ever becoming the basis for some new abusive monopoly), Firefox seems to be the ideal vehicle right now. But nevertheless Firefox is only a means and other means could serve.

Therefore I am very glad that the other major standards-focused, Web-focused browsers --- Opera, Safari, and Konqueror --- are fine products doing the right things. In fact, if KHTML were to exceed Firefox in every way that matters and become the dominant browser, I would not shed one tear. (I speak hypothetically; sorry KHTML fans, but that won't happen anytime soon!) I would remain satisfied knowing that the growth of Firefox has played a big part in reversing the trend of the Web becoming IE-only, and that we have thereby held the door open for other browsers and platforms.

But the door could yet close again, so back to coding!