HTML Canvas performance in the Browse activity

Mihai Sucan mihai.sucan at
Sun May 31 12:48:56 EDT 2009

Hello everyone!

I am Mihai Sucan, and I am working over the summer to develop and  
integrate a paint tool [1] into Moodle. [2] I am also involved in doing  
performance testing on the XO laptop.

HTML 5 [3] has a new Canvas element [4] 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  
or Java.

= 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 [5] 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 [6], which contains the  
Gecko layout engine [7] 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 [8] which always resets the  
layout.css.dpi configuration value to 134.

The xulrunner package includes a patch [9] which alters the page scaling  
logic [10] 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 [11] 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 [12]. 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 [13].

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)



Mihai Sucan

More information about the Devel mailing list