Pixi.js: アクティブなWebGLコンテキストが倚すぎたす

䜜成日 2015幎12月11日  Â·  29コメント  Â·  ゜ヌス: pixijs/pixi.js

Reactず統合されたアプリを構築しおいたす。このアプリは、pixi.js、three.jsなど、いく぀かの個別の実隓を読み蟌みたす。iframeを䜿甚しお実隓を読み蟌むこずができないため、自分でクリヌンアップする必芁がありたす。

新しい実隓ぞのナビゲヌションがあるたびに、レンダラヌが存圚するかどうかを確認し、存圚する堎合は砎棄したす。

ダミヌコヌド

if renderer
    renderer.destroy(true);
    renderer = null

renderer = new PIXI.autoDetectRenderer ......

webglレンダラヌを正しくクリヌニングしおいるようですが、16ペヌゞが読み蟌たれるず、 WARNING: Too many active WebGL contexts. Oldest context will be lost.ずいう譊告が衚瀺されたす。譊告しかないため、デスクトップでは問題になりたせんが、iPadではクラッシュしたす。ブラりザずメッセヌゞが衚瀺されたす X A problem occurred with this web page, so it was reloaded. 。

私はthreejsず、それらがこれに察する゜リュヌションをどのように実装するかを芋おいたした、そしお圌らは次のコヌドを持っおい

私は愚かなこずをしおいたすか

最も参考になるコメント

私は良い解決策を芋぀けたず思いたす。 これにより、お互いを知る必芁のないマップオヌバヌレむReactコンポヌネントを䜜成し、ReactがDOMを所有できるようになりたす。

この手法を䜿甚し

gl.getExtension('WEBGL_lose_context').loseContext();

完党な䟋を次に瀺したす。

var document = require('global/document');
var PIXI = require('pixi.js');

// I want to keep this canvas / renderer around. For example, this might be a bottom layer PIXI / React map overlay.
var canvas1 = document.createElement('canvas');
document.body.appendChild(canvas1);
createRenderer(0xff0000, canvas1);

function createRenderer(color, canvas) {
  canvas = canvas || document.createElement('canvas');
  var renderer = new PIXI.WebGLRenderer(800, 600, {view: canvas});
  var stage = new PIXI.Container();
  var graphics = new PIXI.Graphics();
  graphics.beginFill(color, 0.5);
  graphics.drawCircle(0, 0, 200);
  graphics.endFill();
  stage.addChild(graphics);
  renderer.render(stage);
  return {renderer: renderer, stage: stage, graphics: graphics};
}

// Simulate frequent adding / removing of lots of PIXI / React map overlays on top.
for (var i = 0; i < 16; i++) {
  var canvas = document.createElement('canvas');
  document.body.appendChild(canvas);
  var scene = createRenderer(0x00ff00, canvas);
  // Uncomment to see that the original canvas isn't removed.
  /* scene.renderer.currentRenderTarget.gl
      .getExtension('WEBGL_lose_context').loseContext(); */
  scene.renderer.destroy();
  scene.stage.removeChild(scene.graphics);
  document.body.removeChild(canvas);
}

たぶん、PIXIはこれを独自の「砎棄」メ゜ッドに远加する必芁がありたすか

党おのコメント29件

@andrevenancio
ただし、月曜日たたは火曜日からしか䜿甚しおいないため、Pixiの専門家ではありたせん。 䞀床に1぀だけにアクセスする必芁があるずいう考えで、倚くの実隓このようなのために耇数のレンダラヌずキャンバスがある堎合は、グロヌバルレンダラヌたたは別のレンダラヌを䜿甚しお、実隓を配列に保持したす。 次に、それを衚瀺する必芁がある堎合は、各実隓のステヌゞをレンダラヌに枡すだけです。

var renderer = PIXI.autoDetectRenderer({blah});
var experiments = [];
experiments.push(experiment1);
experiments.push(experiment2);
experiments.push(experiment3);

var currentExperiment = $('#experminetSelector').val();
renderer.render(experiments[currentExperiment]);

このようにしお、レンダラヌを1回だけ䜜成し、各実隓のステヌゞに枡すだけです。 ただし、これは、倚くの異なる実隓ペヌゞを甚意するのではなく、1぀のペヌゞのみをレンダリングしお、すべおの実隓を実行しようずしおいる堎合にのみ機胜したす。

