5

私は自分のflipコマンドを作成しましたが、それは遅く、永遠にかかります。blitjavascript にormemcpyスタイル コマンドがあるかどうかを知りたいです。現在、forループを使用してアイテムごとにコピーを行っていますが、「永遠に」かかります。

これが私のフリップ機能の使用例です私は 3 つのレイヤーを実行しています。全高の場合は 1 つだけで、3 つの単純なアニメーションと fps が約 35 FPS に達しています。理想的には、私が期待する 200+ の範囲で、はるかに高い FPS で 3 レイをトップアウトする必要があります。

v:36.8 l0:36.8 l1:57.8 l2:36.8 レイヤーの FPS はバッファーへのレンダリングであり、v はflip関数を使用したキャンバスへのレンダリングです。(これらの 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

9 層または 10 層のレイヤーがあると想像してみてください。FPS は石のように低下​​します。FF バージョン 12 では、すでに使用できません... 2 桁の FPS レートでさえありません。Opera は少なくとも 2 桁です。

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)

私のフリップ機能

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);
}
4

2 に答える 2

2

利用可能な場合、 Typed Array .prototype .subarray()を使用するmemcpy.jsがあります。ブラウザ のサポートは良好で、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
}
于 2019-06-10T20:05:16.217 に答える
1

コードを改善することはできますが、スピードアップが重要になるとは思えません。

これが私が思いついたものです、それはテストされていないことに注意してください。最初の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;
                }
            }
        }
    }
};

r、g、b、およびaがすべて8ビットの量子であると仮定すると、それらを1つのintにパックすることを検討できます。これにより、内部ループでの処理が減ります。さらに効率的なのは、新しいarrayBuffer機能を使用することです。

于 2012-05-26T06:01:21.297 に答える