• 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/ganesh/dawn/GrDawnAsyncWait.h"
9 
10 #include "include/core/SkTypes.h"
11 
12 #ifdef __EMSCRIPTEN__
13 #include <emscripten.h>
14 #endif  // __EMSCRIPTEN__
15 
16 namespace {
17 
18 #ifdef __EMSCRIPTEN__
19 
20 // When we use Dawn/WebGPU in a WebAssembly environment, we do not have access to
21 // `wgpu::Device::Tick()`, which is only available to dawn_native. Here we emulate the same
22 // behavior by scheduling and awaiting on a single async task, which will yield to the browser's
23 // underlying event loop.
24 //
25 // This requires that Emscripten is configured with `-s ASYNCIFY` to work as expected.
26 EM_ASYNC_JS(void, asyncSleep, (), {
27     await new Promise((resolve, _) => {
28         setTimeout(resolve, 0);
29     })
30 });
31 
32 #endif  // __EMSCRIPTEN__
33 
34 }  // namespace
35 
GrDawnAsyncWait(const wgpu::Device & device)36 GrDawnAsyncWait::GrDawnAsyncWait(const wgpu::Device& device) : fDevice(device), fSignaled(false) {}
37 
yieldAndCheck() const38 bool GrDawnAsyncWait::yieldAndCheck() const {
39     if (fSignaled.load()) {
40         return true;
41     }
42 #ifdef __EMSCRIPTEN__
43     asyncSleep();
44 #else
45     fDevice.Tick();
46 #endif  // __EMSCRIPTEN__
47     return fSignaled.load();
48 }
49 
busyWait() const50 void GrDawnAsyncWait::busyWait() const {
51     while (!this->yieldAndCheck()) {}
52 }
53