简体   繁体   English

javascript是否有blit或memcpy命令?

[英]Does javascript have a blit or memcpy command?

I've build my own flip command and, well its slow and takes forever. 我已经构建了自己的flip命令,并且它很慢并且需要永远。 I would like to know if javascript has a blit or memcpy style command. 我想知道javascript是否有blitmemcpy样式命令。 Right now I'm going through item by item with for loops to do a copy and it takes "forever". 现在,我正在逐个项目地使用for循环进行复制,它需要“永远”。

Here is a example use of my flip function. 以下是我的翻转功能的示例用法。 I'm running 3 layers, only 1 if full height, with 3 simple animations and the fps it topped out at about 35 FPS. 我正在运行3层,如果全高,则只有1层,有3个简单的动画,fps以35 FPS的速度突出。 Ideally 3 layes should be topped out at far far higher FPS, in the 200+ range I would expect. 理想情况下,在远远高于FPS的情况下,应该有3个位置,在我预期的200+范围内。

v:36.8 l0:36.8 l1:57.8 l2:36.8 The layer's FPS are the rendering to their buffers, the v is the rendering to the canvas with the flip function. v:36.8 l0:36.8 l1:57.8 l2:36.8图层的FPS是对其缓冲区的渲染,v是使用flip函数渲染到画布。 (These FPS are from Chrome on a mac) (这些FPS来自Mac上的Chrome)

v = the screen update, the main flip function listed below.
l0 = The bottom fire, its a full height layer
l2 = The static noise, its a 1/2 height layer
l3 = The top fire, its a 1/4 height layet

Imagine having 9 or 10 layers, the FPS would drop like a stone. 想象一下,有9层或10层,FPS会像石头一样掉落。 In FF version 12 its already unusable... not even double digit FPS rates. 在FF版本12中,它已经无法使用......甚至没有两位数的FPS费率。 Opera is at least double digets. 歌剧至少是双倍的。

v:4.2 l0:4.2 l1:4.2 l2:4.2 (FF 12 OSX)
v:15.5 l0:15.5 l1:15.5 l2:15.5  (Opera latest OSX)

My flip function 我的翻转功能

flip : function() {
    var fps = '';
    // Combine the layers onto the back buffer
    for (var l = 0; l < this.layers.length; l++)
    {
        fps += 'l' + l + ':' + this.layers[l].fps.toFixed(1) + ' ';
        var layerWidth = this.layers[l].options.width;
        var layerHeight = this.layers[l].options.height;
        for (var x = 0; x < layerWidth; x++)
        {
            for (var y = 0; y < layerHeight; y++)
            {
                var index = (y*this.layers[l].options.width + x)*4;
                var r = this.layers[l].buffer[index+0];
                var g = this.layers[l].buffer[index+1];
                var b = this.layers[l].buffer[index+2];
                var a = this.layers[l].buffer[index+3];
                if (r|g|b|a != 0) {
                    this.buffer.data[index+0] = r;
                    this.buffer.data[index+1] = g;
                    this.buffer.data[index+2] = b;
                    this.buffer.data[index+3] = a;
                }
            }
        }
    }
    fps = 'v:' + this.fps.toFixed(1) + ' ' + fps;
    this.$fps.html(fps);

    // blit the buffer
    this.context.putImageData(this.buffer, 0, 0);

    // Calculate fps
    var now = new Date;
    var thisFrameFPS = 1000 / (now - this.last);
    this.fps += (thisFrameFPS - this.fps) / 50;
    this.last = now;


    var t = this;
    setTimeout(function() {t.flip.apply(t);}, this.speed);
}

Your code can be improved, but I doubt that the speedup will be significant. 您的代码可以改进,但我怀疑加速是否会很重要。

Here's what I came up with, note it is untested. 这是我想出来的,请注意它未经测试。 I have assumed that the order of processing the layers is not significant, if it is replace the first for loop with your version. 我假设处理图层的顺序并不重要,如果它是用您的版本替换第一个for循环。

function flip () {
    var fps = '';
    // Combine the layers onto the back buffer
    for (var l = this.layers.length; l--;) {
        fps += 'l' + l + ':' + this.layers[l].fps.toFixed (1) + ' ';
        var layerWidth = this.layers[l].options.width;
        var layerHeight = this.layers[l].options.height;
        for (var index = 0, x = layerWidth; x--;) {
            for (var y = layerHeight; y--; index += 4) {
                var r = this.layers[l].buffer[index+0];
                var g = this.layers[l].buffer[index+1];
                var b = this.layers[l].buffer[index+2];
                var a = this.layers[l].buffer[index+3];
                if (r|g|b|a != 0) {
                    this.buffer.data[index+0] = r;
                    this.buffer.data[index+1] = g;
                    this.buffer.data[index+2] = b;
                    this.buffer.data[index+3] = a;
                }
            }
        }
    }
};

On the assumption that the r,g,b and a are all 8 bit quantiites you could consider packing them into a single int. 假设r,g,b和a都是8位量化,您可以考虑将它们打包成单个int。 That would reduce the processing in the inner loop. 这将减少内循环中的处理。 Even more efficient would be to use the new arrayBuffer facilities 更高效的是使用新的arrayBuffer工具

There is a memcpy.js that uses Typed​Array​.prototype​.subarray() if available. 有一个memcpy.js使用Typed Array .prototype .subarray()(如果可用)。
The browser support is good and even IE10 have subarray . 浏览器支持很好 ,甚至IE10都有subarray

function memcpy (src, srcOffset, dst, dstOffset, length) {
    var i

    src = src.subarray || src.slice ? src : src.buffer
    dst = dst.subarray || dst.slice ? dst : dst.buffer

    src = srcOffset ? src.subarray ?
        src.subarray(srcOffset, length && srcOffset + length) :
        src.slice(srcOffset, length && srcOffset + length) : src

    if (dst.set) {
        dst.set(src, dstOffset)
    } else {
        for (i=0; i<src.length; i++) {
            dst[i + dstOffset] = src[i]
        }
    }

    return dst
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM