Commit c3461769 authored by juj's avatar juj Committed by GitHub

HTML5 Event Backproxying. Bump version to 1.38.17 to rebuild cache after...

HTML5 Event Backproxying. Bump version to 1.38.17 to rebuild cache after adding new field to struct info. (#6202)
parent 527cb9ba
This diff is collapsed.
......@@ -458,7 +458,10 @@ if (Module['noInitialRun']) {
#endif // HAS_MAIN
#if EXIT_RUNTIME == 0
Module["noExitRuntime"] = true;
#if USE_PTHREADS
if (!ENVIRONMENT_IS_PTHREAD) // EXIT_RUNTIME=0 only applies to default behavior of the main browser thread
#endif
Module["noExitRuntime"] = true;
#endif
#if USE_PTHREADS
......
......@@ -169,7 +169,7 @@ this.onmessage = function(e) {
}
// The thread might have finished without calling pthread_exit(). If so, then perform the exit operation ourselves.
// (This is a no-op if explicit pthread_exit() had been called prior.)
PThread.threadExit(result);
if (!Module['noExitRuntime']) PThread.threadExit(result);
} else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread.
if (threadInfoStruct && PThread.thisThreadCancelState == 0/*PTHREAD_CANCEL_ENABLE*/) {
PThread.threadCancel();
......
......@@ -1401,7 +1401,8 @@
"canvasResolutionScaleMode",
"filteringMode",
"canvasResizedCallback",
"canvasResizedCallbackUserData"
"canvasResizedCallbackUserData",
"canvasResizedCallbackTargetThread"
]
}
},
......
This diff is collapsed.
#include <stdio.h>
#include <emscripten.h>
#include <string.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
// #define TEST_SYNC_BLOCKING_LOOP
void *mainRuntimeThreadId = 0;
void *registeringThreadId = 0;
EM_BOOL mouse_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
{
static int once;
void *threadId = pthread_self();
if (!once) printf("pthread_self()=%p, registeringThreadId=%p, mainRuntimeThreadId=%p, emscripten_main_browser_thread_id()=%p\n", threadId, registeringThreadId, mainRuntimeThreadId, emscripten_main_browser_thread_id());
printf("eventType: %d, mouseEvent: %p, userData: %p, screen: (%ld,%ld), client: (%ld,%ld),%s%s%s%s button: %hu, buttons: %hu, movement: (%ld,%ld), canvas: (%ld,%ld)\n",
eventType, e, userData,
e->screenX, e->screenY, e->clientX, e->clientY,
e->ctrlKey ? " CTRL" : "", e->shiftKey ? " SHIFT" : "", e->altKey ? " ALT" : "", e->metaKey ? " META" : "",
e->button, e->buttons, e->movementX, e->movementY, e->canvasX, e->canvasY);
assert(threadId && threadId == registeringThreadId);
assert(userData == (void*)0x42);
assert(e);
assert(eventType == EMSCRIPTEN_EVENT_MOUSEMOVE);
if (once) return 0;
once = 1;
#ifdef REPORT_RESULT
REPORT_RESULT(1);
#endif
return 0;
}
void *threadMain(void *arg)
{
registeringThreadId = pthread_self();
EMSCRIPTEN_RESULT ret = emscripten_set_mousemove_callback(0, (void*)0x42, 1, mouse_callback);
assert(ret == EMSCRIPTEN_RESULT_SUCCESS);
printf("Please move the mouse cursor.\n");
#ifdef TEST_SYNC_BLOCKING_LOOP
for(;;)
{
usleep(1000);
emscripten_current_thread_process_queued_calls();
}
#else
EM_ASM(Module['noExitRuntime'] = true);
#endif
return 0;
}
int main()
{
mainRuntimeThreadId = pthread_self();
pthread_t thread;
int rc = pthread_create(&thread, NULL, threadMain, 0);
assert(rc == 0);
EM_ASM(Module['noExitRuntime'] = true);
}
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <emscripten/key_codes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
void *application_main_thread_id = 0;
void *main_browser_thread_id = 0;
volatile int saw_keydown_event_on_enter_key_on_application_main_thread = 0;
volatile int saw_keydown_event_on_enter_key_on_main_browser_thread = 0;
volatile int saw_keypress_event_on_enter_key = 0;
void ReportResult(int code)
{
printf("Test finished with code: %d\n", code);
#ifdef REPORT_RESULT
REPORT_RESULT(code);
#endif
exit(code);
}
EM_BOOL keydown_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
printf("keydown_callback_on_application_main_thread received on pthread: %p, application_main_thread_id: %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
assert((void*)pthread_self() == application_main_thread_id);
if (dom_pk_code == DOM_PK_ENTER) saw_keydown_event_on_enter_key_on_application_main_thread = 1;
return 0;
}
EM_BOOL keydown_callback_on_main_browser_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
printf("keydown_callback_on_main_browser_thread received on pthread: %p, main_browser_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), main_browser_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
assert((void*)pthread_self() == main_browser_thread_id);
#if __EMSCRIPTEN_PTHREADS__
EmscriptenKeyboardEvent *duplicatedEventStruct = malloc(sizeof(*e));
memcpy(duplicatedEventStruct, e, sizeof(*e));
emscripten_async_queue_on_thread(application_main_thread_id, EM_FUNC_SIG_IIII, keydown_callback_on_application_main_thread, duplicatedEventStruct, eventType, duplicatedEventStruct, userData);
#else
keydown_callback_on_application_main_thread(eventType, e, userData);
#endif
if (dom_pk_code == DOM_PK_ENTER) saw_keydown_event_on_enter_key_on_main_browser_thread = 1;
return dom_pk_code == DOM_PK_ENTER; // Suppress default event handling for the enter/return key so that it should not generate the keypress event.
}
EM_BOOL keypress_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
printf("keypress_callback_on_application_main_thread received on pthread: %p, application_main_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
assert((void*)pthread_self() == application_main_thread_id);
if (dom_pk_code == DOM_PK_ENTER)
{
saw_keypress_event_on_enter_key = 1;
printf("Test failed! KeyPress event came through even though it was suppressed in KeyDown handler!\n");
ReportResult(12345); // FAIL
}
return 0;
}
EM_BOOL keyup_callback_on_application_main_thread(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
int dom_pk_code = emscripten_compute_dom_pk_code(e->code);
printf("keyup_callback_on_application_main_thread received on pthread: %p, application_main_thread_id; %p, dom_pk_code: %s\n", (void*)pthread_self(), application_main_thread_id, emscripten_dom_pk_code_to_string(dom_pk_code));
assert((void*)pthread_self() == application_main_thread_id);
if (dom_pk_code == DOM_PK_ENTER)
{
if (!saw_keydown_event_on_enter_key_on_application_main_thread)
{
printf("Test failed! KeyUp event came through, but a KeyDown event should have first been processed on the application main thread!\n");
ReportResult(12346); // FAIL
}
if (!saw_keydown_event_on_enter_key_on_main_browser_thread)
{
printf("Test failed! KeyUp event came through, but a KeyDown event should have first been processed on the main browser thread!\n");
ReportResult(12347); // FAIL
}
if (saw_keypress_event_on_enter_key)
{
printf("Test failed! KeyUp event came through, but a KeyPress event was first seen, suppressing it did not work!\n");
ReportResult(12348); // FAIL
}
printf("Test passed!\n");
ReportResult(1); // PASS
}
return 0;
}
int main()
{
main_browser_thread_id = emscripten_main_browser_thread_id();
assert(main_browser_thread_id);
application_main_thread_id = (void*)pthread_self();
assert(application_main_thread_id);
printf("Main browser thread ID: %p, application main thread ID: %p\n", main_browser_thread_id, application_main_thread_id);
emscripten_set_keydown_callback_on_thread(0, 0, 1, keydown_callback_on_main_browser_thread, EM_CALLBACK_THREAD_CONTEXT_MAIN_BROWSER_THREAD);
emscripten_set_keypress_callback_on_thread(0, 0, 1, keypress_callback_on_application_main_thread, EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);
emscripten_set_keyup_callback_on_thread(0, 0, 1, keyup_callback_on_application_main_thread, EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);
printf("Please press the Enter key.\n");
EM_ASM(Module['noExitRuntime'] = true);
}
......@@ -3503,10 +3503,12 @@ window.close = function() {
for args in [[], ['-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8']]:
self.btest(path_from_root('tests', 'pthread', 'test_pthread_supported.cpp'), expected='0', args=['-O3'] + args)
# Test that --separate-asm works with -s USE_PTHREADS=1.
@requires_threads
def test_pthread_separate_asm_pthreads(self):
self.btest(path_from_root('tests', 'pthread', 'test_pthread_atomics.cpp'), expected='0', args=['-s', 'TOTAL_MEMORY=64MB', '-O3', '-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8', '--separate-asm', '--profiling'])
# Test the operation of Module.pthreadMainPrefixURL variable
@requires_threads
def test_pthread_custom_pthread_main_url(self):
self.clear()
......@@ -3831,12 +3833,16 @@ window.close = function() {
def test_utf16_textdecoder(self):
self.btest('benchmark_utf16.cpp', expected='0', args=['--embed-file', path_from_root('tests/utf16_corpus.txt') + '@/utf16_corpus.txt', '-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","lengthBytesUTF16"]'])
# Tests that it is possible to initialize and render WebGL content in a pthread by using OffscreenCanvas.
# -DTEST_CHAINED_WEBGL_CONTEXT_PASSING: Tests that it is possible to transfer WebGL canvas in a chain from main thread -> thread 1 -> thread 2 and then init and render WebGL content there.
@no_chrome('see #7374')
@requires_threads
def test_webgl_offscreen_canvas_in_pthread(self):
for args in [[], ['-DTEST_CHAINED_WEBGL_CONTEXT_PASSING']]:
self.btest('gl_in_pthread.cpp', expected='1', args=args + ['-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=2', '-s', 'OFFSCREENCANVAS_SUPPORT=1', '-lGL'])
# Tests that it is possible to render WebGL content on a <canvas> on the main thread, after it has once been used to render WebGL content in a pthread first
# -DTEST_MAIN_THREAD_EXPLICIT_COMMIT: Test the same (WebGL on main thread after pthread), but by using explicit .commit() to swap on the main thread instead of implicit "swap when rAF ends" logic
@no_chrome('see #7374')
@requires_threads
def test_webgl_offscreen_canvas_in_mainthread_after_pthread(self):
......
......@@ -187,3 +187,17 @@ class interactive(BrowserCore):
def test_threadprofiler(self):
self.btest('pthread/test_pthread_mandelbrot.cpp', expected='0', args=['-O2', '--threadprofiler', '-s', 'USE_PTHREADS=1', '-DTEST_THREAD_PROFILING=1', '-msse', '-s', 'PTHREAD_POOL_SIZE=16', '--shell-file', path_from_root('tests', 'pthread', 'test_pthread_mandelbrot_shell.html')])
# Test that event backproxying works.
def test_html5_callbacks_on_calling_thread(self):
# TODO: Make this automatic by injecting mouse event in e.g. shell html file.
for args in [[], ['-DTEST_SYNC_BLOCKING_LOOP=1']]:
self.btest('html5_callbacks_on_calling_thread.c', expected='1', args=args + ['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1'])
# Test that it is possible to register HTML5 event callbacks on either main browser thread, or application main thread,
# and that the application can manually proxy the event from main browser thread to the application main thread, to
# implement event suppression capabilities.
def test_html5_callback_on_two_threads(self):
# TODO: Make this automatic by injecting enter key press in e.g. shell html file.
for args in [[], ['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1']]:
self.btest('html5_event_callback_in_two_threads.c', expected='1', args=args)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment