1 // Copyright 2021 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWN_NODE_BINDING_ASYNC_RUNNER_H_ 16 #define DAWN_NODE_BINDING_ASYNC_RUNNER_H_ 17 18 #include <stdint.h> 19 #include <memory> 20 21 #include "dawn/webgpu_cpp.h" 22 #include "napi.h" 23 24 namespace wgpu { namespace binding { 25 26 // AsyncRunner is used to poll a wgpu::Device with calls to Tick() while there are asynchronous 27 // tasks in flight. 28 class AsyncRunner { 29 public: 30 AsyncRunner(Napi::Env env, wgpu::Device device); 31 32 // Begin() should be called when a new asynchronous task is started. 33 // If the number of executing asynchronous tasks transitions from 0 to 1, then a function 34 // will be scheduled on the main JavaScript thread to call wgpu::Device::Tick() whenever the 35 // thread is idle. This will be repeatedly called until the number of executing asynchronous 36 // tasks reaches 0 again. 37 void Begin(); 38 39 // End() should be called once the asynchronous task has finished. 40 // Every call to Begin() should eventually result in a call to End(). 41 void End(); 42 43 private: 44 void QueueTick(); 45 Napi::Env env_; 46 wgpu::Device const device_; 47 uint64_t count_ = 0; 48 bool tick_queued_ = false; 49 }; 50 51 // AsyncTask is a RAII helper for calling AsyncRunner::Begin() on construction, and 52 // AsyncRunner::End() on destruction. 53 class AsyncTask { 54 public: 55 inline AsyncTask(AsyncTask&&) = default; 56 57 // Constructor. 58 // Calls AsyncRunner::Begin() AsyncTask(std::shared_ptr<AsyncRunner> runner)59 inline AsyncTask(std::shared_ptr<AsyncRunner> runner) : runner_(std::move(runner)) { 60 runner_->Begin(); 61 }; 62 63 // Destructor. 64 // Calls AsyncRunner::End() ~AsyncTask()65 inline ~AsyncTask() { 66 runner_->End(); 67 } 68 69 private: 70 AsyncTask(const AsyncTask&) = delete; 71 AsyncTask& operator=(const AsyncTask&) = delete; 72 std::shared_ptr<AsyncRunner> runner_; 73 }; 74 75 }} // namespace wgpu::binding 76 77 #endif // DAWN_NODE_BINDING_ASYNC_RUNNER_H_ 78