5

Canvas2Dでかなり集中的なレンダリングを行うときに、デバッグが特に難しいものにぶつかりました。私は、いくつかの魔法を挟んでglobalCompositeOperation、複数のオフスクリーンキャンバスまで、あらゆる種類のものを使用しています。drawImage

それは完全にうまくそしてスムーズに動作します:

  • Chrome(26)[OSX 10.7.5]
  • Safari(6.0.2)[OSX 10.7.5]
  • Firefox(18と20の両方のAurora)[OSX 10.7.5]
  • Chrome(24)[Windows 7]
  • Firefox(12)[Windows 7]
  • Chromium(24)[Archlinux、Gnome 3]

編集:Windows 7のテストを追加しました。不思議なことに、FF12(デュアルブートに古いバージョンがありました)で動作しますが、FF18にアップグレードすると明らかにパフォーマンスが低下します。ただし、WindowsでもLinuxほど悪くはなく、OSXの同じバージョンでも問題なく動作します。多分回帰?

何らかの理由で、FirefoxとLinux(18と20の両方のAuroraを試しました)では、ドラッグとレンダリングを同時に行うとレンダリングパフォーマンスが低下します。

アニメーションをファイアアンドフォーゲットすると、Chrome / Safariと同等になりますが、ドラッグしてレンダリングすると、ドラッグを放した後にエンドフレームしか表示されないことがよくあります。

  • requestAnimationFrameマウスイベントハンドラーでの直接レンダリングも機能しません。
  • プロファイリング後、報告されたレンダリングパーツのタイミングは、許容範囲内(絶対最悪の場合は最大100ms)であり、画面に表示されるものとは完全に一致していません。
  • いくつかのものを削除して負荷を減らしてみたところ、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 と同等ですが、ドラッグしてレンダリングすると、ドラッグを離した後に終了フレームしか表示されないことがよくあります。

これはおそらく、Linux 上の Firefox のダブル バッファリング バグです。

キャンバスの実装には、二重バッファリングが組み込まれています。次のような簡単な例で、任意のブラウザーでの動作を確認できます: http://jsfiddle.net/simonsarris/XzAjv/setTimeoutすぐには起こらない)

実装は、内部ビットマップにレンダリングすることですべてのレンダリングを遅らせようとし、次に一度に (次の一時停止で) キャンバスにレンダリングします。これにより、シーンを再描画する前にキャンバスをクリアするときの「ちらつき」効果が停止します。これは良いことです。

しかし、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 に答える