HTML Canvas performance in the Browse activity
mihai.sucan at gmail.com
Sun May 31 12:48:56 EDT 2009
I am Mihai Sucan, and I am working over the summer to develop and
integrate a paint tool  into Moodle.  I am also involved in doing
performance testing on the XO laptop.
HTML 5  has a new Canvas element  which provides an API for bitmap
drawing operations on a bidimensional surface. Rendering is generally
quite fast on desktop Web browsers, and it requires no plugins like Flash
= The problem =
On the XO OS 8.2.x, and probably on older versions, HTML Canvas
performance is most often very slow because the default Browse activity is
configured to scale pages. Typically, pages are rendered using 96 DPI in
Web browsers, but on the XO the browser renders the pages using 134 DPI.
This ensures the text and images are still readable - otherwise they'd be
far too small because the XO display  has a high DPI resolution.
Nonetheless, scaling images up is quite slow - the high-quality bilinear
filter is used. This impacts the overall performance of the browser and
moreso the performance of the Canvas element.
The Browse activity uses the xulrunner package , which contains the
Gecko layout engine  version 1.9.0 (the same as in Firefox 3.0).
Users can change the DPI used for rendering a page by going to
about:config, where they can modify the layout.css.dpi value. Yet, Hulahop
includes some piece of puzzling code  which always resets the
layout.css.dpi configuration value to 134.
The xulrunner package includes a patch  which alters the page scaling
logic  in Gecko. This patch makes a simple, yet important change to
how the DPI config value is used for scaling the page being rendered. A
normal Gecko build only scales pages using an integer scaling factor, but
on the XO the scaling factor can also be a floating-point number. This
means that a normal Gecko build uses a scale factor of 1 for DPI < 192,
and a scale factor of 2 for 192 <= DPI <= 288, and so on.
= Patches =
Gecko 1.9.1 includes a patch  which adds a new config option
layout.css.devPixelsPerPx. This allows OLPC to configure the browser such
that physical units render properly scaled using the correct DPI value,
but not the CSS pixel values. CSS pixels could be equal to device pixels -
they would all render small, but much faster.
Another Gecko patch worth being noted is the CSS image-rendering property
support . This would allow Web developers to tell Gecko to use
nearest-neighbour instead of bilinear interpolation for the scaling of
= Solutions =
The XO browser has two problems actually: 1) performance issue caused by
scaling everything up; 2) the difference in the scaling logic from a
normal Gecko build.
Problem 1: Having everything render using 96 DPI is not acceptable - pages
would be unreadable. I would suggest that Gecko on the XO scales images
using a faster algorithm instead of the bilinear one. It would also be
interesting to experiment with the new layout.css.devPixelsPerPx
configuration set to 1. Maybe hardware acceleration in newer XOs?
Problem 2: Keeping the current 134 DPI value would always require Gecko to
be patched, thus making it different from other Gecko builds. Maybe the
browser could use 200 DPI? Perhaps pages would render too big.
A different line of thought would be: "why complain about problem 2?" I
mean, Web developers are not supposed to be tinkering with DPI in their
Web pages - it's the problem of the browser.
As a Web developer I do not mind about problem 2 if problem 1 is fixed.
Problem 2 is important only when trying to work around problem 1.
= Work around =
It's simple: you need to scale down the Canvas element such that Gecko
cancels the scaling. However, you need to find out the DPI used for
rendering the page. You can do this only by using CSS 3 Media Queries .
Gecko has support for floating-point pixel values, so there's nothing to
worry about values being floating-point numbers. The work around I came up
with is described at:
This work-around is not ideal simply because it would be best if the
Browse activity would be faster by default. What do you guys think? Is
there something that can be done? The performance improvement is far from
being marginal when the work-around is used.
Sorry for this lengthy email. ;)
(I have posted this on the wiki as well for further reference to others
who need help with Canvas on the XO)
More information about the Devel