From 3285d258944876366d455b84e653be00e15e99ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 15 Jun 2025 17:40:56 +0300 Subject: [PATCH 1/2] Fix asynchronous GLUT main loop utilizing tests that raced against reftest XHR. --- test/float_tex.c | 11 +++++++++++ test/gl_subdata.c | 12 ++++++++++++ test/hello_world_gles.c | 8 ++++++++ test/hello_world_gles_deriv.c | 11 +++++++++++ test/hello_world_gles_proxy.c | 10 +++++++++- 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/test/float_tex.c b/test/float_tex.c index d493afc5f4fd0..5afd38f5a722b 100644 --- a/test/float_tex.c +++ b/test/float_tex.c @@ -6,6 +6,9 @@ #include #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif #define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES @@ -99,6 +102,9 @@ static void glut_draw_callback(void) { glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); glDrawArrays(GL_POINTS, 0, NUM_NODES); glutSwapBuffers(); +#ifdef __EMSCRIPTEN__ + EM_ASM(doReftest()); // All done, perform the JS side image comparison reftest. +#endif } GLuint createShader(const char source[], int type) { @@ -160,6 +166,11 @@ int main(int argc, char *argv[]) { /* Set up glut callback functions */ glutDisplayFunc(glut_draw_callback); gl_init(); +#ifdef __EMSCRIPTEN__ + // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous + // reftest immediately after falling out from main. + EM_ASM({ delete Module['postRun']; }); +#endif glutMainLoop(); return 0; } diff --git a/test/gl_subdata.c b/test/gl_subdata.c index 184891e7ec531..ba8d7c5039203 100644 --- a/test/gl_subdata.c +++ b/test/gl_subdata.c @@ -7,6 +7,10 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif + #define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #include @@ -99,6 +103,9 @@ static void glut_draw_callback(void) { glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); glDrawArrays(GL_POINTS, 0, NUM_NODES); glutSwapBuffers(); +#ifdef __EMSCRIPTEN__ + EM_ASM(doReftest()); // All done, perform the JS side image comparison reftest. +#endif } GLuint createShader(const char* source, int type) { @@ -155,6 +162,11 @@ int main(int argc, char *argv[]) { /* Set up glut callback functions */ glutDisplayFunc(glut_draw_callback); gl_init(); +#ifdef __EMSCRIPTEN__ + // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous + // reftest immediately after falling out from main. + EM_ASM({ delete Module['postRun']; }); +#endif glutMainLoop(); return 0; } diff --git a/test/hello_world_gles.c b/test/hello_world_gles.c index 673a5c90ba5ca..8f3795aad7126 100644 --- a/test/hello_world_gles.c +++ b/test/hello_world_gles.c @@ -549,6 +549,9 @@ gears_draw(void) draw_gear(gear3, transform, -3.1, 4.2, -2 * angle - 25.0, blue); glutSwapBuffers(); +#ifdef __EMSCRIPTEN__ + EM_ASM({if (typeof doReftest !== 'undefined') doReftest();}); // All done, perform the JS side image comparison reftest. +#endif #ifdef LONGTEST glutPostRedisplay(); // check for issues with not throttling calls @@ -773,6 +776,11 @@ main(int argc, char *argv[]) /* Initialize the gears */ gears_init(); +#ifdef __EMSCRIPTEN__ + // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous + // reftest immediately after falling out from main. + EM_ASM({ delete Module['postRun']; }); +#endif glutMainLoop(); return 0; diff --git a/test/hello_world_gles_deriv.c b/test/hello_world_gles_deriv.c index 592078ed77b99..c03c33323c73e 100644 --- a/test/hello_world_gles_deriv.c +++ b/test/hello_world_gles_deriv.c @@ -46,6 +46,9 @@ #include #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif #ifdef __APPLE__ #include #include @@ -541,6 +544,9 @@ gears_draw(void) draw_gear(gear3, transform, -3.1, 4.2, -2 * angle - 25.0, blue); glutSwapBuffers(); +#ifdef __EMSCRIPTEN__ + EM_ASM(doReftest()); // All done, perform the JS side image comparison reftest. +#endif } /** @@ -730,6 +736,11 @@ main(int argc, char *argv[]) /* Initialize the gears */ gears_init(); +#ifdef __EMSCRIPTEN__ + // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous + // reftest immediately after falling out from main. + EM_ASM({ delete Module['postRun']; }); +#endif glutMainLoop(); return 0; diff --git a/test/hello_world_gles_proxy.c b/test/hello_world_gles_proxy.c index 0ec0b33744226..1f6392d4ca825 100644 --- a/test/hello_world_gles_proxy.c +++ b/test/hello_world_gles_proxy.c @@ -47,6 +47,9 @@ #include #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif #ifdef __APPLE__ #include #include @@ -559,12 +562,17 @@ gears_draw(void) draw_gear(gear3, transform, -3.1, 4.2, -2 * angle - 25.0, blue); glutSwapBuffers(); +#ifdef __EMSCRIPTEN__ + EM_ASM({if (typeof doReftest !== 'undefined') doReftest();}); // All done, perform the JS side image comparison reftest. +#endif #ifdef LONGTEST glutPostRedisplay(); // check for issues with not throttling calls #endif +#ifdef __EMSCRIPTEN__ EM_ASM({ window.close() }); +#endif } /** @@ -758,7 +766,7 @@ main(int argc, char *argv[]) // Don't trigger the reftest immediately after main finishes, // this test uses rAF to perform rendering, so let it trigger // the reftest after having rendered some frames. - EM_ASM(Module['postRun'] = undefined); + EM_ASM({ delete Module['postRun']; }); #endif /* Initialize the window */ From ba484229e608753271986261dae6657bdd8a3a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sun, 15 Jun 2025 21:02:45 +0300 Subject: [PATCH 2/2] Fix --- test/hello_world_gles.c | 2 +- test/hello_world_gles_deriv.c | 2 +- test/hello_world_gles_proxy.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hello_world_gles.c b/test/hello_world_gles.c index 8f3795aad7126..bfb31a1789131 100644 --- a/test/hello_world_gles.c +++ b/test/hello_world_gles.c @@ -779,7 +779,7 @@ main(int argc, char *argv[]) #ifdef __EMSCRIPTEN__ // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous // reftest immediately after falling out from main. - EM_ASM({ delete Module['postRun']; }); + EM_ASM({ if (typeof doReftest !== 'undefined' && Module['postRun'] == doReftest) delete Module['postRun']; }); #endif glutMainLoop(); diff --git a/test/hello_world_gles_deriv.c b/test/hello_world_gles_deriv.c index c03c33323c73e..bfc523067ff74 100644 --- a/test/hello_world_gles_deriv.c +++ b/test/hello_world_gles_deriv.c @@ -739,7 +739,7 @@ main(int argc, char *argv[]) #ifdef __EMSCRIPTEN__ // This test kicks off an asynchronous glutMainLoop(), so do not perform a synchronous // reftest immediately after falling out from main. - EM_ASM({ delete Module['postRun']; }); + EM_ASM({ if (typeof doReftest !== 'undefined' && Module['postRun'] == doReftest) delete Module['postRun']; }); #endif glutMainLoop(); diff --git a/test/hello_world_gles_proxy.c b/test/hello_world_gles_proxy.c index 1f6392d4ca825..ced87ede56ec4 100644 --- a/test/hello_world_gles_proxy.c +++ b/test/hello_world_gles_proxy.c @@ -766,7 +766,7 @@ main(int argc, char *argv[]) // Don't trigger the reftest immediately after main finishes, // this test uses rAF to perform rendering, so let it trigger // the reftest after having rendered some frames. - EM_ASM({ delete Module['postRun']; }); + EM_ASM({ if (typeof doReftest !== 'undefined' && Module['postRun'] == doReftest) delete Module['postRun']; }); #endif /* Initialize the window */