Bug 1869043 add a main thread record of track audio outputs r=padenot
[gecko.git] / gfx / wgpu_bindings / src / lib.rs
blob23a205ce7963ad20acc058a718bc07a5204ec1c9
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 use crate::error::ErrorBufferType;
6 use wgc::id;
8 pub use wgc::command::{compute_ffi::*, render_ffi::*};
10 pub mod client;
11 pub mod error;
12 pub mod identity;
13 pub mod server;
15 pub use wgc::device::trace::Command as CommandEncoderAction;
17 use std::marker::PhantomData;
18 use std::{borrow::Cow, mem, slice};
20 use nsstring::nsACString;
22 type RawString = *const std::os::raw::c_char;
24 //TODO: figure out why 'a and 'b have to be different here
25 //TODO: remove this
26 fn cow_label<'a, 'b>(raw: &'a RawString) -> Option<Cow<'b, str>> {
27     if raw.is_null() {
28         None
29     } else {
30         let cstr = unsafe { std::ffi::CStr::from_ptr(*raw) };
31         cstr.to_str().ok().map(Cow::Borrowed)
32     }
35 // Hides the repeated boilerplate of turning a `Option<&nsACString>` into a `Option<Cow<str>`.
36 pub fn wgpu_string(gecko_string: Option<&nsACString>) -> Option<Cow<str>> {
37     gecko_string.map(|s| s.to_utf8())
40 /// An equivalent of `&[T]` for ffi structures and function parameters.
41 #[repr(C)]
42 pub struct FfiSlice<'a, T> {
43     // `data` may be null.
44     pub data: *const T,
45     pub length: usize,
46     pub _marker: PhantomData<&'a T>,
49 impl<'a, T> FfiSlice<'a, T> {
50     pub unsafe fn as_slice(&self) -> &'a [T] {
51         if self.data.is_null() {
52             // It is invalid to construct a rust slice with a null pointer.
53             return &[];
54         }
56         std::slice::from_raw_parts(self.data, self.length)
57     }
60 impl<'a, T> Copy for FfiSlice<'a, T> {}
61 impl<'a, T> Clone for FfiSlice<'a, T> {
62     fn clone(&self) -> Self {
63         *self
64     }
67 #[repr(C)]
68 pub struct ByteBuf {
69     data: *const u8,
70     len: usize,
71     capacity: usize,
74 impl ByteBuf {
75     fn from_vec(vec: Vec<u8>) -> Self {
76         if vec.is_empty() {
77             ByteBuf {
78                 data: std::ptr::null(),
79                 len: 0,
80                 capacity: 0,
81             }
82         } else {
83             let bb = ByteBuf {
84                 data: vec.as_ptr(),
85                 len: vec.len(),
86                 capacity: vec.capacity(),
87             };
88             mem::forget(vec);
89             bb
90         }
91     }
93     unsafe fn as_slice(&self) -> &[u8] {
94         slice::from_raw_parts(self.data, self.len)
95     }
98 #[repr(C)]
99 #[derive(serde::Serialize, serde::Deserialize)]
100 pub struct AdapterInformation<S> {
101     id: id::AdapterId,
102     limits: wgt::Limits,
103     features: wgt::Features,
104     name: S,
105     vendor: u32,
106     device: u32,
107     device_type: wgt::DeviceType,
108     driver: S,
109     driver_info: S,
110     backend: wgt::Backend,
113 #[derive(serde::Serialize, serde::Deserialize)]
114 struct ImplicitLayout<'a> {
115     pipeline: id::PipelineLayoutId,
116     bind_groups: Cow<'a, [id::BindGroupLayoutId]>,
119 #[derive(serde::Serialize, serde::Deserialize)]
120 enum DeviceAction<'a> {
121     CreateTexture(
122         id::TextureId,
123         wgc::resource::TextureDescriptor<'a>,
124         Option<SwapChainId>,
125     ),
126     CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
127     CreateBindGroupLayout(
128         id::BindGroupLayoutId,
129         wgc::binding_model::BindGroupLayoutDescriptor<'a>,
130     ),
131     RenderPipelineGetBindGroupLayout(id::RenderPipelineId, u32, id::BindGroupLayoutId),
132     ComputePipelineGetBindGroupLayout(id::ComputePipelineId, u32, id::BindGroupLayoutId),
133     CreatePipelineLayout(
134         id::PipelineLayoutId,
135         wgc::binding_model::PipelineLayoutDescriptor<'a>,
136     ),
137     CreateBindGroup(id::BindGroupId, wgc::binding_model::BindGroupDescriptor<'a>),
138     CreateShaderModule(
139         id::ShaderModuleId,
140         wgc::pipeline::ShaderModuleDescriptor<'a>,
141         Cow<'a, str>,
142     ),
143     CreateComputePipeline(
144         id::ComputePipelineId,
145         wgc::pipeline::ComputePipelineDescriptor<'a>,
146         Option<ImplicitLayout<'a>>,
147     ),
148     CreateRenderPipeline(
149         id::RenderPipelineId,
150         wgc::pipeline::RenderPipelineDescriptor<'a>,
151         Option<ImplicitLayout<'a>>,
152     ),
153     CreateRenderBundle(
154         id::RenderBundleId,
155         wgc::command::RenderBundleEncoder,
156         wgc::command::RenderBundleDescriptor<'a>,
157     ),
158     CreateRenderBundleError(id::RenderBundleId, wgc::Label<'a>),
159     CreateCommandEncoder(
160         id::CommandEncoderId,
161         wgt::CommandEncoderDescriptor<wgc::Label<'a>>,
162     ),
163     Error {
164         message: String,
165         r#type: ErrorBufferType,
166     },
169 #[derive(serde::Serialize, serde::Deserialize)]
170 enum QueueWriteAction {
171     Buffer {
172         dst: id::BufferId,
173         offset: wgt::BufferAddress,
174     },
175     Texture {
176         dst: wgt::ImageCopyTexture<id::TextureId>,
177         layout: wgt::ImageDataLayout,
178         size: wgt::Extent3d,
179     },
182 #[derive(serde::Serialize, serde::Deserialize)]
183 enum TextureAction<'a> {
184     CreateView(id::TextureViewId, wgc::resource::TextureViewDescriptor<'a>),
187 #[repr(C)]
188 #[derive(serde::Serialize, serde::Deserialize)]
189 enum DropAction {
190     Adapter(id::AdapterId),
191     Device(id::DeviceId),
192     ShaderModule(id::ShaderModuleId),
193     PipelineLayout(id::PipelineLayoutId),
194     BindGroupLayout(id::BindGroupLayoutId),
195     BindGroup(id::BindGroupId),
196     CommandBuffer(id::CommandBufferId),
197     RenderBundle(id::RenderBundleId),
198     RenderPipeline(id::RenderPipelineId),
199     ComputePipeline(id::ComputePipelineId),
200     Buffer(id::BufferId),
201     Texture(id::TextureId),
202     TextureView(id::TextureViewId),
203     Sampler(id::SamplerId),
206 impl DropAction {
207     // helper function to construct byte bufs
208     fn to_byte_buf(&self) -> ByteBuf {
209         let mut data = Vec::new();
210         bincode::serialize_into(&mut data, self).unwrap();
211         ByteBuf::from_vec(data)
212     }
215 #[repr(C)]
216 pub struct ImageDataLayout<'a> {
217     pub offset: wgt::BufferAddress,
218     pub bytes_per_row: Option<&'a u32>,
219     pub rows_per_image: Option<&'a u32>,
222 impl<'a> ImageDataLayout<'a> {
223     fn into_wgt(&self) -> wgt::ImageDataLayout {
224         wgt::ImageDataLayout {
225             offset: self.offset,
226             bytes_per_row: self.bytes_per_row.map(|bpr| *bpr),
227             rows_per_image: self.rows_per_image.map(|rpi| *rpi),
228         }
229     }
232 #[repr(C)]
233 #[derive(Copy, Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
234 pub struct SwapChainId(pub u64);