免責事項私はpixiを初めお䜿甚したすが、これを詊しおいたせん。マむレヌゞは異なる堎合がありたす。 たた、開発者が調査したり、ガむダンスを提䟛したりするようなバグを芋぀けたようにも聞こえたす。

単䞀のレンダラヌず耇数のシヌンがあれば問題ありたせん。 1぀のレンダラヌ=== 1぀のキャンバス芁玠。

皆さん、フィヌドバックをありがずうございたす。 @samuraiskirtあなたが提案しおいるこずはたったくばかげたこずではなく、それが私が通垞1぀のフレヌムワヌクでいく぀かの実隓を行う方法です...しかし、実隓はpixi.jsを䜿甚しお行うこずができるので、別の解決策を䜜成する必芁がありたすthreejsたたはプレヌンwebgl。 たた、それに加えお、react構造ですでに定矩されおいる遷移のタむプにより、ある時点で叀い実隓ず新しい実隓が同時にレンダリングされ、1぀のレンダラヌのアむデアが勝ちたした。動䜜したせん...

さらに....これは問題の回避策であり、解決策そのものではありたせん... .destroyメ゜ッドが実際にwebglコンテキストぞの参照を砎棄しない堎合...ポむントは䜕ですか :(

ペバディ コンテキストが砎棄されおいない堎合、destroy関数が想定どおりに機胜しおいないこずに完党に同意したす:)

私はさたよう、あなたはautodetectRendererを䜿っおいたすか ブラりザがwebGL察応かどうかを怜出するために䜜成したテストコンテキストが砎棄されおいない可胜性がありたす。

いく぀かの远加情報webglコンテキストを砎棄するこずはできたせん。それらはガベヌゞコレクションされたす䜕かが倉曎されおいない限り。

保持しおいる参照を削陀し、オプションでキャンバス芁玠コンテキストのクリヌンアップに必芁を削陀するず思いたすが、クリヌンアップを行うのはブラりザヌの責任です。 コンテキストがリヌクしおいるか、ブラりザが必芁ずするよりも速く䜜成されおいる可胜性がありたす。 正盎なずころわかりたせん。

開発ツヌルは、このようなコンテキストの呚りのリヌクを瀺しおいたすか 倚分それは助けるこずができたすか 䜕かがコンテキストを維持しおいるように聞こえたす..倚分、コンテキストぞのjs refか、基瀎ずなるキャンバスぞのjs refですか

これが、私が䜕があっおもiframeが倧奜きな理由です。

@GoodBoyDigital私はこのようにautodetectRendererを䜿甚しおいたす

<strong i="9">@renderer</strong> = new PIXI.autoDetectRenderer canvas.width, canvas.height, { view: canvas, antialias: false, backgroundColor: 0xffffff }

私は今これを駐車しおいたす、私がそれを芋぀けたずきに解決策が䜕であるかを皆さんに知らせたす..そのコンテキストを匷制的に倱うず、ガベヌゞコレクションにそれをクリヌンアップさせるかもしれないず思っおいたした..しかしそれも確かではありたせん:)

私は同じ問題を抱えおいたす。 私が構築しおいるものでは、Pixiを頻繁に砎棄しお再構築する必芁があり、メモリぞの圱響が心配です。 珟時点では、各WebGLむンスタンスは非垞に小さいですが、これを構築し続けるず、はるかに倧きくなりたす。

䜕か進展はありたすか

明確にするために、私はPhaserを䜿甚しおいたすが、Pixiのrenderer.destroyメ゜ッドを呌び出しおいるようです。

ただ運がない。 1぀のグロヌバルレンダラヌを䜿甚しおさたざたなシヌンをレンダリングするか、iframeを介しおコンテンツをロヌドするだけで、ぶら䞋がっおいるものを適切に凊理できたす。

ちょっず芗いお、はい、これは本圓に少しトリッキヌなものです。 私が芋る限り、コンテキストを砎壊するためにできる限りのこずをしたす。 したがっお、すべおのテクスチャ/プログラムのarraybuffersectは砎棄されたす。 私たちにできるこずは、コンテキストが砎棄されたらプヌルしお、毎回新しいコンテキストを䜜成するのではなく、再利甚できるようにするこずです。

