[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] WebKit 20-50% slower than Chrome/Minefield using large Float32Array Arrays



Cool demo.

One thing you should try, without even going to WebGL, is filling the
canvas using context.putImageData() instead of lots of fillRect calls.
 Perhaps also best to render into a 100x100 canvas, and have the
browser scale it onto the correct size on the page, instead of doing
that in your paint routine.  Though I think the scaling will be smooth
instead of blocky; not sure if you want that.

The other thing you should definitely do is make a color table instead
of making and parsing "hsl(...)" strings for every pixel.

Code (untested, edited from yours) would look something like:

model2d.displayTemperature = function(canvas, model) {
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = "rgb(0,0,0)";
    ctx.globalCompositeOperation = "destination-atop";

    // Set the CSS width/height to the desired display height.
    // Better to just do this in the HTML on the page using the
    // style attribute.
    canvas.style.width = canvas.clientWidth + 'px';
    canvas.style.height = canvas.clientHeight + 'px';

    // Force the actual source pixel data to be 100x100.
    canvas.width = 100;
    canvas.height = 100;

    var hue;
    var rgb;

    var columns = model.nx;
    var rows = model.ny;
    var ycols, ycols_plus_x;

    var t = model.t;
    var min = model2d.getMinTypedArray(t);
    var max = model2d.getMaxTypedArray(t);
    var scale = 255/(max - min);
    var temp;
    var imdata = ctx.getImageData(0, 0, 100, 100);
    var data = imdata.data;
    for (y = 0; y < rows; y++) {
        ycols = y * rows;
        var pix_index = y * 100;
        for (x = 0; x < columns; x++) {
            ycols_plus_x = ycols + x;
            temp = model.t[ycols_plus_x];
            hue =  Math.abs(Math.round(scale * temp - min) - 255);
            // Assume a pre-computed color table!
            rgb = color_table[Math.min(Math.floor(hue + 0.5), 255)];
            data[pix_index] = rgb.r;
            data[pix_index + 1] = rgb.g;
            data[pix_index + 2] = rgb.b;
            data[pix_index + 3] = rgb.a;
            pix_index += 4;
        }
    }
    ctx.putImageData(imdata, 0, 0);
}

-T

On Thu, Feb 17, 2011 at 6:42 AM, Stephen Bannasch
<stephen.bannasch@deanbrook.org> wrote:
>
> Here's a test using large Float32Array Typed Arrays (many sized 100x100)
> where WebKit ends up 20-50% slower than Chrome and Minefield. In these tests
> Minefield edges out Chrome but not by much.
>
> I found that 90% of the time was spent rendering the false-color thermal map
> graphics.
>
> Suggestions for how to speed this up would be great.
>
> I created an initial port of our Java Energy2D application running in
> JavaScript. The backing model is doing a thermal simulation of conductivity,
> convection, and radiation with 10,000 cells.
>
>  http://visual-demos.dev.concord.org/seasons/earth/model2d.html
>
> The JavaScript implementation uses JavaScript Typed Arrays so it only works
> with browsers that supports WebGL (Chrome 9, recent FireFox betas, and
> WebKit nightlies).
>
> The original Java version of Energy2D can be seen here:
> http://energy.concord.org/energy2d/index.html
>
> The JavaScript simulation model starts with a fixed high-temperature spot in
> the middle.
>
> The basic model simulation space is a 100x100 grid, 10,000 cells the same as
> the Java version of Energy2D.
>
> The JavaScript code is here:
> https://github.com/stepheneb/seasons/blob/master/earth/model2d.js
>
> I'm getting about 4 model iterations/s on Chrome and FF betas, and about 3
> on WebKit/Safari.
>
> I wondered how much of the time was doing graphics and how much was running
> the model ... turns out a huge bottleneck is rendering the graphics.
>
> The demo page renders the false-color thermal map with one of two
> techniques: using HTML5 Canvas, or stuffing 10,000 styled divs using
> innerHTML. I was surprised when the two methods ended up practically
> equivalent in time.
>
> I'd like to find a much quicker way to render the graphics ... perhaps using
> WebGL.
>
> I'm very impressed at how fast the model calculation runs.
>
> My tests below run the model for 15s on my MacOS X 10.6.6 PowerBook Pro with
> a 2.66 GHz Intel Core i7.
>
>
> Rendering to both the canvas visualization and the table of data:
>
> Browser                            model steps      model steps/s
> --------------------------------------------------------------------
> Chrome v9.0.597.102                  59              3.9
> Minefield 4.0b12pre (2011-02-16)     60              4.0
> WebKit v5.0.3 (6533.19.4, r78685)    48              3.2
>
>
> Rendering just to the canvas visualization:
>
> Browser                            model steps      model steps/s
> --------------------------------------------------------------------
> Chrome v9.0.597.102                  68              4.5
> Minefield 4.0b12pre (2011-02-16)     84              5.6
> WebKit v5.0.3 (6533.19.4, r78685)    64              4.3
>
>
> With rendering to the canvas and the table of data disabled:
>
> Browser                            model steps      model steps/s
> --------------------------------------------------------------------
> Chrome v9.0.597.102                 489             32.6
> Minefield 4.0b12pre (2011-02-16)    507             33.8
> WebKit v5.0.3 (6533.19.4, r78685)   220             14.7
>
> What is speeding this up is the use of JavaScript Typed Arrays:
>
>  http://www.khronos.org/registry/typedarray/specs/latest/
>
> This capability is associated with browsers that have implemented WebGL but
> none of the JavaScript Energy2D code is actually running on the GPU. The
> speedup is because of optimizations the JavaScript engines can make with
> math when working with fixed length arrays and one kind of number.
>
>
> -----------------------------------------------------------
> You are currently subscribed to public_webgl@khronos.org.
> To unsubscribe, send an email to majordomo@khronos.org with
> the following command in the body of your email:
> unsubscribe public_webgl
> -----------------------------------------------------------
>
>

-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email:
unsubscribe public_webgl
-----------------------------------------------------------