WASM: Allow clients to enable pthreads.

Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.

To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.

The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.

This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
This commit is contained in:
Philip Rideout
2022-08-12 12:51:12 -07:00
parent 430f060db2
commit bfe8a8aa18
14 changed files with 83 additions and 11 deletions

View File

@@ -368,13 +368,11 @@ export EMSDK=<your chosen home for the emscripten SDK>
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
use Python to create a quick localhost server:
cannot open the HTML directly from the filesystem due to CORS. We recommend using the emrun tool
to create a quick localhost server:
```
cd out/cmake-webgl-release/web/samples
python3 -m http.server # Python 3
python -m SimpleHTTPServer # Python 2.7
emrun out/cmake-webgl-release/web/samples --no_browser --port 8000
```
You can then open http://localhost:8000/suzanne.html in your web browser.

View File

@@ -359,6 +359,10 @@ if (WEBGL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti")
endif()
if (WEBGL_PTHREADS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()
# ==================================================================================================
# Debug compiler flags
# ==================================================================================================
@@ -401,8 +405,8 @@ endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GC_SECTIONS} ${B_SYMBOLIC_FUNCTIONS}")
if (WEBGL)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_WEBGL2=1")
if (WEBGL_PTHREADS)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pthread")
endif()
# ==================================================================================================

View File

@@ -160,6 +160,10 @@ target_include_directories(gltfio_core PUBLIC ${PUBLIC_HDR_DIR})
target_compile_definitions(gltfio_core PUBLIC -DGLTFIO_DRACO_SUPPORTED=1)
target_link_libraries(gltfio_core PUBLIC dracodec)
if (WEBGL_PTHREADS)
target_compile_definitions(gltfio_core PUBLIC -DFILAMENT_WASM_THREADS)
endif()
if (NOT WEBGL AND NOT ANDROID AND NOT IOS)
# ==================================================================================================

View File

@@ -20,6 +20,7 @@
#include <vector>
#include <utils/JobSystem.h>
#include <utils/Log.h>
#include <filament/Engine.h>
#include <filament/Texture.h>
@@ -247,6 +248,11 @@ void StbProvider::decodeSingleTexture() {
StbProvider::StbProvider(Engine* engine) : mEngine(engine) {
mDecoderRootJob = mEngine->getJobSystem().createJob();
#ifndef NDEBUG
slog.i << "Texture Decoder has "
<< mEngine->getJobSystem().getThreadCount()
<< " background threads." << io::endl;
#endif
}
StbProvider::~StbProvider() {

View File

@@ -152,6 +152,10 @@ set(TEST_SRCS
test/test_BinaryTreeArray.cpp
)
if (WEBGL_PTHREADS)
target_compile_definitions(${TARGET} PUBLIC -DFILAMENT_WASM_THREADS)
endif()
# The Path tests are platform-specific
if (NOT WEBGL)
if (WIN32)

View File

@@ -303,6 +303,8 @@ public:
return mParallelSplitCount;
}
size_t getThreadCount() const { return mThreadCount; }
private:
// this is just to avoid using std::default_random_engine, since we're in a public header.
class default_random_engine {

View File

@@ -116,8 +116,14 @@
# define UTILS_HAS_HYPER_THREADING 0
#endif
#if defined(__EMSCRIPTEN__) || defined(FILAMENT_SINGLE_THREADED)
#if defined(FILAMENT_SINGLE_THREADED)
# define UTILS_HAS_THREADING 0
#elif defined(__EMSCRIPTEN__)
# if defined(__EMSCRIPTEN_PTHREADS__) && defined(FILAMENT_WASM_THREADS)
# define UTILS_HAS_THREADING 1
# else
# define UTILS_HAS_THREADING 0
# endif
#else
# define UTILS_HAS_THREADING 1
#endif

21
third_party/gltumble/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Philip Rideout
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
third_party/gltumble/gltumble.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
third_party/gltumble/tnt/README.md vendored Normal file
View File

@@ -0,0 +1,2 @@
This is [gltumble](https://github.com/prideout/gltumble), which we should eventually replace by
providing JavaScript bindings for our `CameraManipulator` class hierarchy.

View File

@@ -17,6 +17,11 @@ set(CPP_SRC
# The emcc options are not documented well, the best place to find them is the source:
# https://github.com/kripken/emscripten/blob/main/src/settings.js
if (WEBGL_PTHREADS)
set(COPTS "${COPTS} -pthread")
set(LOPTS "${LOPTS} -pthread")
endif()
# The following setting is required because we disable RTTI.
set(COPTS "${COPTS} -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0")
@@ -27,6 +32,7 @@ set(LOPTS "${LOPTS} --bind")
set(LOPTS "${LOPTS} -s ALLOW_MEMORY_GROWTH=1")
set(LOPTS "${LOPTS} -s MODULARIZE=1")
set(LOPTS "${LOPTS} -s EXPORT_NAME=Filament")
set(LOPTS "${LOPTS} -s USE_WEBGL2=1")
set(LOPTS "${LOPTS} -s FULL_ES3")
set(LOPTS "${LOPTS} -s MIN_WEBGL_VERSION=2")
set(LOPTS "${LOPTS} -s MAX_WEBGL_VERSION=2")

View File

@@ -176,7 +176,19 @@ add_custom_command(
DEPENDS ${PROJECT_BINARY_DIR}/../filament-js/filament-viewer.js
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/../filament-js/filament-viewer.js ${SERVER_DIR})
add_custom_target(filamentjs_public DEPENDS ${SERVER_DIR}/filament.js ${SERVER_DIR}/filament.wasm ${SERVER_DIR}/filament-viewer.js)
add_custom_target(filamentjs_public DEPENDS
${SERVER_DIR}/filament.js
${SERVER_DIR}/filament.wasm
${SERVER_DIR}/filament-viewer.js)
if (WEBGL_PTHREADS)
add_custom_command(
OUTPUT ${SERVER_DIR}/filament.worker.js
DEPENDS filament-js
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/../filament-js/filament.worker.js ${SERVER_DIR})
add_dependencies(filamentjs_public ${SERVER_DIR}/filament.worker.js)
endif()
# ==================================================================================================
# The websamples target depends on all HTML files, assets, and filament.{js,wasm}
@@ -220,6 +232,12 @@ add_custom_command(
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/gl-matrix/gl-matrix-min.js)
list(APPEND DEMO_ASSETS ${SERVER_DIR}/gl-matrix-min.js)
add_custom_command(
OUTPUT ${SERVER_DIR}/gltumble.min.js
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/gltumble/gltumble.min.js ${SERVER_DIR}/gltumble.min.js
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/gltumble/gltumble.min.js)
list(APPEND DEMO_ASSETS ${SERVER_DIR}/gltumble.min.js)
add_custom_target(${PROJECT_NAME} ALL DEPENDS
${DEMO_ASSETS}
sample_materials

View File

@@ -20,7 +20,7 @@ canvas { position: absolute; width: 100%; height: 100%; }
</div>
<script src="filament.js"></script>
<script src="gl-matrix-min.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script src="gltumble.min.js"></script>
<script>
const env = 'default_env';

View File

@@ -14,7 +14,7 @@ canvas { touch-action: none; width: 100%; height: 100%; }
<canvas></canvas>
<script src="filament.js"></script>
<script src="gl-matrix-min.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script src="gltumble.min.js"></script>
<script>
const mesh_url = "AnimatedMorphCube.glb";