火狐浏览器中离屏画布性能问题

3

我遇到了以下问题,我相信我一定做错了什么事,但是我找不到原因。(这是在Firefox 8中)

我有一个大雪碧图文件,我创建了一个新的小画布来存放其中的一个瓷砖,并使用drawImage的最基本重载将此隔离的瓷砖绘制在我的“屏幕”画布的数百个位置。

我这样做是为了避免使用drawImage的最后重载,该重载仅使用较大的精灵文件的一部分。在Chrome中,通过避免这种剪切,我惊讶地获得了约10%的性能提升。然而,在Firefox中,帧速率从300下降到17 FPS。

因此,我看到的实质上是,在Firefox中,“从图像绘制到画布”的速度比“从画布绘制到画布”快了约20倍。

这正确吗?我没有在这个特殊情况下找到任何信息,但这是我测试时看到的结果。

这是我正在使用的代码。我有什么特别愚蠢的行为吗?

function Test5() {
    var imgSprite = $('imgSprite');
    var tileCanvas = document.createElement("canvas");
    tileCanvas.width = 64; tileCanvas.height = 31;
    var tileCtx = tileCanvas.getContext("2d");
    tileCtx.drawImage(imgSprite, 0, 0, 64, 31, 0, 0, 64, 31);

    //--------------------------------------
    var ctx = getContext('mainScreen');

    ctx.fillStyle = '#fff';

    time(function() { // time will run this function many times and time it
        ctx.fillRect(0,0, 1200,900);
        var x=0, y=0, row = 0;
        for (var i=1; i < 1000; i++) {
            ctx.drawImage(tileCanvas, x,y); // <-- this is the line I care about
            // some simple code to calculate new x/y
        }
    }, 1000, "Test5", 'Drawing from an individual tile canvas, instead of a section of big sprite');
}

如果不是使用

 ctx.drawImage(tileCanvas, x,y);  

I do :

 ctx.drawImage(imgSprite, 0, 0, 64, 31, x, y, 64, 31);  

那就快20倍速度更快了。

我有什么遗漏吗?


编辑: 在提出这个问题后,我为自己制作了一个小页面,以测试不同平台上的几种不同的东西,并查看每种方式在每种情况下的最佳方式。

http://www.crystalgears.com/isoengine/jstests3-canvas.html

很抱歉,那段代码非常丑陋,只是一个快速的hack,不应该被其他人甚至是我自己在几天后看到。


你能给我们展示一下 time() 的结果和代码,这样我们就可以玩了吗? - Hogan
http://www.crystalgears.com/isoengine/jstests3-canvas.html - time()是一个非常简单的函数。请查看该页面,其中有许多不同的方法来测试在不同平台上的最佳方式。要重现此操作,请单击3个“Test 1”按钮。您会注意到画布的速度比其他两个慢20倍。很抱歉代码很丑陋,而且非常混乱,我主要是为了快速解决问题而这样做的,实际上这是从另一个快速解决问题中复制/粘贴/合并的结果。但是您可以使用此功能测试许多有趣的事情。谢谢! - Daniel Magliola
1个回答

1

没有进行分析很难确定(特别是针对您的特定图像和可能的显卡+驱动程序),但您可能会遇到https://bugzilla.mozilla.org/show_bug.cgi?id=705559

当然,该错误应该导致使用<canvas>参数的drawImage函数变慢;尽管20倍变慢非常令人惊讶(因此是“可能”)。


哦,好的...谢谢你的回复,这解释了一切。希望他们最终会修复它。同时,我还注意到在Safari iPhone中使用小图像(使用toDataURL()创建)比使用画布更快,所以我正在分支一下,在Android / Chrome上使用画布,在Firefox / iPhone上使用toDataURL()。但是,如果它有助于此的分析/改进,这可能有所帮助:http://www.crystalgears.com/isoengine/jstests3-canvas.html - Daniel Magliola
顺便说一下...不确定这是否被认为是一个“bug”,但我注意到的另一件事是,如果我在Chrome中绘制“画布区域”外部,它会非常快,而在Firefox中,它与在画布内部绘制的速度完全相同(您可以通过比较测试页面上的Test5和Test9的性能来看到这一点)。似乎Chrome首先检查边界,然后决定不进行blitting。实现类似于此的东西可能有意义,也可能没有意义,只是注意到了这种行为上的巨大差异。 - Daniel Magliola
我在Firefox代码中没有看到任何特殊情况路径,用于绘制完全在画布之外的情况...我想知道这是否是人们通常会做的事情。感谢测试用例! - Boris Zbarsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接