emscripten-core / emscripten-core/emscripten

Pressing with 2 fingers on an Emscripten web page causes an assertion failure on some tablets

Open
#14,064 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

I made an Emscripten SDL webpage. When I press with 2 fingers on the webpage when running it on my Amazon Fire tablet with Firefox web browser (version 88.1.2), there's a crash / freeze. It didn't happen on 2 other tablets I tried, an iPad and a Windows tablet.

Using Firefox Remote Debugging I discovered that it's an assertion failure in the generated .js code that Emscripten created. In __registerTouchEventCallback, there are 3 assertions which all fail:

`assert(!touch.isChanged);`
`assert(!touch.onTarget);`
`assert(!touch.onTarget);`

This comment was an explanation for those asserts, though I don't quite understand it:
`// Verify that browser does not recycle touch objects with old stale data, but reports new ones each time.`

Does this mean it's a bug in the browser? If so, is there a workaround?

I reproduced it with a simple test program with Emscripten 2.0.18, as well as 1.39.18, the version I was using the most.

I think it's related to, or the same as, this bug:
https://github.com/emscripten-core/emscripten/issues/12826

In that bug, @lpotter claimed that it doesn't happen with Emscripten 1.39.8. I downgraded to that version and it also fixed my problem.

Here is my test program:
```
#include
#include

#include

#ifdef __EMSCRIPTEN__
#include
#endif

using namespace std;

namespace {
/** The main SDL window */
SDL_Window* window = NULL;
/** The renderer used to render to the screen */
SDL_Renderer* renderer = NULL;
bool blink = false;
bool quit = false;
unsigned int currentTime = 0;
unsigned int startTime = 0;
}

void render() {
SDL_Rect rect;
rect.x = 10;
rect.y = 10;
rect.h = 100;
rect.w = 100;

currentTime = SDL_GetTicks();
unsigned int quarterSecondsSinceStart = (currentTime - startTime) / 250;
blink = quarterSecondsSinceStart % 2 == 1;

if (0 != SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0)) {
printf("Error setting clear colour");
}
if (0 != SDL_RenderClear(renderer)) {
printf("Error clearing");
}

int r, g, b;
r = 251; g = 211; b = 146;

if (0 != SDL_SetRenderDrawColor(renderer, r, g, b, 0)) {
printf("Error setting colour");
}

if (blink) {
if (SDL_RenderDrawRect(renderer, &rect) != 0) {
printf("Error in SDL_RenderDrawRect");
}
} else {
if (SDL_RenderFillRect(renderer, &rect) != 0) {
printf("Error in SDL_RenderDrawRect");
}
}
SDL_RenderPresent(renderer);
}

/** Called repeatedly to redraw the screen and process input */
void mainLoopFunction()
{
//Struct for handling events
SDL_Event input;

render();

//---Event polling method---
//It runs until the number of events to be polled gets to zero
while (SDL_PollEvent(&input) > 0)
{
//If they quit the game, e.g. by closing the window
if (input.type == SDL_QUIT) {
#ifdef __EMSCRIPTEN__
emscripten_cancel_main_loop();
#endif
return;
}
}
}

int main(int argc, char** args)
{
if (0 != SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS)) {
printf("Error initializing SDL: %s", SDL_GetError());
return 1;
}

startTime = SDL_GetTicks();

window = SDL_CreateWindow("Test",
SDL_WINDOWPOS_CENTERED_DISPLAY(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0),
640, 480,
(SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE));

if (window == NULL) {
printf("Error creating window");
return 1;
} else {
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
printf("Error creating renderer");
return 2;
} else {

#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(mainLoopFunction, -1, 1);
#else
do {
mainLoopFunction();
} while (quit == false);
#endif

if (renderer) {
SDL_DestroyRenderer(renderer);
}
if (window) {
SDL_DestroyWindow(window);
}
SDL_Quit();
}
}

return 0;
}

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.