Симптом
На 26.2-neoforge клиент падает после нескольких открытий/закрытий GUI:
java.lang.IllegalStateException: Texture view Sampler0 (MCEF Browser Texture 1x1) has been closed!
at com.mojang.blaze3d.opengl.GlCommandEncoder.trySetup(GlCommandEncoder.java:694)
at com.mojang.blaze3d.opengl.GlCommandEncoder.executeDraw(GlCommandEncoder.java:520)
at com.mojang.blaze3d.opengl.GlRenderPass.drawIndexed(GlRenderPass.java:153)
at net.minecraft.client.gui.render.GuiRenderer.executeDraw(GuiRenderer.java:405)
at net.minecraft.client.gui.render.GuiRenderer.executeDrawRange(GuiRenderer.java:212)
at net.minecraft.client.gui.render.GuiRenderer.draw(GuiRenderer.java:184)
at net.minecraft.client.gui.render.GuiRenderer.render(GuiRenderer.java:124)
at net.minecraft.client.renderer.GameRenderer.render(GameRenderer.java:447)
at net.minecraft.client.Minecraft.renderFrame(Minecraft.java:1328)
Рендер связывает текстуру браузера, которая уже закрыта, и это валит весь клиент,
а не только GUI. Вероятно, это же лежит в основе жалоб вида «после нескольких
открытий GUI перестаёт открываться».
Причина: preload-пул браузеров у Rinku
Установлено A/B-прогонами. Переключается ровно одной настройкой в
config/mcef/mcef.properties:
| Условие |
Результат |
browser-preload-enabled=true (дефолт), закрытие через 150 мс |
краш на 4-м цикле |
browser-preload-enabled=true (дефолт), закрытие через 3000 мс |
краш на 4-м цикле |
browser-preload-enabled=false, закрытие через 800 мс |
12/12 выжил |
Два вывода из этой таблицы:
- Это не гонка по времени. Задержка перед закрытием роли не играет — краш
наступает на одном и том же цикле при 150 мс и при 3000 мс. Значит дело в
счётчике, а не в тайминге, и первоначальная версия про отложенный
GuiRenderer как первопричину неверна: отложенный рендер лишь то место, где
закрытая текстура обнаруживается.
- Пул — необходимое условие. С выключенным preload краш не воспроизводится.
Размеры пула в дефолтном конфиге — по одному на тип:
browser-preload-enabled=true
browser-preload-opaque-pool-size=1
browser-preload-transparent-pool-size=1
1x1 в тексте ошибки — это плейсхолдерный размер текстуры браузера до первой
отрисовки, то есть в рендер попадает инстанс из пула, чья текстура уже закрыта.
Где не воспроизводится
| Таргет |
Rinku |
Результат |
| 1.21.11-fabric |
2.2.0 |
60/60 циклов, чисто |
| 26.1.2-neoforge |
2.2.0 |
12/12 циклов, чисто |
| 26.2-neoforge |
2.2.1 |
краш на 4-м цикле |
Развести «баг MC 26.2» и «баг Rinku 2.2.1» на 2.2.x невозможно: сборки
2.2.0 под 26.2 не существует, для 26.2 опубликована только 2.2.1, а 2.2.0
последняя под 26.1.1.
При этом 3.0.4 есть и под 26.1.2, и под 26.2. Так что #28 (миграция на Rinku
3.0.4) — единственный способ получить одинаковую версию Rinku на обеих линиях
26, и вполне возможно, что она же и фиксит этот краш. Проверить это без
миграции нельзя: 3.0.0 ломает API, WebGUI против него не соберётся.
Важно про метод закрытия
Баг видно только если закрывать GUI так, как это делает игрок — через
закрытие экрана, отдав уборку самому WebGUI. Если в цикле вызывать
WebSession.closeGuiAndRestoreHud() напрямую, тест делает уборку за модом и
проходит зелёным всегда. Первый прогон стресса именно так и обманул меня: 40/40
на 1.21.11 при неверном пути закрытия.
Обходной путь
Пользователям на 26.2 — в config/mcef/mcef.properties:
browser-preload-enabled=false
Ценой чуть более медленного первого открытия.
Воспроизведение
Стендом из mc-webgui/testkit (приватный репозиторий):
node mcp/repro-texture-26.mjs 26.2-neoforge 800 12
Прогон поднимает dev-клиент, открывает страницу как GUI, закрывает экран и
повторяет, отслеживая краш в логе клиента.
Что сделать
Симптом
На 26.2-neoforge клиент падает после нескольких открытий/закрытий GUI:
Рендер связывает текстуру браузера, которая уже закрыта, и это валит весь клиент,
а не только GUI. Вероятно, это же лежит в основе жалоб вида «после нескольких
открытий GUI перестаёт открываться».
Причина: preload-пул браузеров у Rinku
Установлено A/B-прогонами. Переключается ровно одной настройкой в
config/mcef/mcef.properties:browser-preload-enabled=true(дефолт), закрытие через 150 мсbrowser-preload-enabled=true(дефолт), закрытие через 3000 мсbrowser-preload-enabled=false, закрытие через 800 мсДва вывода из этой таблицы:
наступает на одном и том же цикле при 150 мс и при 3000 мс. Значит дело в
счётчике, а не в тайминге, и первоначальная версия про отложенный
GuiRendererкак первопричину неверна: отложенный рендер лишь то место, гдезакрытая текстура обнаруживается.
Размеры пула в дефолтном конфиге — по одному на тип:
1x1в тексте ошибки — это плейсхолдерный размер текстуры браузера до первойотрисовки, то есть в рендер попадает инстанс из пула, чья текстура уже закрыта.
Где не воспроизводится
Развести «баг MC 26.2» и «баг Rinku 2.2.1» на 2.2.x невозможно: сборки
2.2.0под 26.2 не существует, для 26.2 опубликована только2.2.1, а2.2.0последняя под 26.1.1.
При этом
3.0.4есть и под 26.1.2, и под 26.2. Так что #28 (миграция на Rinku3.0.4) — единственный способ получить одинаковую версию Rinku на обеих линиях
26, и вполне возможно, что она же и фиксит этот краш. Проверить это без
миграции нельзя: 3.0.0 ломает API, WebGUI против него не соберётся.
Важно про метод закрытия
Баг видно только если закрывать GUI так, как это делает игрок — через
закрытие экрана, отдав уборку самому WebGUI. Если в цикле вызывать
WebSession.closeGuiAndRestoreHud()напрямую, тест делает уборку за модом ипроходит зелёным всегда. Первый прогон стресса именно так и обманул меня: 40/40
на 1.21.11 при неверном пути закрытия.
Обходной путь
Пользователям на 26.2 — в
config/mcef/mcef.properties:Ценой чуть более медленного первого открытия.
Воспроизведение
Стендом из
mc-webgui/testkit(приватный репозиторий):Прогон поднимает dev-клиент, открывает страницу как GUI, закрывает экран и
повторяет, отслеживая краш в логе клиента.
Что сделать
закрытой текстурой / не закрывать браузер, пока кадр с ним в батче) или
это баг Rinku, который надо заводить у Keksuccino