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)35DawnAsyncWait::DawnAsyncWait(const wgpu::Device& device) : fDevice(device), fSignaled(false) {} 36 yieldAndCheck() const37bool 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() const49void DawnAsyncWait::busyWait() const { 50 while (!this->yieldAndCheck()) {} 51 } 52 53 } // namespace skgpu::graphite 54