Skip to content

Commit

Permalink
Merge pull request #3282 from Desdaemon/webgl-restore
Browse files Browse the repository at this point in the history
Reset UI on WebGL context loss
  • Loading branch information
Ghabry authored Oct 13, 2024
2 parents 3b2cb25 + 6655ec7 commit f6419e3
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 3 deletions.
6 changes: 4 additions & 2 deletions resources/emscripten/emscripten-pre.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ Module = { ...Module,
canvas: (() => {
const canvas = document.getElementById('canvas');

// As a default initial behavior, pop up an alert when webgl context is lost
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener('webglcontextlost', event => {
alert('WebGL context lost. You will need to reload the page.');
event.preventDefault();
}, false);

canvas.addEventListener('webglcontextrestored', () => {
Module.api.resetCanvas();
});

return canvas;
})(),

Expand Down
8 changes: 8 additions & 0 deletions src/platform/emscripten/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "system.h"
#include "async_handler.h"
#include "baseui.h"
#include "filefinder.h"
#include "filesystem_stream.h"
#include "player.h"
Expand Down Expand Up @@ -159,6 +160,12 @@ bool Emscripten_Interface_Private::UploadFontStep2(std::string filename, int buf
return true;
}

bool Emscripten_Interface::ResetCanvas() {
DisplayUi.reset();
DisplayUi = BaseUi::CreateUi(Player::screen_width, Player::screen_height, Player::ParseCommandLine());
return DisplayUi != nullptr;
}

// Binding code
EMSCRIPTEN_BINDINGS(player_interface) {
emscripten::class_<Emscripten_Interface>("api")
Expand All @@ -173,6 +180,7 @@ EMSCRIPTEN_BINDINGS(player_interface) {
#endif
.class_function("refreshScene", &Emscripten_Interface::RefreshScene)
.class_function("takeScreenshot", &Emscripten_Interface::TakeScreenshot)
.class_function("resetCanvas", &Emscripten_Interface::ResetCanvas)
;

emscripten::class_<Emscripten_Interface_Private>("api_private")
Expand Down
1 change: 1 addition & 0 deletions src/platform/emscripten/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Emscripten_Interface {
static void RefreshScene();
static void TakeScreenshot();
static void Reset();
static bool ResetCanvas();
};

class Emscripten_Interface_Private {
Expand Down
7 changes: 6 additions & 1 deletion src/platform/emscripten/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,14 @@ void main_loop() {
Player::MainLoop();
if (!DisplayUi.get()) {
// Yield on shutdown to ensure async operations (e.g. IDBFS saving) can finish
counter = -5;
counter = -10;
}
} else if (counter == -1) {
if (DisplayUi.get()) {
// we previously lost the UI and restored it, so continue doing stuff.
counter = 6;
return;
}
emscripten_cancel_main_loop();
}
}
Expand Down

0 comments on commit f6419e3

Please sign in to comment.