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 #ifndef skgpu_graphite_DawnBackendContext_DEFINED 9 #define skgpu_graphite_DawnBackendContext_DEFINED 10 11 #include "include/core/SkTypes.h" 12 #include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE 13 14 #include <memory> 15 16 namespace skgpu::graphite { 17 18 class Context; 19 struct ContextOptions; 20 21 /** 22 * WebGPU needs to allow the main thread loop to run to detect GPU progress. Dawn native has a 23 * function wgpu::Instance::ProcessEvents, not (currently) present in WebGPU, that can be used to 24 * detect GPU progress. 25 * 26 * When compiling using Emscripten/WASM the -s ASYNCIFY option can be used to yield. E.g.: 27 * 28 * EM_ASYNC_JS(void, asyncSleep, (), { 29 * await new Promise((resolve, _) = > { 30 * setTimeout(resolve, 0); 31 * }) 32 * }); 33 * 34 * WebGPUTickFunction(wgpu::Device&) { asyncSleep(); } 35 * 36 * If no DawnTickFunction is provided then the graphite::Context will be "non-yielding". This 37 * implies the following restrictions on the Context: 38 * 39 * 1) SyncToCpu::kYes is disallowed as a parameter to Context::submit. 40 * 2) The client must guarantee that GPU work has completed before destroying Context as Context 41 * cannot await the work completion in its destructor. Context reports whether it is awaiting 42 * GPU work completion via Context::hasUnfinishedGpuWork(). 43 * 44 * Using a non-yielding Context makes it possible to build and run Graphite/Dawn on WebGPU without 45 * -s ASYNCIFY. 46 */ 47 using DawnTickFunction = void(const wgpu::Instance& device); 48 49 #if !defined(__EMSCRIPTEN__) DawnNativeProcessEventsFunction(const wgpu::Instance & instance)50SK_API inline void DawnNativeProcessEventsFunction(const wgpu::Instance& instance) { 51 instance.ProcessEvents(); 52 } 53 #endif 54 55 // The DawnBackendContext contains all of the base Dawn objects needed by the graphite Dawn 56 // backend. The client will create this object and pass it into the Context::MakeDawn factory call 57 // when setting up Skia. 58 struct SK_API DawnBackendContext { 59 wgpu::Instance fInstance; 60 wgpu::Device fDevice; 61 wgpu::Queue fQueue; 62 // See comment on DawnTickFunction. 63 DawnTickFunction* fTick = 64 #if defined(__EMSCRIPTEN__) 65 nullptr; 66 #else 67 DawnNativeProcessEventsFunction; 68 #endif 69 }; 70 71 namespace ContextFactory { 72 SK_API std::unique_ptr<Context> MakeDawn(const DawnBackendContext&, const ContextOptions&); 73 } // namespace ContextFactory 74 75 } // namespace skgpu::graphite 76 77 #endif // skgpu_graphite_DawnBackendContext_DEFINED 78