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"
22 class RemoteTextureOwnerClient
;
28 class ExternalTexture
;
29 class PresentationData
;
31 // Destroy/Drop messages:
32 // - Messages with "Destroy" in their name request deallocation of resources
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.
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
44 class WebGPUParent final
: public PWebGPUParent
, public SupportsWeakPtr
{
45 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebGPUParent
, override
)
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
,
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.
141 uint64_t mMappedOffset
;
142 uint64_t mMappedSize
;
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
);
171 static void MapCallback(ffi::WGPUBufferMapAsyncStatus aStatus
,
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
>>
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
225 struct DeviceLostRequest
{
226 WeakPtr
<WebGPUParent
> mParent
;
229 std::unordered_map
<RawId
, std::unique_ptr
<DeviceLostRequest
>>
233 } // namespace webgpu
234 } // namespace mozilla
236 #endif // WEBGPU_PARENT_H_