WebGPUChild.h (6641B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef WEBGPU_CHILD_H_ 7 #define WEBGPU_CHILD_H_ 8 9 #include <deque> 10 #include <unordered_map> 11 12 #include "mozilla/MozPromise.h" 13 #include "mozilla/WeakPtr.h" 14 #include "mozilla/webgpu/Adapter.h" 15 #include "mozilla/webgpu/Device.h" 16 #include "mozilla/webgpu/Instance.h" 17 #include "mozilla/webgpu/PWebGPUChild.h" 18 #include "mozilla/webgpu/SupportedFeatures.h" 19 #include "mozilla/webgpu/SupportedLimits.h" 20 #include "mozilla/webgpu/ffi/wgpu.h" 21 22 namespace mozilla { 23 namespace dom { 24 struct GPURequestAdapterOptions; 25 } // namespace dom 26 namespace layers { 27 class CompositorBridgeChild; 28 } // namespace layers 29 namespace webgpu { 30 namespace ffi { 31 struct WGPUClient; 32 struct WGPULimits; 33 struct WGPUTextureViewDescriptor; 34 } // namespace ffi 35 36 using AdapterPromise = 37 MozPromise<ipc::ByteBuf, Maybe<ipc::ResponseRejectReason>, true>; 38 using PipelinePromise = MozPromise<RawId, ipc::ResponseRejectReason, true>; 39 using DevicePromise = MozPromise<bool, ipc::ResponseRejectReason, true>; 40 41 ffi::WGPUByteBuf* ToFFI(ipc::ByteBuf* x); 42 43 /// The child actor is held alive by all WebGPU DOM wrapper objects since it 44 /// provides access to the rust Client; even if it can't send any more 45 /// messages. 46 /// 47 /// It should not take part in cycle collection because the cycle collector can 48 /// be destroyed earlier than IPDL actors; see Bug 1983205. 49 /// 50 /// It also doesn't need to take part in cycle collection even if some of 51 /// its fields contain strong references to DOM wrapper objects because 52 /// we make sure that all cycles are broken either by a server message or 53 /// by `ClearActorState`. 54 class WebGPUChild final : public PWebGPUChild { 55 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebGPUChild, override) 56 57 public: 58 friend class layers::CompositorBridgeChild; 59 60 public: 61 explicit WebGPUChild(); 62 63 RawId RenderBundleEncoderFinish(ffi::WGPURenderBundleEncoder& aEncoder, 64 RawId aDeviceId, 65 const dom::GPURenderBundleDescriptor& aDesc); 66 RawId RenderBundleEncoderFinishError(RawId aDeviceId, const nsString& aLabel); 67 68 ffi::WGPUClient* GetClient() const { return mClient.get(); } 69 70 void SwapChainPresent(RawId aTextureId, 71 const RemoteTextureId& aRemoteTextureId, 72 const RemoteTextureOwnerId& aOwnerId); 73 74 void RegisterDevice(Device* const aDevice); 75 void UnregisterDevice(RawId aDeviceId); 76 77 void QueueSubmit(RawId aSelfId, RawId aDeviceId, 78 nsTArray<RawId>& aCommandBuffers, 79 const nsTArray<RawId>& aUsedExternalTextureSources); 80 void NotifyWaitForSubmit(RawId aTextureId); 81 82 static void JsWarning(nsIGlobalObject* aGlobal, const nsACString& aMessage); 83 84 void SendSerializedMessages(uint32_t aNrOfMessages, 85 ipc::ByteBuf aSerializedMessages); 86 87 private: 88 virtual ~WebGPUChild(); 89 90 UniquePtr<ffi::WGPUClient> const mClient; 91 92 /// This is used to relay device lost and uncaptured error messages. 93 /// 94 /// It must hold devices weakly, or else we can end up with cycles that might 95 /// never get broken. This is ok because: 96 /// - device lost messages no longer need to be relayed once there are no 97 /// more external references to the Device, and 98 /// - uncaptured error messages will be relayed since the Device will be 99 /// kept alive if there are any `uncapturederror` event handlers registered 100 /// (see the call to `KeepAliveIfHasListenersFor` in its constructor). 101 std::unordered_map<RawId, WeakPtr<Device>> mDeviceMap; 102 103 nsTArray<RawId> mSwapChainTexturesWaitingForSubmit; 104 105 bool mScheduledFlushQueuedMessages = false; 106 void ScheduledFlushQueuedMessages(); 107 nsTArray<ipc::ByteBuf> mQueuedDataBuffers; 108 nsTArray<ipc::MutableSharedMemoryHandle> mQueuedHandles; 109 void ClearActorState(); 110 111 public: 112 ipc::IPCResult RecvServerMessage(const ipc::ByteBuf& aByteBuf); 113 ipc::IPCResult RecvUncapturedError(RawId aDeviceId, 114 const nsACString& aMessage); 115 ipc::IPCResult RecvDeviceLost(RawId aDeviceId, uint8_t aReason, 116 const nsACString& aMessage); 117 118 size_t QueueDataBuffer(ipc::ByteBuf&& bb); 119 size_t QueueShmemHandle(ipc::MutableSharedMemoryHandle&& handle); 120 void ScheduleFlushQueuedMessages(); 121 void FlushQueuedMessages(); 122 123 void ActorDestroy(ActorDestroyReason) override; 124 125 struct PendingRequestAdapterPromise { 126 RefPtr<dom::Promise> promise; 127 RefPtr<Instance> instance; 128 RawId adapter_id; 129 }; 130 131 std::deque<PendingRequestAdapterPromise> mPendingRequestAdapterPromises; 132 133 struct PendingRequestDevicePromise { 134 RefPtr<dom::Promise> promise; 135 RawId device_id; 136 RawId queue_id; 137 nsString label; 138 RefPtr<Adapter> adapter; 139 RefPtr<SupportedFeatures> features; 140 RefPtr<SupportedLimits> limits; 141 RefPtr<AdapterInfo> adapter_info; 142 RefPtr<dom::Promise> lost_promise; 143 }; 144 145 std::deque<PendingRequestDevicePromise> mPendingRequestDevicePromises; 146 147 std::unordered_map<RawId, RefPtr<dom::Promise>> mPendingDeviceLostPromises; 148 149 struct PendingPopErrorScopePromise { 150 RefPtr<dom::Promise> promise; 151 RefPtr<Device> device; 152 }; 153 154 std::deque<PendingPopErrorScopePromise> mPendingPopErrorScopePromises; 155 156 struct PendingCreatePipelinePromise { 157 RefPtr<dom::Promise> promise; 158 RefPtr<Device> device; 159 bool is_render_pipeline; 160 RawId pipeline_id; 161 nsString label; 162 }; 163 164 std::deque<PendingCreatePipelinePromise> mPendingCreatePipelinePromises; 165 166 struct PendingCreateShaderModulePromise { 167 RefPtr<dom::Promise> promise; 168 RefPtr<Device> device; 169 RefPtr<ShaderModule> shader_module; 170 }; 171 172 std::deque<PendingCreateShaderModulePromise> 173 mPendingCreateShaderModulePromises; 174 175 struct PendingBufferMapPromise { 176 RefPtr<dom::Promise> promise; 177 RefPtr<Buffer> buffer; 178 }; 179 180 std::unordered_map<RawId, std::deque<PendingBufferMapPromise>> 181 mPendingBufferMapPromises; 182 183 // Pending submitted work done promises for each queue. We must track these 184 // separately for each queue because there are guarantees about the order 185 // different queues will complete their work in. For each queue individually 186 // we know these will be resolved FIFO. 187 std::unordered_map<ffi::WGPUQueueId, std::deque<RefPtr<dom::Promise>>> 188 mPendingOnSubmittedWorkDonePromises; 189 }; 190 191 } // namespace webgpu 192 } // namespace mozilla 193 194 #endif // WEBGPU_CHILD_H_