Bug 1865921 Part 1: Make WebGPUParent supply a device lost callback. r=ErichDonGubler...
[gecko.git] / dom / webgpu / ipc / WebGPUParent.h
bloba488a324a71288e68b3637ad55630e11dfc064e7
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/. */
6 #ifndef WEBGPU_PARENT_H_
7 #define WEBGPU_PARENT_H_
9 #include <unordered_map>
11 #include "mozilla/WeakPtr.h"
12 #include "mozilla/webgpu/ffi/wgpu.h"
13 #include "mozilla/webgpu/PWebGPUParent.h"
14 #include "mozilla/webrender/WebRenderAPI.h"
15 #include "mozilla/ipc/RawShmem.h"
16 #include "WebGPUTypes.h"
17 #include "base/timer.h"
19 namespace mozilla {
21 namespace layers {
22 class RemoteTextureOwnerClient;
23 } // namespace layers
25 namespace webgpu {
27 class ErrorBuffer;
28 class ExternalTexture;
29 class PresentationData;
31 // Destroy/Drop messages:
32 // - Messages with "Destroy" in their name request deallocation of resources
33 // owned by the
34 // object and put the object in a destroyed state without deleting the object.
35 // It is still safe to reffer to these objects.
36 // - Messages with "Drop" in their name can be thought of as C++ destructors.
37 // They completely
38 // delete the object, so future attempts at accessing to these objects will
39 // crash. The child process should *never* send a Drop message if it still
40 // holds references to the object. An object that has been destroyed still
41 // needs to be dropped when the last reference to it dies on the child
42 // process.
44 class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
45 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebGPUParent, override)
47 public:
48 explicit WebGPUParent();
50 ipc::IPCResult RecvInstanceRequestAdapter(
51 const dom::GPURequestAdapterOptions& aOptions,
52 const nsTArray<RawId>& aTargetIds,
53 InstanceRequestAdapterResolver&& resolver);
54 ipc::IPCResult RecvAdapterRequestDevice(
55 RawId aAdapterId, const ipc::ByteBuf& aByteBuf, RawId aDeviceId,
56 AdapterRequestDeviceResolver&& resolver);
57 ipc::IPCResult RecvAdapterDrop(RawId aAdapterId);
58 ipc::IPCResult RecvDeviceDestroy(RawId aDeviceId);
59 ipc::IPCResult RecvDeviceDrop(RawId aDeviceId);
60 ipc::IPCResult RecvDeviceCreateBuffer(RawId aDeviceId, RawId aBufferId,
61 dom::GPUBufferDescriptor&& aDesc,
62 ipc::UnsafeSharedMemoryHandle&& aShmem);
63 ipc::IPCResult RecvBufferMap(RawId aBufferId, uint32_t aMode,
64 uint64_t aOffset, uint64_t size,
65 BufferMapResolver&& aResolver);
66 ipc::IPCResult RecvBufferUnmap(RawId aDeviceId, RawId aBufferId, bool aFlush);
67 ipc::IPCResult RecvBufferDestroy(RawId aBufferId);
68 ipc::IPCResult RecvBufferDrop(RawId aBufferId);
69 ipc::IPCResult RecvTextureDestroy(RawId aTextureId, RawId aDeviceId);
70 ipc::IPCResult RecvTextureDrop(RawId aTextureId);
71 ipc::IPCResult RecvTextureViewDrop(RawId aTextureViewId);
72 ipc::IPCResult RecvSamplerDrop(RawId aSamplerId);
73 ipc::IPCResult RecvCommandEncoderFinish(
74 RawId aEncoderId, RawId aDeviceId,
75 const dom::GPUCommandBufferDescriptor& aDesc);
76 ipc::IPCResult RecvCommandEncoderDrop(RawId aEncoderId);
77 ipc::IPCResult RecvCommandBufferDrop(RawId aCommandBufferId);
78 ipc::IPCResult RecvRenderBundleDrop(RawId aBundleId);
79 ipc::IPCResult RecvQueueSubmit(RawId aQueueId, RawId aDeviceId,
80 const nsTArray<RawId>& aCommandBuffers,
81 const nsTArray<RawId>& aTextureIds);
82 ipc::IPCResult RecvQueueOnSubmittedWorkDone(
83 RawId aQueueId, std::function<void(mozilla::void_t)>&& aResolver);
84 ipc::IPCResult RecvQueueWriteAction(RawId aQueueId, RawId aDeviceId,
85 const ipc::ByteBuf& aByteBuf,
86 ipc::UnsafeSharedMemoryHandle&& aShmem);
87 ipc::IPCResult RecvBindGroupLayoutDrop(RawId aBindGroupLayoutId);
88 ipc::IPCResult RecvPipelineLayoutDrop(RawId aPipelineLayoutId);
89 ipc::IPCResult RecvBindGroupDrop(RawId aBindGroupId);
90 ipc::IPCResult RecvShaderModuleDrop(RawId aModuleId);
91 ipc::IPCResult RecvComputePipelineDrop(RawId aPipelineId);
92 ipc::IPCResult RecvRenderPipelineDrop(RawId aPipelineId);
93 ipc::IPCResult RecvImplicitLayoutDrop(RawId aImplicitPlId,
94 const nsTArray<RawId>& aImplicitBglIds);
95 ipc::IPCResult RecvDeviceCreateSwapChain(
96 RawId aDeviceId, RawId aQueueId, const layers::RGBDescriptor& aDesc,
97 const nsTArray<RawId>& aBufferIds,
98 const layers::RemoteTextureOwnerId& aOwnerId,
99 bool aUseExternalTextureInSwapChain);
100 ipc::IPCResult RecvDeviceCreateShaderModule(
101 RawId aDeviceId, RawId aModuleId, const nsString& aLabel,
102 const nsCString& aCode, DeviceCreateShaderModuleResolver&& aOutMessage);
104 ipc::IPCResult RecvSwapChainPresent(
105 RawId aTextureId, RawId aCommandEncoderId,
106 const layers::RemoteTextureId& aRemoteTextureId,
107 const layers::RemoteTextureOwnerId& aOwnerId);
108 ipc::IPCResult RecvSwapChainDrop(
109 const layers::RemoteTextureOwnerId& aOwnerId);
111 ipc::IPCResult RecvDeviceAction(RawId aDeviceId,
112 const ipc::ByteBuf& aByteBuf);
113 ipc::IPCResult RecvDeviceActionWithAck(
114 RawId aDeviceId, const ipc::ByteBuf& aByteBuf,
115 DeviceActionWithAckResolver&& aResolver);
116 ipc::IPCResult RecvTextureAction(RawId aTextureId, RawId aDevice,
117 const ipc::ByteBuf& aByteBuf);
118 ipc::IPCResult RecvCommandEncoderAction(RawId aEncoderId, RawId aDeviceId,
119 const ipc::ByteBuf& aByteBuf);
120 ipc::IPCResult RecvBumpImplicitBindGroupLayout(RawId aPipelineId,
121 bool aIsCompute,
122 uint32_t aIndex,
123 RawId aAssignId);
125 ipc::IPCResult RecvDevicePushErrorScope(RawId aDeviceId, dom::GPUErrorFilter);
126 ipc::IPCResult RecvDevicePopErrorScope(
127 RawId aDeviceId, DevicePopErrorScopeResolver&& aResolver);
128 ipc::IPCResult RecvGenerateError(Maybe<RawId> aDeviceId, dom::GPUErrorFilter,
129 const nsCString& message);
131 ipc::IPCResult GetFrontBufferSnapshot(
132 IProtocol* aProtocol, const layers::RemoteTextureOwnerId& aOwnerId,
133 Maybe<Shmem>& aShmem, gfx::IntSize& aSize);
135 void ActorDestroy(ActorDestroyReason aWhy) override;
137 struct BufferMapData {
138 ipc::WritableSharedMemoryMapping mShmem;
139 // True if buffer's usage has MAP_READ or MAP_WRITE set.
140 bool mHasMapFlags;
141 uint64_t mMappedOffset;
142 uint64_t mMappedSize;
143 RawId mDeviceId;
146 BufferMapData* GetBufferMapData(RawId aBufferId);
148 bool UseExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId);
150 bool EnsureExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId,
151 ffi::WGPUDeviceId aDeviceId,
152 ffi::WGPUTextureId aTextureId,
153 uint32_t aWidth, uint32_t aHeight,
154 struct ffi::WGPUTextureFormat aFormat,
155 ffi::WGPUTextureUsages aUsage);
157 std::shared_ptr<ExternalTexture> CreateExternalTexture(
158 ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId,
159 uint32_t aWidth, uint32_t aHeight,
160 const struct ffi::WGPUTextureFormat aFormat,
161 ffi::WGPUTextureUsages aUsage);
163 std::shared_ptr<ExternalTexture> GetExternalTexture(ffi::WGPUTextureId aId);
165 void PostExternalTexture(
166 const std::shared_ptr<ExternalTexture>&& aExternalTexture,
167 const layers::RemoteTextureId aRemoteTextureId,
168 const layers::RemoteTextureOwnerId aOwnerId);
170 private:
171 static void MapCallback(ffi::WGPUBufferMapAsyncStatus aStatus,
172 uint8_t* aUserData);
173 static void DeviceLostCallback(uint8_t* aUserData, uint8_t aReason,
174 const char* aMessage);
175 void DeallocBufferShmem(RawId aBufferId);
177 void RemoveExternalTexture(RawId aTextureId);
179 virtual ~WebGPUParent();
180 void MaintainDevices();
181 void LoseDevice(const RawId aDeviceId, Maybe<uint8_t> aReason,
182 const nsACString& aMessage);
184 bool ForwardError(const RawId aDeviceId, ErrorBuffer& aError) {
185 return ForwardError(Some(aDeviceId), aError);
187 bool ForwardError(Maybe<RawId> aDeviceId, ErrorBuffer& aError);
189 void ReportError(Maybe<RawId> aDeviceId, GPUErrorFilter,
190 const nsCString& message);
192 static Maybe<ffi::WGPUFfiLUID> GetCompositorDeviceLuid();
194 UniquePtr<ffi::WGPUGlobal> mContext;
195 base::RepeatingTimer<WebGPUParent> mTimer;
197 /// A map from wgpu buffer ids to data about their shared memory segments.
198 /// Includes entries about mappedAtCreation, MAP_READ and MAP_WRITE buffers,
199 /// regardless of their state.
200 std::unordered_map<uint64_t, BufferMapData> mSharedMemoryMap;
201 /// Associated presentation data for each swapchain.
202 std::unordered_map<layers::RemoteTextureOwnerId, RefPtr<PresentationData>,
203 layers::RemoteTextureOwnerId::HashFn>
204 mPresentationDataMap;
206 RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
208 /// Associated stack of error scopes for each device.
209 std::unordered_map<uint64_t, std::vector<ErrorScope>>
210 mErrorScopeStackByDevice;
212 std::unordered_map<ffi::WGPUTextureId, std::shared_ptr<ExternalTexture>>
213 mExternalTextures;
215 // Store a set of DeviceIds that have been SendDeviceLost. We use this to
216 // limit each Device to one DeviceLost message.
217 nsTHashSet<RawId> mLostDeviceIds;
219 // Shared handle of wgpu device's fence.
220 RefPtr<gfx::FileHandleWrapper> mFenceHandle;
222 // Store DeviceLostRequest structs for each device as unique_ptrs mapped
223 // to their device ids. We keep these unique_ptrs alive as long as the
224 // device is alive.
225 struct DeviceLostRequest {
226 WeakPtr<WebGPUParent> mParent;
227 RawId mDeviceId;
229 std::unordered_map<RawId, std::unique_ptr<DeviceLostRequest>>
230 mDeviceLostRequests;
233 } // namespace webgpu
234 } // namespace mozilla
236 #endif // WEBGPU_PARENT_H_