ちょっず@GoodBoyDigital私の堎合、私はアニメヌションを出し入れしおいたので、垞に2぀のコンテキストが必芁でした...それはReactず統合し、完党なpixiにしないこずの問題です...ずにかく、これが修正できるバグかどうかはわかりたせん蚀うたでもなく..ブラりザがコンテキストを管理するようなものだず思いたす... three.jsからのこのハックが機胜するかどうかさえわかりたせん...倚分それをurV4で詊しお、pixiで16以䞊のタブを開いおみおくださいhttps://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L289

それ以倖の堎合は心配ありたせん、私はすでに私のアプリのアヌキテクチャを倉曎したした... iframe FTW :)

いい人だ 私は間違いなくthree.jsトリックを远加するこずも怜蚎したす。

1぀のグロヌバルレンダリングを䜿甚したいず思いたす。 実際、それが私の究極の目暙です。 ただし、コヌドを既存のコンテキストにストリヌミングする方法が必芁です。

蚀い換えれば、ナヌザヌはコヌドを曞いおいたす。 事前に䜜成されおいたせん。

私は良い解決策を芋぀けたず思いたす。 これにより、お互いを知る必芁のないマップオヌバヌレむReactコンポヌネントを䜜成し、ReactがDOMを所有できるようになりたす。

この手法を䜿甚し

gl.getExtension('WEBGL_lose_context').loseContext();

完党な䟋を次に瀺したす。

var document = require('global/document');
var PIXI = require('pixi.js');

// I want to keep this canvas / renderer around. For example, this might be a bottom layer PIXI / React map overlay.
var canvas1 = document.createElement('canvas');
document.body.appendChild(canvas1);
createRenderer(0xff0000, canvas1);

function createRenderer(color, canvas) {
  canvas = canvas || document.createElement('canvas');
  var renderer = new PIXI.WebGLRenderer(800, 600, {view: canvas});
  var stage = new PIXI.Container();
  var graphics = new PIXI.Graphics();
  graphics.beginFill(color, 0.5);
  graphics.drawCircle(0, 0, 200);
  graphics.endFill();
  stage.addChild(graphics);
  renderer.render(stage);
  return {renderer: renderer, stage: stage, graphics: graphics};
}

// Simulate frequent adding / removing of lots of PIXI / React map overlays on top.
for (var i = 0; i < 16; i++) {
  var canvas = document.createElement('canvas');
  document.body.appendChild(canvas);
  var scene = createRenderer(0x00ff00, canvas);
  // Uncomment to see that the original canvas isn't removed.
  /* scene.renderer.currentRenderTarget.gl
      .getExtension('WEBGL_lose_context').loseContext(); */
  scene.renderer.destroy();
  scene.stage.removeChild(scene.graphics);
  document.body.removeChild(canvas);
}

たぶん、PIXIはこれを独自の「砎棄」メ゜ッドに远加する必芁がありたすか

私たちがコンテキストを所有しおいる堎合、それは理にかなっおいたす。私は今、私たちが所有しおいるず想定しおいたすv3。

関数isWebGLSupportedsource / core / utils / index.jsで眮換
return !!(gl && gl.getContextAttributes().stencil);

ず
var success = !!(gl && gl.getContextAttributes().stencil); gl.getExtension('WEBGL_lose_context').loseContext(); gl = undefined; return success;

私の問題を修正したした。 それはグヌグルクロヌムで最も顕著でした-Firefoxはどちらの方法でも機胜したした。 私は少しWebGLの初心者なので、このアプロヌチに぀いおコメントしおいただければ幞いです。

チェック時にコンテキストを匷制的に倱うずいう良い呌びかけです。コンテキストを所有しおいるこずが100わかっおいるので、これは玠晎らしいアむデアです。

これはマヌゞされたしたか 私たちは同じ問題を抱えおいたす。

ping @ englercjこれは今すぐ閉じるこずができるず思いたす

gl.getExtension('WEBGL_lose_context').loseContext()は譊告を抑制する可胜性がありたすが、仕様では、 WEBGL_lose_context.restoreContext()が呌び出されるたで、コンテキストの喪倱をシミュレヌトするだけであるずされおいたす。これにより、最初から本圓に倱われなかった堎合にのみコンテキストを埩元できたす。

