• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/graphite/dawn/DawnAsyncWait.h"
9 
10 #ifdef __EMSCRIPTEN__
11 #include <emscripten.h>
12 #endif  // __EMSCRIPTEN__
13 
14 namespace skgpu::graphite {
15 namespace {
16 
17 #ifdef __EMSCRIPTEN__
18 
19 // When we use Dawn/WebGPU in a WebAssembly environment, we do not have access to
20 // `wgpu::Device::Tick()`, which is only available to dawn_native. Here we emulate the same
21 // behavior by scheduling and awaiting on a single async task, which will yield to the browser's
22 // underlying event loop.
23 //
24 // This requires that Emscripten is configured with `-s ASYNCIFY` to work as expected.
25 EM_ASYNC_JS(void, asyncSleep, (), {
26     await new Promise((resolve, _) => {
27         setTimeout(resolve, 0);
28     })
29 });
30 
31 #endif  // __EMSCRIPTEN__
32 
33 }  // namespace
34 
DawnAsyncWait(const wgpu::Device & device)35 DawnAsyncWait::DawnAsyncWait(const wgpu::Device& device) : fDevice(device), fSignaled(false) {}
36 
yieldAndCheck() const37 bool DawnAsyncWait::yieldAndCheck() const {
38     if (fSignaled.load()) {
39         return true;
40     }
41 #ifdef __EMSCRIPTEN__
42     asyncSleep();
43 #else
44     fDevice.Tick();
45 #endif  // __EMSCRIPTEN__
46     return fSignaled.load();
47 }
48 
busyWait() const49 void DawnAsyncWait::busyWait() const {
50     while (!this->yieldAndCheck()) {}
51 }
52 
53 } // namespace skgpu::graphite
54