5

在使用 Canvas2D 进行一些非常密集的渲染时,我遇到了一些特别难以调试的问题。我使用各种各样的东西,从globalCompositeOperation多个屏幕外的画布,中间有一些drawImage魔法。

它在:

  • 铬 (26) [OSX 10.7.5]
  • Safari (6.0.2) [OSX 10.7.5]
  • Firefox(18 和 20 Aurora)[OSX 10.7.5]
  • 铬 (24) [Windows 7]
  • 火狐 (12) [Windows 7]
  • 铬 (24) [Archlinux, Gnome 3]

编辑:添加了针对 Windows 7 的测试。奇怪的是,它适用于 FF12(我的双启动时有一个旧版本),但升级到 FF18 后性能肯定会受到影响。它在 Windows 上并不像在 Linux 上那么糟糕,而且 OSX 上的相同版本也可以完美运行。可能是回归?

出于某种原因,在 Firefox 和 Linux 上(我尝试了 18 和 20 Aurora),同时拖动和渲染时渲染性能很差。

如果我触发并忘记动画,它与 Chrome/Safari 相当,但如果我拖动和渲染,我通常在释放拖动后只看到结束帧。

  • requestAnimationFrame鼠标事件处理程序上的直接渲染和直接渲染都不起作用。
  • 分析后,渲染部分的报告时间完全在可接受的范围内(绝对最差可达 100 毫秒),并且绝对与我在屏幕上看到的不对应。
  • 我尝试通过删除一些东西来减少负载,最终报告的渲染时间低于 15 毫秒,但我看到的并没有改变。

令我困惑的是,除了Linux 上的 Firefox 之外,它几乎可以在其他任何地方使用。关于我应该在哪里查看,错误报告或解决我的问题的任何想法?

4

2 回答 2

3

由于这个问题,我已经完全切换到 Linux 上的 Chrome。它源于他们使用的名为 Cairo 的旧 2D 渲染引擎,该引擎陈旧且过时。Azure 是要替换这个引擎,他们基本上已经完成了除 linux 之外的所有平台。

http://blog.mozilla.org/joe/2011/04/26/introducing-the-azure-project/ https://bugzilla.mozilla.org/show_bug.cgi?id=781731

于 2013-05-21T18:34:41.027 回答
1

我想我知道你应该根据这个看哪里:

如果我触发并忘记动画,它与 Chrome/Safari 相当,但如果我拖动和渲染,我通常在释放拖动后只看到结束帧。

可能是 Firefox 在 linux 上的双缓冲错误。

Canvas 实现内置了双缓冲。您可以在任何浏览器上看到它在一个简单的例子中的作用,比如这个:http: //jsfiddle.net/simonsarris/XzAjv/(它使用一个setTimeoutvs 额外的工作来说明清除确实不会马上发生)

这些实现尝试通过将其渲染到内部位图来延迟所有渲染,然后一次性(在下一次暂停时)将其渲染到画布上。在重绘场景之前清除画布时,这会停止“闪烁”效果,这很好。

但似乎 Linux Firefox 中存在一个普通的老错误。在您的拖动和渲染过程中,它似乎没有更新画布,可能是为了缓冲,但似乎在不应该这样做的时候这样做。这可以解释为什么它适用于即发即弃的场景。


所以我认为错误报告是有必要的。我没有任何 linux 机器,所以我无法复制它并自己提交一些东西来确定,抱歉。


这是对评论的回复:您可以在鼠标移动期间将绘图部分发送给一个小计时器。

例如:

// The old way
theCanvas.addEventListener('mousemove', function() {
  // if we're dragging and are redrawing
  drawingCode();
}, false);

// The new way
theCanvas.addEventListener('mousemove', function() {
  // if we're dragging and are redrawing

  // in 1 millisecond, fire off drawing code
  setTimeout(function() { drawingCode(); }, 1);
}, false);

没有这样的方法,它完全隐藏。您可以做的是,在鼠标移动期间,调度

于 2013-01-23T20:05:32.433 回答