これは䟿利かもしれたせんlose_contextは仕様による単なるシミュレヌションですが、このスレッドパブリックWebGLWEBGL_lose_context mozilla開発者のJeff Gilbertからでは、FirefoxではloseContext()が「このコンテキストずそのコンテキストを解攟したすリ゜ヌス」 。

問題は、他のブラりザがこれを異なる方法で凊理するこずです。 Google開発者Ken Russellからの掚奚コメントがありたす。WebGLRenderingContextで明瀺的なdelete * APIを䜿甚しお、アプリケヌションが䜿甚しなくなったGPUリ゜​​ヌスを解攟しおください。

私はこれを実隓したこずがないこずを認めなければなりたせんが、どの解決策もブラりザ固有になるず思われたす。

興味深いFF実装ノヌト。 確かに、個々のリ゜ヌスを削陀するこずに぀いおのKenのアドバむスは、暙準的な方法のように芋えたす。FFは、倚くの人気のあるブラりザヌの1぀にすぎず、FFの動䜜でさえ予告なしに倉曎される可胜性がありたす。 たた、実装の詳现や停のナヌザヌ゚ヌゞェント文字列たたはブラりザのスニッフィング、および代替手段がある堎合は远加のコヌドパスに䟝存したくないため、ブラりザごずにテストしおいたせん。

今日、iOSでアプリのテストを行っおいたずころ、この゚ラヌが発生したした。 既知の回避策はありたすか 私のpixiビュヌはアプリの画面のサブコンポヌネントであるため、ナヌザヌがそのペヌゞから移動するず砎棄されたす。 問題を回避するために、ビュヌのキャンバスに同じレンダラヌを䜕らかの方法でデタッチ/再アタッチするこずは機胜するでしょうか

回避策は、耇数のコンテキストを䜜成しないこずです。 持っおいるものを再利甚するだけです。 ペヌゞをナビゲヌトする堎合、前のペヌゞで䜕が䜜成されたかは問題ではありたせん。

うヌん、では、コンテキストを再利甚するにはどうすればよいですか 私はangularJSを䜿甚しおいるので、テンプレヌトフレヌムワヌク内で䜜業しおいたす。 たずえば、canvas芁玠をDOMから切り離しお保存し、ナヌザヌがペヌゞに戻ったずきに、ペヌゞ内のその堎所に再アタッチするこずはできたすか PIXI内に「この既存のレンダラヌずコンテキストを䜿甚しお、この新しいキャンバスにアタッチする」ずいう方法があれば玠晎らしいのですが、内郚でどのように行われるのかわかりたせん。

私が気にする理由は、アプリの背景ずしお1぀の倧きなpixiビュヌを䜿甚しおいお、蚭定ペヌゞで䜿甚する小さなビュヌを䜿甚しおいるためです。 ナヌザヌが蚭定ペヌゞに耇数回アクセスするず、最初に䜜成されたため、メむンの背景ペヌゞが匷制終了されたす。

これは、シングルペヌゞアプリ内でPIXIを䜿甚する堎合の問題のようです。

PIXI.Application / PIXI.WebGLRenderer / PIXI.CanvasRendererのむンスタンスを保存するず、canvas芁玠のむンスタンスも保存されたす。 たずえば、PIXI.Applicationでは、HTMLCanvasElementであるviewプロパティを取埗できたす。 このcanvas芁玠を挿入しお、AngularJS / Reactアプリから削陀できたす。 PIXIでは、オプションずしお枡すこずで、䜿甚するキャンバス芁玠をレンダラヌに指瀺できたすが、これは䜿甚しないでください。 代わりに、PIXIが独自のcanvas芁玠を内郚的に䜜成し、DOMコンテナにaddChildを远加するこずを蚱可したす。

<div id="pixi-container"></div>
// maintain the reference to this Application even as your SPA view gets destroyed
const app = new PIXI.Application();

// Insert in the DOM or whatever the equivalent is in Angular
document.querySelector("#pixi-container").appendChild(app.view);

わかりたした、ありがずう、私はそれを詊しおみたす。 実は党然悪くないです。

了解したした。ビュヌを砎棄するのではなく、切り離しお再床远加するこずで問題が解決したした。助けおくれた人たちに感謝したす。

このスレッドは、閉じられた埌に最近のアクティビティがないため、自動的にロックされおいたす。 関連するバグに぀いおは、新しい問題を開いおください。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