Как обрабатывать ошибки WebGL CONTEXT_LOST_WEBGL более изящно в Pixi JS? - PullRequest
1 голос
/ 04 апреля 2020

У меня есть приложение React, которое использует библиотеку визуализации данных, которая использует Pixi JS.

Иногда я получаю разочаровывающие CONTEXT_LOST_WEBGL ошибки в Chrome, которые вынуждают пользователя вручную перезагрузить страницу, в порядок отображения (пере) страницы.

Я не могу часто или надежно воспроизвести ошибку, но я знаю, что это происходит, потому что другие люди говорят мне, что приложение иногда не показывает данных. Ситуации, которые вызывают эту ошибку, кажутся очень зависимыми от контекста и поэтому трудно подвести итог - маломощные графические адаптеры или множество открытых одновременно вкладок и т. Д. c.

Конечный пользователь будет знать только, что ошибки CONTEXT_LOST_WEBGL, если у этого пользователя открыто окно консоли инструментов разработчика. В противном случае веб-страница просто выглядит пустой.

Я пытался настроить мое приложение React для перезагрузки окна без вмешательства пользователя вручную, когда происходит событие webglcontextlost:

componentDidMount() {
  ...
  window.addEventListener("webglcontextlost", (e) => { window.location.reload(); });
  ...
}

Я не уверен, что он работает правильно, , то есть , если событие webglcontextlost обрабатывается в другом месте. Или, возможно, я пытаюсь подписаться на неправильное событие?

В противном случае, чтобы попытаться обработать это более изящно, есть ли способ в raw Javascript или через стороннюю библиотеку периодически измерять доступное памяти для WebGL, и использовать это измерение для перезагрузки страницы, когда доступная память достигает некоторого произвольного порога, который может предсказать неизбежное CONTEXT_LOST_WEBGL состояние ошибки?

1 Ответ

2 голосов
/ 04 апреля 2020

есть ли в raw Javascript способ периодически измерять доступную память для WebGL

Нет, точно так же, как нет способа измерить JavaScript память

window.addEventListener("webglcontextlost", (e) => { window.location.reload(); });

Неправильно. Это должно быть

someCanvas.addEventListener("webglcontextlost", (e) => { window.location.reload(); });

Каждый холст может индивидуально потерять свой контекст. Большинство браузеров допускают только 8-16 контекстов WebGL одновременно. Как только предел достигнут, холсты начинают терять свой контекст.

Что касается изящного восстановления, это большая работа. По сути, вам нужно воссоздать все ресурсы WebGL, что означает, что вам нужно структурировать свой код, чтобы это было возможно. Отделите все состояние вашего приложения от материала, выпущенного для WebGL (или от pixi. js), и когда вы получите событие потерянного контекста, затем запретите использование по умолчанию и заново создайте все содержимое WebGL

let gl;

someCanvas.addEventListener("webglcontextlost", (e) => {
  e.preventDefault();  // allows the context to be restored
});
someCanvas.addEventListener("webglcontextrestored", (e) => {
  initWebGL(gl);
});

gl = someCanvas.getContext('webgl');
initWebGL(gl);

Обратите внимание, что pixi. js сам по себе может или не может быть разработан для обработки contextlost

...