xref: /aosp_15_r20/external/skia/src/gpu/graphite/dawn/DawnAsyncWait.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2022 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_DawnAsyncWait_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_DawnAsyncWait_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include "webgpu/webgpu_cpp.h"  // NO_G3_REWRITE
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker #include <atomic>
16*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker class DawnSharedContext;
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker class DawnAsyncWait {
23*c8dee2aaSAndroid Build Coastguard Worker public:
24*c8dee2aaSAndroid Build Coastguard Worker     DawnAsyncWait(const DawnSharedContext*);
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker     // Returns true if the wait has been signaled and false otherwise. If the Context allows
27*c8dee2aaSAndroid Build Coastguard Worker     // yielding, then this function yields execution to the event loop where Dawn's asynchronous
28*c8dee2aaSAndroid Build Coastguard Worker     // tasks get scheduled and returns as soon as the loop yields the execution back to the caller.
29*c8dee2aaSAndroid Build Coastguard Worker     // Otherwise, it just checks.
30*c8dee2aaSAndroid Build Coastguard Worker     bool yieldAndCheck() const;
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker     // Returns true if it is legal to call busyWait().
33*c8dee2aaSAndroid Build Coastguard Worker     bool mayBusyWait() const;
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker     // Busy-waits until this wait has been signaled. May only be called if the Context allows
36*c8dee2aaSAndroid Build Coastguard Worker     // yielding.
37*c8dee2aaSAndroid Build Coastguard Worker     // TODO(armansito): This could benefit from a timeout in the case the wait never gets signaled.
38*c8dee2aaSAndroid Build Coastguard Worker     void busyWait() const;
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker     // Marks this wait as resolved. Once called, all calls to `yieldAndCheck` and `busyWait` will
41*c8dee2aaSAndroid Build Coastguard Worker     // return true immediately.
signal()42*c8dee2aaSAndroid Build Coastguard Worker     void signal() { fSignaled = true; }
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker     // Resets this object into its unsignaled state.
reset()45*c8dee2aaSAndroid Build Coastguard Worker     void reset() { fSignaled = false; }
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker private:
48*c8dee2aaSAndroid Build Coastguard Worker     const DawnSharedContext* fSharedContext;
49*c8dee2aaSAndroid Build Coastguard Worker     std::atomic_bool fSignaled;
50*c8dee2aaSAndroid Build Coastguard Worker };
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker template <typename T> class DawnAsyncResult {
53*c8dee2aaSAndroid Build Coastguard Worker public:
DawnAsyncResult(const DawnSharedContext * sharedContext)54*c8dee2aaSAndroid Build Coastguard Worker     DawnAsyncResult(const DawnSharedContext* sharedContext) : fSync(sharedContext) {}
55*c8dee2aaSAndroid Build Coastguard Worker 
~DawnAsyncResult()56*c8dee2aaSAndroid Build Coastguard Worker     ~DawnAsyncResult() {
57*c8dee2aaSAndroid Build Coastguard Worker         if (fSync.mayBusyWait()) {
58*c8dee2aaSAndroid Build Coastguard Worker             fSync.busyWait();
59*c8dee2aaSAndroid Build Coastguard Worker         }
60*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fSync.yieldAndCheck());
61*c8dee2aaSAndroid Build Coastguard Worker     }
62*c8dee2aaSAndroid Build Coastguard Worker 
set(const T & result)63*c8dee2aaSAndroid Build Coastguard Worker     void set(const T& result) {
64*c8dee2aaSAndroid Build Coastguard Worker         fResult = result;
65*c8dee2aaSAndroid Build Coastguard Worker         fSync.signal();
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker 
getIfReady()68*c8dee2aaSAndroid Build Coastguard Worker     const T* getIfReady() const { return fSync.yieldAndCheck() ? &fResult : nullptr; }
69*c8dee2aaSAndroid Build Coastguard Worker 
waitAndGet()70*c8dee2aaSAndroid Build Coastguard Worker     const T& waitAndGet() const {
71*c8dee2aaSAndroid Build Coastguard Worker         // If fSync is already signaled, the wait will return immediately.
72*c8dee2aaSAndroid Build Coastguard Worker         fSync.busyWait();
73*c8dee2aaSAndroid Build Coastguard Worker         return fResult;
74*c8dee2aaSAndroid Build Coastguard Worker     }
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker private:
77*c8dee2aaSAndroid Build Coastguard Worker     DawnAsyncWait fSync;
78*c8dee2aaSAndroid Build Coastguard Worker     T fResult;
79*c8dee2aaSAndroid Build Coastguard Worker };
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_DawnAsyncWait_DEFINED
84