mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
webgpu: leverage routed_promise in calls returning promises (#35859)
Using the RoutedPromiseListener let us define a different response type for each promise. This removes unreachable branches that used to exist when they all shared the same WebGPUResponse. Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
4814cbdb1f
commit
1c9f486f88
15 changed files with 221 additions and 263 deletions
|
@ -157,7 +157,7 @@ use style_traits::CSSPixel;
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use webgpu::swapchain::WGPUImageMap;
|
use webgpu::swapchain::WGPUImageMap;
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use webgpu::{self, WebGPU, WebGPURequest, WebGPUResponse};
|
use webgpu::{self, WebGPU, WebGPURequest};
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use webrender::RenderApi;
|
use webrender::RenderApi;
|
||||||
use webrender::RenderApiSender;
|
use webrender::RenderApiSender;
|
||||||
|
@ -1936,7 +1936,7 @@ where
|
||||||
FromScriptMsg::RequestAdapter(response_sender, options, adapter_id) => {
|
FromScriptMsg::RequestAdapter(response_sender, options, adapter_id) => {
|
||||||
match webgpu_chan {
|
match webgpu_chan {
|
||||||
None => {
|
None => {
|
||||||
if let Err(e) = response_sender.send(WebGPUResponse::None) {
|
if let Err(e) = response_sender.send(None) {
|
||||||
warn!("Failed to send request adapter message: {}", e)
|
warn!("Failed to send request adapter message: {}", e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,11 +52,8 @@ impl ServoInternalsMethods<crate::DomTypeHolder> for ServoInternals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoutedPromiseListener for ServoInternals {
|
impl RoutedPromiseListener<MemoryReportResult> for ServoInternals {
|
||||||
type Response = MemoryReportResult;
|
fn handle_response(&self, response: MemoryReportResult, promise: &Rc<Promise>, can_gc: CanGc) {
|
||||||
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
|
||||||
fn handle_response(&self, response: Self::Response, promise: &Rc<Promise>, can_gc: CanGc) {
|
|
||||||
promise.resolve_native(&response.content, can_gc);
|
promise.resolve_native(&response.content, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,26 +5,24 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
|
||||||
use ipc_channel::router::ROUTER;
|
|
||||||
use js::jsapi::Heap;
|
use js::jsapi::Heap;
|
||||||
use script_traits::ScriptMsg;
|
use script_traits::ScriptMsg;
|
||||||
use webgpu::wgt::PowerPreference;
|
use webgpu::wgt::PowerPreference;
|
||||||
use webgpu::{WebGPUResponse, wgc};
|
use webgpu::{WebGPUAdapterResponse, wgc};
|
||||||
|
|
||||||
use super::wgsllanguagefeatures::WGSLLanguageFeatures;
|
use super::wgsllanguagefeatures::WGSLLanguageFeatures;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
GPUMethods, GPUPowerPreference, GPURequestAdapterOptions, GPUTextureFormat,
|
GPUMethods, GPUPowerPreference, GPURequestAdapterOptions, GPUTextureFormat,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::Error;
|
use crate::dom::bindings::error::Error;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||||
use crate::dom::bindings::reflector::{DomGlobal, DomObject, Reflector, reflect_dom_object};
|
|
||||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::webgpu::gpuadapter::GPUAdapter;
|
use crate::dom::webgpu::gpuadapter::GPUAdapter;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -48,59 +46,6 @@ impl GPU {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait AsyncWGPUListener {
|
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WGPUResponse<T: AsyncWGPUListener + DomObject> {
|
|
||||||
trusted: TrustedPromise,
|
|
||||||
receiver: Trusted<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsyncWGPUListener + DomObject> WGPUResponse<T> {
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
|
||||||
fn response(self, response: WebGPUResponse, can_gc: CanGc) {
|
|
||||||
let promise = self.trusted.root();
|
|
||||||
self.receiver
|
|
||||||
.root()
|
|
||||||
.handle_response(response, &promise, can_gc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn response_async<T: AsyncWGPUListener + DomObject + 'static>(
|
|
||||||
promise: &Rc<Promise>,
|
|
||||||
receiver: &T,
|
|
||||||
) -> IpcSender<WebGPUResponse> {
|
|
||||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
|
||||||
let task_source = receiver
|
|
||||||
.global()
|
|
||||||
.task_manager()
|
|
||||||
.dom_manipulation_task_source()
|
|
||||||
.to_sendable();
|
|
||||||
let mut trusted: Option<TrustedPromise> = Some(TrustedPromise::new(promise.clone()));
|
|
||||||
let trusted_receiver = Trusted::new(receiver);
|
|
||||||
ROUTER.add_typed_route(
|
|
||||||
action_receiver,
|
|
||||||
Box::new(move |message| {
|
|
||||||
let trusted = if let Some(trusted) = trusted.take() {
|
|
||||||
trusted
|
|
||||||
} else {
|
|
||||||
error!("WebGPU callback called twice!");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let context = WGPUResponse {
|
|
||||||
trusted,
|
|
||||||
receiver: trusted_receiver.clone(),
|
|
||||||
};
|
|
||||||
task_source.queue(task!(process_webgpu_task: move|| {
|
|
||||||
context.response(message.unwrap(), CanGc::note());
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
action_sender
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GPUMethods<crate::DomTypeHolder> for GPU {
|
impl GPUMethods<crate::DomTypeHolder> for GPU {
|
||||||
// https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter
|
// https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter
|
||||||
fn RequestAdapter(
|
fn RequestAdapter(
|
||||||
|
@ -111,7 +56,7 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
let global = &self.global();
|
let global = &self.global();
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
let power_preference = match options.powerPreference {
|
let power_preference = match options.powerPreference {
|
||||||
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,
|
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,
|
||||||
Some(GPUPowerPreference::High_performance) => PowerPreference::HighPerformance,
|
Some(GPUPowerPreference::High_performance) => PowerPreference::HighPerformance,
|
||||||
|
@ -150,10 +95,15 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPU {
|
impl RoutedPromiseListener<WebGPUAdapterResponse> for GPU {
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
response: WebGPUAdapterResponse,
|
||||||
|
promise: &Rc<Promise>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
match response {
|
match response {
|
||||||
WebGPUResponse::Adapter(Ok(adapter)) => {
|
Some(Ok(adapter)) => {
|
||||||
let adapter = GPUAdapter::new(
|
let adapter = GPUAdapter::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
adapter.channel,
|
adapter.channel,
|
||||||
|
@ -170,15 +120,14 @@ impl AsyncWGPUListener for GPU {
|
||||||
);
|
);
|
||||||
promise.resolve_native(&adapter, can_gc);
|
promise.resolve_native(&adapter, can_gc);
|
||||||
},
|
},
|
||||||
WebGPUResponse::Adapter(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
warn!("Could not get GPUAdapter ({:?})", e);
|
warn!("Could not get GPUAdapter ({:?})", e);
|
||||||
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
||||||
},
|
},
|
||||||
WebGPUResponse::None => {
|
None => {
|
||||||
warn!("Couldn't get a response, because WebGPU is disabled");
|
warn!("Couldn't get a response, because WebGPU is disabled");
|
||||||
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
||||||
},
|
},
|
||||||
_ => unreachable!("GPU received wrong WebGPUResponse"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom_struct::dom_struct;
|
||||||
use js::jsapi::{Heap, JSObject};
|
use js::jsapi::{Heap, JSObject};
|
||||||
use webgpu::wgc::instance::RequestDeviceError;
|
use webgpu::wgc::instance::RequestDeviceError;
|
||||||
use webgpu::wgt::MemoryHints;
|
use webgpu::wgt::MemoryHints;
|
||||||
use webgpu::{WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, wgt};
|
use webgpu::{WebGPU, WebGPUAdapter, WebGPUDeviceResponse, WebGPURequest, wgt};
|
||||||
|
|
||||||
use super::gpusupportedfeatures::GPUSupportedFeatures;
|
use super::gpusupportedfeatures::GPUSupportedFeatures;
|
||||||
use super::gpusupportedlimits::set_limit;
|
use super::gpusupportedlimits::set_limit;
|
||||||
|
@ -22,10 +22,10 @@ use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::types::{GPUAdapterInfo, GPUSupportedLimits};
|
use crate::dom::types::{GPUAdapterInfo, GPUSupportedLimits};
|
||||||
use crate::dom::webgpu::gpu::{AsyncWGPUListener, response_async};
|
|
||||||
use crate::dom::webgpu::gpudevice::GPUDevice;
|
use crate::dom::webgpu::gpudevice::GPUDevice;
|
||||||
use crate::dom::webgpu::gpusupportedfeatures::gpu_to_wgt_feature;
|
use crate::dom::webgpu::gpusupportedfeatures::gpu_to_wgt_feature;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -116,7 +116,7 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
// Step 2
|
// Step 2
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
let mut required_features = wgt::Features::empty();
|
let mut required_features = wgt::Features::empty();
|
||||||
for &ext in descriptor.requiredFeatures.iter() {
|
for &ext in descriptor.requiredFeatures.iter() {
|
||||||
if let Some(feature) = gpu_to_wgt_feature(ext) {
|
if let Some(feature) = gpu_to_wgt_feature(ext) {
|
||||||
|
@ -205,10 +205,15 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPUAdapter {
|
impl RoutedPromiseListener<WebGPUDeviceResponse> for GPUAdapter {
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
response: WebGPUDeviceResponse,
|
||||||
|
promise: &Rc<Promise>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
match response {
|
match response {
|
||||||
WebGPUResponse::Device((device_id, queue_id, Ok(descriptor))) => {
|
(device_id, queue_id, Ok(descriptor)) => {
|
||||||
let device = GPUDevice::new(
|
let device = GPUDevice::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
self.channel.clone(),
|
self.channel.clone(),
|
||||||
|
@ -224,16 +229,14 @@ impl AsyncWGPUListener for GPUAdapter {
|
||||||
self.global().add_gpu_device(&device);
|
self.global().add_gpu_device(&device);
|
||||||
promise.resolve_native(&device, can_gc);
|
promise.resolve_native(&device, can_gc);
|
||||||
},
|
},
|
||||||
WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => {
|
(_, _, Err(RequestDeviceError::UnsupportedFeature(f))) => promise.reject_error(
|
||||||
promise.reject_error(
|
Error::Type(RequestDeviceError::UnsupportedFeature(f).to_string()),
|
||||||
Error::Type(RequestDeviceError::UnsupportedFeature(f).to_string()),
|
can_gc,
|
||||||
can_gc,
|
),
|
||||||
)
|
(_, _, Err(RequestDeviceError::LimitsExceeded(_))) => {
|
||||||
},
|
|
||||||
WebGPUResponse::Device((_, _, Err(RequestDeviceError::LimitsExceeded(_)))) => {
|
|
||||||
promise.reject_error(Error::Operation, can_gc)
|
promise.reject_error(Error::Operation, can_gc)
|
||||||
},
|
},
|
||||||
WebGPUResponse::Device((device_id, queue_id, Err(e))) => {
|
(device_id, queue_id, Err(e)) => {
|
||||||
let device = GPUDevice::new(
|
let device = GPUDevice::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
self.channel.clone(),
|
self.channel.clone(),
|
||||||
|
@ -249,8 +252,6 @@ impl AsyncWGPUListener for GPUAdapter {
|
||||||
device.lose(GPUDeviceLostReason::Unknown, e.to_string(), can_gc);
|
device.lose(GPUDeviceLostReason::Unknown, e.to_string(), can_gc);
|
||||||
promise.resolve_native(&device, can_gc);
|
promise.resolve_native(&device, can_gc);
|
||||||
},
|
},
|
||||||
WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"),
|
|
||||||
_ => unreachable!("GPUAdapter received wrong WebGPUResponse"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSharedMemory;
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
use js::typedarray::ArrayBuffer;
|
use js::typedarray::ArrayBuffer;
|
||||||
use webgpu::wgc::device::HostMap;
|
use webgpu::wgc::device::HostMap;
|
||||||
use webgpu::{Mapping, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse, wgt};
|
use webgpu::{Mapping, WebGPU, WebGPUBuffer, WebGPURequest, wgc, wgt};
|
||||||
|
use wgc::resource::BufferAccessError;
|
||||||
|
|
||||||
use crate::conversions::Convert;
|
use crate::conversions::Convert;
|
||||||
use crate::dom::bindings::buffer_source::DataBlock;
|
use crate::dom::bindings::buffer_source::DataBlock;
|
||||||
|
@ -25,9 +26,9 @@ use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::str::USVString;
|
use crate::dom::bindings::str::USVString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::webgpu::gpu::{AsyncWGPUListener, response_async};
|
|
||||||
use crate::dom::webgpu::gpudevice::GPUDevice;
|
use crate::dom::webgpu::gpudevice::GPUDevice;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::{CanGc, JSContext};
|
use crate::script_runtime::{CanGc, JSContext};
|
||||||
|
|
||||||
#[derive(JSTraceable, MallocSizeOf)]
|
#[derive(JSTraceable, MallocSizeOf)]
|
||||||
|
@ -270,7 +271,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync {
|
if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync {
|
||||||
sender,
|
sender,
|
||||||
buffer_id: self.buffer.0,
|
buffer_id: self.buffer.0,
|
||||||
|
@ -419,15 +420,16 @@ impl GPUBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPUBuffer {
|
impl RoutedPromiseListener<Result<Mapping, BufferAccessError>> for GPUBuffer {
|
||||||
#[allow(unsafe_code)]
|
fn handle_response(
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
&self,
|
||||||
|
response: Result<Mapping, BufferAccessError>,
|
||||||
|
promise: &Rc<Promise>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
match response {
|
match response {
|
||||||
WebGPUResponse::BufferMapAsync(Ok(mapping)) => {
|
Ok(mapping) => self.map_success(promise, mapping, can_gc),
|
||||||
self.map_success(promise, mapping, can_gc)
|
Err(_) => self.map_failure(promise, can_gc),
|
||||||
},
|
|
||||||
WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise, can_gc),
|
|
||||||
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUBuffer"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use webgpu::wgc::pipeline::ComputePipelineDescriptor;
|
use webgpu::wgc::pipeline::ComputePipelineDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPURequest, WebGPUResponse};
|
use webgpu::{
|
||||||
|
WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPUComputePipelineResponse,
|
||||||
|
WebGPURequest,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::conversions::Convert;
|
use crate::conversions::Convert;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
|
@ -76,7 +79,7 @@ impl GPUComputePipeline {
|
||||||
pub(crate) fn create(
|
pub(crate) fn create(
|
||||||
device: &GPUDevice,
|
device: &GPUDevice,
|
||||||
descriptor: &GPUComputePipelineDescriptor,
|
descriptor: &GPUComputePipelineDescriptor,
|
||||||
async_sender: Option<IpcSender<WebGPUResponse>>,
|
async_sender: Option<IpcSender<WebGPUComputePipelineResponse>>,
|
||||||
) -> WebGPUComputePipeline {
|
) -> WebGPUComputePipeline {
|
||||||
let compute_pipeline_id = device.global().wgpu_id_hub().create_compute_pipeline_id();
|
let compute_pipeline_id = device.global().wgpu_id_hub().create_compute_pipeline_id();
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@ use webgpu::wgc::pipeline as wgpu_pipe;
|
||||||
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
||||||
use webgpu::wgt::TextureFormat;
|
use webgpu::wgt::TextureFormat;
|
||||||
use webgpu::{
|
use webgpu::{
|
||||||
PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest, WebGPUResponse,
|
PopError, WebGPU, WebGPUComputePipeline, WebGPUComputePipelineResponse,
|
||||||
wgt,
|
WebGPUPoppedErrorScopeResponse, WebGPURenderPipeline, WebGPURenderPipelineResponse,
|
||||||
|
WebGPURequest, wgt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::gpu::AsyncWGPUListener;
|
|
||||||
use super::gpudevicelostinfo::GPUDeviceLostInfo;
|
use super::gpudevicelostinfo::GPUDeviceLostInfo;
|
||||||
use super::gpuerror::AsWebGpu;
|
use super::gpuerror::AsWebGpu;
|
||||||
use super::gpupipelineerror::GPUPipelineError;
|
use super::gpupipelineerror::GPUPipelineError;
|
||||||
|
@ -46,7 +46,6 @@ use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::types::GPUError;
|
use crate::dom::types::GPUError;
|
||||||
use crate::dom::webgpu::gpu::response_async;
|
|
||||||
use crate::dom::webgpu::gpuadapter::GPUAdapter;
|
use crate::dom::webgpu::gpuadapter::GPUAdapter;
|
||||||
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
|
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
|
||||||
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
|
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
|
||||||
|
@ -63,6 +62,7 @@ use crate::dom::webgpu::gpusupportedfeatures::GPUSupportedFeatures;
|
||||||
use crate::dom::webgpu::gputexture::GPUTexture;
|
use crate::dom::webgpu::gputexture::GPUTexture;
|
||||||
use crate::dom::webgpu::gpuuncapturederrorevent::GPUUncapturedErrorEvent;
|
use crate::dom::webgpu::gpuuncapturederrorevent::GPUUncapturedErrorEvent;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -469,7 +469,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
GPUComputePipeline::create(self, descriptor, Some(sender));
|
GPUComputePipeline::create(self, descriptor, Some(sender));
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
|
||||||
) -> Fallible<Rc<Promise>> {
|
) -> Fallible<Rc<Promise>> {
|
||||||
let (implicit_ids, desc) = self.parse_render_pipeline(descriptor)?;
|
let (implicit_ids, desc) = self.parse_render_pipeline(descriptor)?;
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?;
|
GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?;
|
||||||
Ok(promise)
|
Ok(promise)
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
|
||||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope>
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope>
|
||||||
fn PopErrorScope(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
|
fn PopErrorScope(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
|
||||||
let promise = Promise::new_in_current_realm(comp, can_gc);
|
let promise = Promise::new_in_current_realm(comp, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
if self
|
if self
|
||||||
.channel
|
.channel
|
||||||
.0
|
.0
|
||||||
|
@ -582,82 +582,104 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPUDevice {
|
impl RoutedPromiseListener<WebGPUPoppedErrorScopeResponse> for GPUDevice {
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
response: WebGPUPoppedErrorScopeResponse,
|
||||||
|
promise: &Rc<Promise>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
match response {
|
match response {
|
||||||
WebGPUResponse::PoppedErrorScope(result) => match result {
|
Ok(None) | Err(PopError::Lost) => {
|
||||||
Ok(None) | Err(PopError::Lost) => {
|
promise.resolve_native(&None::<Option<GPUError>>, can_gc)
|
||||||
promise.resolve_native(&None::<Option<GPUError>>, can_gc)
|
|
||||||
},
|
|
||||||
Err(PopError::Empty) => promise.reject_error(Error::Operation, can_gc),
|
|
||||||
Ok(Some(error)) => {
|
|
||||||
let error = GPUError::from_error(&self.global(), error, can_gc);
|
|
||||||
promise.resolve_native(&error, can_gc);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
WebGPUResponse::ComputePipeline(result) => match result {
|
Err(PopError::Empty) => promise.reject_error(Error::Operation, can_gc),
|
||||||
Ok(pipeline) => promise.resolve_native(
|
Ok(Some(error)) => {
|
||||||
&GPUComputePipeline::new(
|
let error = GPUError::from_error(&self.global(), error, can_gc);
|
||||||
&self.global(),
|
promise.resolve_native(&error, can_gc);
|
||||||
WebGPUComputePipeline(pipeline.id),
|
},
|
||||||
pipeline.label.into(),
|
}
|
||||||
self,
|
}
|
||||||
can_gc,
|
}
|
||||||
),
|
|
||||||
|
impl RoutedPromiseListener<WebGPUComputePipelineResponse> for GPUDevice {
|
||||||
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
response: WebGPUComputePipelineResponse,
|
||||||
|
promise: &Rc<Promise>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
|
match response {
|
||||||
|
Ok(pipeline) => promise.resolve_native(
|
||||||
|
&GPUComputePipeline::new(
|
||||||
|
&self.global(),
|
||||||
|
WebGPUComputePipeline(pipeline.id),
|
||||||
|
pipeline.label.into(),
|
||||||
|
self,
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
Err(webgpu::Error::Validation(msg)) => promise.reject_native(
|
can_gc,
|
||||||
|
),
|
||||||
|
Err(webgpu::Error::Validation(msg)) => promise.reject_native(
|
||||||
|
&GPUPipelineError::new(
|
||||||
|
&self.global(),
|
||||||
|
msg.into(),
|
||||||
|
GPUPipelineErrorReason::Validation,
|
||||||
|
can_gc,
|
||||||
|
),
|
||||||
|
can_gc,
|
||||||
|
),
|
||||||
|
Err(webgpu::Error::OutOfMemory(msg) | webgpu::Error::Internal(msg)) => promise
|
||||||
|
.reject_native(
|
||||||
&GPUPipelineError::new(
|
&GPUPipelineError::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
msg.into(),
|
msg.into(),
|
||||||
GPUPipelineErrorReason::Validation,
|
GPUPipelineErrorReason::Internal,
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
Err(webgpu::Error::OutOfMemory(msg) | webgpu::Error::Internal(msg)) => promise
|
}
|
||||||
.reject_native(
|
}
|
||||||
&GPUPipelineError::new(
|
}
|
||||||
&self.global(),
|
|
||||||
msg.into(),
|
impl RoutedPromiseListener<WebGPURenderPipelineResponse> for GPUDevice {
|
||||||
GPUPipelineErrorReason::Internal,
|
fn handle_response(
|
||||||
can_gc,
|
&self,
|
||||||
),
|
response: WebGPURenderPipelineResponse,
|
||||||
can_gc,
|
promise: &Rc<Promise>,
|
||||||
),
|
can_gc: CanGc,
|
||||||
},
|
) {
|
||||||
WebGPUResponse::RenderPipeline(result) => match result {
|
match response {
|
||||||
Ok(pipeline) => promise.resolve_native(
|
Ok(pipeline) => promise.resolve_native(
|
||||||
&GPURenderPipeline::new(
|
&GPURenderPipeline::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
WebGPURenderPipeline(pipeline.id),
|
WebGPURenderPipeline(pipeline.id),
|
||||||
pipeline.label.into(),
|
pipeline.label.into(),
|
||||||
self,
|
self,
|
||||||
can_gc,
|
|
||||||
),
|
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
Err(webgpu::Error::Validation(msg)) => promise.reject_native(
|
can_gc,
|
||||||
|
),
|
||||||
|
Err(webgpu::Error::Validation(msg)) => promise.reject_native(
|
||||||
|
&GPUPipelineError::new(
|
||||||
|
&self.global(),
|
||||||
|
msg.into(),
|
||||||
|
GPUPipelineErrorReason::Validation,
|
||||||
|
can_gc,
|
||||||
|
),
|
||||||
|
can_gc,
|
||||||
|
),
|
||||||
|
Err(webgpu::Error::OutOfMemory(msg) | webgpu::Error::Internal(msg)) => promise
|
||||||
|
.reject_native(
|
||||||
&GPUPipelineError::new(
|
&GPUPipelineError::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
msg.into(),
|
msg.into(),
|
||||||
GPUPipelineErrorReason::Validation,
|
GPUPipelineErrorReason::Internal,
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
can_gc,
|
can_gc,
|
||||||
),
|
),
|
||||||
Err(webgpu::Error::OutOfMemory(msg) | webgpu::Error::Internal(msg)) => promise
|
|
||||||
.reject_native(
|
|
||||||
&GPUPipelineError::new(
|
|
||||||
&self.global(),
|
|
||||||
msg.into(),
|
|
||||||
GPUPipelineErrorReason::Internal,
|
|
||||||
can_gc,
|
|
||||||
),
|
|
||||||
can_gc,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUDevice"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSharedMemory;
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
use webgpu::{WebGPU, WebGPUQueue, WebGPURequest, WebGPUResponse, wgt};
|
use webgpu::{WebGPU, WebGPUQueue, WebGPURequest, wgt};
|
||||||
|
|
||||||
use super::gpu::{AsyncWGPUListener, response_async};
|
|
||||||
use crate::conversions::{Convert, TryConvert};
|
use crate::conversions::{Convert, TryConvert};
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
|
@ -24,6 +23,7 @@ use crate::dom::promise::Promise;
|
||||||
use crate::dom::webgpu::gpubuffer::GPUBuffer;
|
use crate::dom::webgpu::gpubuffer::GPUBuffer;
|
||||||
use crate::dom::webgpu::gpucommandbuffer::GPUCommandBuffer;
|
use crate::dom::webgpu::gpucommandbuffer::GPUCommandBuffer;
|
||||||
use crate::dom::webgpu::gpudevice::GPUDevice;
|
use crate::dom::webgpu::gpudevice::GPUDevice;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -200,7 +200,7 @@ impl GPUQueueMethods<crate::DomTypeHolder> for GPUQueue {
|
||||||
fn OnSubmittedWorkDone(&self, can_gc: CanGc) -> Rc<Promise> {
|
fn OnSubmittedWorkDone(&self, can_gc: CanGc) -> Rc<Promise> {
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let promise = Promise::new(&global, can_gc);
|
let promise = Promise::new(&global, can_gc);
|
||||||
let sender = response_async(&promise, self);
|
let sender = route_promise(&promise, self);
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.channel
|
.channel
|
||||||
.0
|
.0
|
||||||
|
@ -215,21 +215,8 @@ impl GPUQueueMethods<crate::DomTypeHolder> for GPUQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPUQueue {
|
impl RoutedPromiseListener<()> for GPUQueue {
|
||||||
fn handle_response(
|
fn handle_response(&self, _response: (), promise: &Rc<Promise>, can_gc: CanGc) {
|
||||||
&self,
|
promise.resolve_native(&(), can_gc);
|
||||||
response: webgpu::WebGPUResponse,
|
|
||||||
promise: &Rc<Promise>,
|
|
||||||
can_gc: CanGc,
|
|
||||||
) {
|
|
||||||
match response {
|
|
||||||
WebGPUResponse::SubmittedWorkDone => {
|
|
||||||
promise.resolve_native(&(), can_gc);
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
warn!("GPUQueue received wrong WebGPUResponse");
|
|
||||||
promise.reject_error(Error::Operation, can_gc);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
||||||
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURequest, WebGPUResponse};
|
use webgpu::{
|
||||||
|
WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURenderPipelineResponse,
|
||||||
|
WebGPURequest,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPURenderPipelineMethods;
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPURenderPipelineMethods;
|
||||||
|
@ -74,7 +77,7 @@ impl GPURenderPipeline {
|
||||||
device: &GPUDevice,
|
device: &GPUDevice,
|
||||||
pipeline_layout: PipelineLayout,
|
pipeline_layout: PipelineLayout,
|
||||||
descriptor: RenderPipelineDescriptor<'static>,
|
descriptor: RenderPipelineDescriptor<'static>,
|
||||||
async_sender: Option<IpcSender<WebGPUResponse>>,
|
async_sender: Option<IpcSender<WebGPURenderPipelineResponse>>,
|
||||||
) -> Fallible<WebGPURenderPipeline> {
|
) -> Fallible<WebGPURenderPipeline> {
|
||||||
let render_pipeline_id = device.global().wgpu_id_hub().create_render_pipeline_id();
|
let render_pipeline_id = device.global().wgpu_id_hub().create_render_pipeline_id();
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webgpu::{WebGPU, WebGPURequest, WebGPUResponse, WebGPUShaderModule};
|
use webgpu::{ShaderCompilationInfo, WebGPU, WebGPURequest, WebGPUShaderModule};
|
||||||
|
|
||||||
use super::gpu::AsyncWGPUListener;
|
|
||||||
use super::gpucompilationinfo::GPUCompilationInfo;
|
use super::gpucompilationinfo::GPUCompilationInfo;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||||
|
@ -20,8 +19,8 @@ use crate::dom::bindings::trace::RootedTraceableBox;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::dom::types::GPUDevice;
|
use crate::dom::types::GPUDevice;
|
||||||
use crate::dom::webgpu::gpu::response_async;
|
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
|
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -96,7 +95,7 @@ impl GPUShaderModule {
|
||||||
promise.clone(),
|
promise.clone(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
let sender = response_async(&promise, &*shader_module);
|
let sender = route_promise(&promise, &*shader_module);
|
||||||
device
|
device
|
||||||
.channel()
|
.channel()
|
||||||
.0
|
.0
|
||||||
|
@ -129,15 +128,15 @@ impl GPUShaderModuleMethods<crate::DomTypeHolder> for GPUShaderModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncWGPUListener for GPUShaderModule {
|
impl RoutedPromiseListener<Option<ShaderCompilationInfo>> for GPUShaderModule {
|
||||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
fn handle_response(
|
||||||
match response {
|
&self,
|
||||||
WebGPUResponse::CompilationInfo(info) => {
|
response: Option<ShaderCompilationInfo>,
|
||||||
let info = GPUCompilationInfo::from(&self.global(), info, can_gc);
|
promise: &Rc<Promise>,
|
||||||
promise.resolve_native(&info, can_gc);
|
can_gc: CanGc,
|
||||||
},
|
) {
|
||||||
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUShaderModule"),
|
let info = GPUCompilationInfo::from(&self.global(), response, can_gc);
|
||||||
}
|
promise.resolve_native(&info, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,20 +14,23 @@ use crate::dom::bindings::reflector::{DomGlobal, DomObject};
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
pub(crate) trait RoutedPromiseListener {
|
pub(crate) trait RoutedPromiseListener<R: Serialize + DeserializeOwned + Send> {
|
||||||
type Response: Serialize + DeserializeOwned + Send;
|
fn handle_response(&self, response: R, promise: &Rc<Promise>, can_gc: CanGc);
|
||||||
|
|
||||||
fn handle_response(&self, response: Self::Response, promise: &Rc<Promise>, can_gc: CanGc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct RoutedPromiseContext<T: RoutedPromiseListener + DomObject> {
|
pub(crate) struct RoutedPromiseContext<
|
||||||
|
R: Serialize + DeserializeOwned + Send,
|
||||||
|
T: RoutedPromiseListener<R> + DomObject,
|
||||||
|
> {
|
||||||
trusted: TrustedPromise,
|
trusted: TrustedPromise,
|
||||||
receiver: Trusted<T>,
|
receiver: Trusted<T>,
|
||||||
|
_phantom: std::marker::PhantomData<R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RoutedPromiseListener + DomObject> RoutedPromiseContext<T> {
|
impl<R: Serialize + DeserializeOwned + Send, T: RoutedPromiseListener<R> + DomObject>
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
RoutedPromiseContext<R, T>
|
||||||
fn response(self, response: T::Response, can_gc: CanGc) {
|
{
|
||||||
|
fn response(self, response: R, can_gc: CanGc) {
|
||||||
let promise = self.trusted.root();
|
let promise = self.trusted.root();
|
||||||
self.receiver
|
self.receiver
|
||||||
.root()
|
.root()
|
||||||
|
@ -35,10 +38,13 @@ impl<T: RoutedPromiseListener + DomObject> RoutedPromiseContext<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn route_promise<T: RoutedPromiseListener + DomObject + 'static>(
|
pub(crate) fn route_promise<
|
||||||
|
R: Serialize + DeserializeOwned + Send + 'static,
|
||||||
|
T: RoutedPromiseListener<R> + DomObject + 'static,
|
||||||
|
>(
|
||||||
promise: &Rc<Promise>,
|
promise: &Rc<Promise>,
|
||||||
receiver: &T,
|
receiver: &T,
|
||||||
) -> IpcSender<T::Response> {
|
) -> IpcSender<R> {
|
||||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let task_source = receiver
|
let task_source = receiver
|
||||||
.global()
|
.global()
|
||||||
|
@ -60,6 +66,7 @@ pub(crate) fn route_promise<T: RoutedPromiseListener + DomObject + 'static>(
|
||||||
let context = RoutedPromiseContext {
|
let context = RoutedPromiseContext {
|
||||||
trusted,
|
trusted,
|
||||||
receiver: trusted_receiver.clone(),
|
receiver: trusted_receiver.clone(),
|
||||||
|
_phantom: Default::default(),
|
||||||
};
|
};
|
||||||
task_source.queue(task!(routed_promise_task: move|| {
|
task_source.queue(task!(routed_promise_task: move|| {
|
||||||
context.response(message.unwrap(), CanGc::note());
|
context.response(message.unwrap(), CanGc::note());
|
||||||
|
|
|
@ -24,7 +24,7 @@ use servo_url::{ImmutableOrigin, ServoUrl};
|
||||||
use strum_macros::IntoStaticStr;
|
use strum_macros::IntoStaticStr;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use webgpu::{WebGPU, WebGPUResponse, wgc};
|
use webgpu::{WebGPU, WebGPUAdapterResponse, wgc};
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
|
|
||||||
use crate::mem::MemoryReportResult;
|
use crate::mem::MemoryReportResult;
|
||||||
|
@ -204,7 +204,7 @@ pub enum ScriptMsg {
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
/// Create a WebGPU Adapter instance
|
/// Create a WebGPU Adapter instance
|
||||||
RequestAdapter(
|
RequestAdapter(
|
||||||
IpcSender<WebGPUResponse>,
|
IpcSender<WebGPUAdapterResponse>,
|
||||||
wgc::instance::RequestAdapterOptions,
|
wgc::instance::RequestAdapterOptions,
|
||||||
wgc::id::AdapterId,
|
wgc::id::AdapterId,
|
||||||
),
|
),
|
||||||
|
|
|
@ -32,7 +32,12 @@ pub use {wgpu_core as wgc, wgpu_types as wgt};
|
||||||
use crate::identity::*;
|
use crate::identity::*;
|
||||||
use crate::render_commands::RenderCommand;
|
use crate::render_commands::RenderCommand;
|
||||||
use crate::swapchain::WebGPUContextId;
|
use crate::swapchain::WebGPUContextId;
|
||||||
use crate::{Error, ErrorFilter, Mapping, PRESENTATION_BUFFER_COUNT, WebGPUResponse};
|
use crate::wgc::resource::BufferAccessError;
|
||||||
|
use crate::{
|
||||||
|
Error, ErrorFilter, Mapping, PRESENTATION_BUFFER_COUNT, ShaderCompilationInfo,
|
||||||
|
WebGPUAdapterResponse, WebGPUComputePipelineResponse, WebGPUDeviceResponse,
|
||||||
|
WebGPUPoppedErrorScopeResponse, WebGPURenderPipelineResponse,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||||
pub struct ContextConfiguration {
|
pub struct ContextConfiguration {
|
||||||
|
@ -45,7 +50,7 @@ pub struct ContextConfiguration {
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub enum WebGPURequest {
|
pub enum WebGPURequest {
|
||||||
BufferMapAsync {
|
BufferMapAsync {
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<Result<Mapping, BufferAccessError>>,
|
||||||
buffer_id: id::BufferId,
|
buffer_id: id::BufferId,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
host_map: HostMap,
|
host_map: HostMap,
|
||||||
|
@ -109,7 +114,7 @@ pub enum WebGPURequest {
|
||||||
descriptor: ComputePipelineDescriptor<'static>,
|
descriptor: ComputePipelineDescriptor<'static>,
|
||||||
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
||||||
/// present only on ASYNC versions
|
/// present only on ASYNC versions
|
||||||
async_sender: Option<IpcSender<WebGPUResponse>>,
|
async_sender: Option<IpcSender<WebGPUComputePipelineResponse>>,
|
||||||
},
|
},
|
||||||
CreatePipelineLayout {
|
CreatePipelineLayout {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
@ -122,7 +127,7 @@ pub enum WebGPURequest {
|
||||||
descriptor: RenderPipelineDescriptor<'static>,
|
descriptor: RenderPipelineDescriptor<'static>,
|
||||||
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
implicit_ids: Option<(id::PipelineLayoutId, Vec<id::BindGroupLayoutId>)>,
|
||||||
/// present only on ASYNC versions
|
/// present only on ASYNC versions
|
||||||
async_sender: Option<IpcSender<WebGPUResponse>>,
|
async_sender: Option<IpcSender<WebGPURenderPipelineResponse>>,
|
||||||
},
|
},
|
||||||
CreateSampler {
|
CreateSampler {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
@ -134,7 +139,7 @@ pub enum WebGPURequest {
|
||||||
program_id: id::ShaderModuleId,
|
program_id: id::ShaderModuleId,
|
||||||
program: String,
|
program: String,
|
||||||
label: Option<String>,
|
label: Option<String>,
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<Option<ShaderCompilationInfo>>,
|
||||||
},
|
},
|
||||||
/// Creates context
|
/// Creates context
|
||||||
CreateContext {
|
CreateContext {
|
||||||
|
@ -206,12 +211,12 @@ pub enum WebGPURequest {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
},
|
},
|
||||||
RequestAdapter {
|
RequestAdapter {
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<WebGPUAdapterResponse>,
|
||||||
options: RequestAdapterOptions,
|
options: RequestAdapterOptions,
|
||||||
adapter_id: AdapterId,
|
adapter_id: AdapterId,
|
||||||
},
|
},
|
||||||
RequestDevice {
|
RequestDevice {
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<WebGPUDeviceResponse>,
|
||||||
adapter_id: WebGPUAdapter,
|
adapter_id: WebGPUAdapter,
|
||||||
descriptor: wgt::DeviceDescriptor<Option<String>>,
|
descriptor: wgt::DeviceDescriptor<Option<String>>,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
@ -300,7 +305,7 @@ pub enum WebGPURequest {
|
||||||
data: IpcSharedMemory,
|
data: IpcSharedMemory,
|
||||||
},
|
},
|
||||||
QueueOnSubmittedWorkDone {
|
QueueOnSubmittedWorkDone {
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<()>,
|
||||||
queue_id: id::QueueId,
|
queue_id: id::QueueId,
|
||||||
},
|
},
|
||||||
PushErrorScope {
|
PushErrorScope {
|
||||||
|
@ -313,7 +318,7 @@ pub enum WebGPURequest {
|
||||||
},
|
},
|
||||||
PopErrorScope {
|
PopErrorScope {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
sender: IpcSender<WebGPUResponse>,
|
sender: IpcSender<WebGPUPoppedErrorScopeResponse>,
|
||||||
},
|
},
|
||||||
ComputeGetBindGroupLayout {
|
ComputeGetBindGroupLayout {
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
|
|
|
@ -12,7 +12,6 @@ use wgc::id;
|
||||||
use wgc::pipeline::CreateShaderModuleError;
|
use wgc::pipeline::CreateShaderModuleError;
|
||||||
use wgpu_core::device::HostMap;
|
use wgpu_core::device::HostMap;
|
||||||
use wgpu_core::instance::{RequestAdapterError, RequestDeviceError};
|
use wgpu_core::instance::{RequestAdapterError, RequestDeviceError};
|
||||||
use wgpu_core::resource::BufferAccessError;
|
|
||||||
pub use {wgpu_core as wgc, wgpu_types as wgt};
|
pub use {wgpu_core as wgc, wgpu_types as wgt};
|
||||||
|
|
||||||
use crate::identity::*;
|
use crate::identity::*;
|
||||||
|
@ -82,23 +81,14 @@ pub struct Mapping {
|
||||||
pub range: Range<u64>,
|
pub range: Range<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
pub type WebGPUDeviceResponse = (
|
||||||
#[allow(clippy::large_enum_variant)]
|
WebGPUDevice,
|
||||||
pub enum WebGPUResponse {
|
WebGPUQueue,
|
||||||
/// WebGPU is disabled
|
Result<wgt::DeviceDescriptor<Option<String>>, RequestDeviceError>,
|
||||||
None,
|
);
|
||||||
Adapter(Result<Adapter, RequestAdapterError>),
|
|
||||||
Device(
|
pub type WebGPUAdapterResponse = Option<Result<Adapter, RequestAdapterError>>;
|
||||||
(
|
|
||||||
WebGPUDevice,
|
pub type WebGPUPoppedErrorScopeResponse = Result<Option<Error>, PopError>;
|
||||||
WebGPUQueue,
|
pub type WebGPURenderPipelineResponse = Result<Pipeline<id::RenderPipelineId>, Error>;
|
||||||
Result<wgt::DeviceDescriptor<Option<String>>, RequestDeviceError>,
|
pub type WebGPUComputePipelineResponse = Result<Pipeline<id::ComputePipelineId>, Error>;
|
||||||
),
|
|
||||||
),
|
|
||||||
BufferMapAsync(Result<Mapping, BufferAccessError>),
|
|
||||||
SubmittedWorkDone,
|
|
||||||
PoppedErrorScope(Result<Option<Error>, PopError>),
|
|
||||||
CompilationInfo(Option<ShaderCompilationInfo>),
|
|
||||||
RenderPipeline(Result<Pipeline<id::RenderPipelineId>, Error>),
|
|
||||||
ComputePipeline(Result<Pipeline<id::ComputePipelineId>, Error>),
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::render_commands::apply_render_command;
|
||||||
use crate::swapchain::{WGPUImageMap, WebGPUContextId};
|
use crate::swapchain::{WGPUImageMap, WebGPUContextId};
|
||||||
use crate::{
|
use crate::{
|
||||||
Adapter, ComputePassId, Error, Mapping, Pipeline, PopError, RenderPassId, WebGPU,
|
Adapter, ComputePassId, Error, Mapping, Pipeline, PopError, RenderPassId, WebGPU,
|
||||||
WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse,
|
WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq)]
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
@ -196,9 +196,7 @@ impl WGPU {
|
||||||
mode: host_map,
|
mode: host_map,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
if let Err(e) =
|
if let Err(e) = resp_sender.send(response) {
|
||||||
resp_sender.send(WebGPUResponse::BufferMapAsync(response))
|
|
||||||
{
|
|
||||||
warn!("Could not send BufferMapAsync Response ({})", e);
|
warn!("Could not send BufferMapAsync Response ({})", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -392,8 +390,8 @@ impl WGPU {
|
||||||
}),
|
}),
|
||||||
Some(e) => Err(Error::from_error(e)),
|
Some(e) => Err(Error::from_error(e)),
|
||||||
};
|
};
|
||||||
if let Err(e) = sender.send(WebGPUResponse::ComputePipeline(res)) {
|
if let Err(e) = sender.send(res) {
|
||||||
warn!("Failed sending WebGPUResponse::ComputePipeline {e:?}");
|
warn!("Failed sending WebGPUComputePipelineResponse {e:?}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.maybe_dispatch_wgpu_error(device_id, error);
|
self.maybe_dispatch_wgpu_error(device_id, error);
|
||||||
|
@ -451,8 +449,8 @@ impl WGPU {
|
||||||
}),
|
}),
|
||||||
Some(e) => Err(Error::from_error(e)),
|
Some(e) => Err(Error::from_error(e)),
|
||||||
};
|
};
|
||||||
if let Err(e) = sender.send(WebGPUResponse::RenderPipeline(res)) {
|
if let Err(e) = sender.send(res) {
|
||||||
warn!("Failed sending WebGPUResponse::RenderPipeline {e:?}");
|
warn!("Failed sending WebGPURenderPipelineResponse {e:?}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.maybe_dispatch_wgpu_error(device_id, error);
|
self.maybe_dispatch_wgpu_error(device_id, error);
|
||||||
|
@ -488,12 +486,12 @@ impl WGPU {
|
||||||
source,
|
source,
|
||||||
Some(program_id),
|
Some(program_id),
|
||||||
);
|
);
|
||||||
if let Err(e) = sender.send(WebGPUResponse::CompilationInfo(
|
if let Err(e) = sender.send(
|
||||||
error
|
error
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|e| crate::ShaderCompilationInfo::from(e, &program)),
|
.map(|e| crate::ShaderCompilationInfo::from(e, &program)),
|
||||||
)) {
|
) {
|
||||||
warn!("Failed to send WebGPUResponse::CompilationInfo {e:?}");
|
warn!("Failed to send CompilationInfo {e:?}");
|
||||||
}
|
}
|
||||||
self.maybe_dispatch_wgpu_error(device_id, error);
|
self.maybe_dispatch_wgpu_error(device_id, error);
|
||||||
},
|
},
|
||||||
|
@ -669,7 +667,7 @@ impl WGPU {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(e) = sender.send(WebGPUResponse::Adapter(response)) {
|
if let Err(e) = sender.send(Some(response)) {
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to send response to WebGPURequest::RequestAdapter ({})",
|
"Failed to send response to WebGPURequest::RequestAdapter ({})",
|
||||||
e
|
e
|
||||||
|
@ -739,8 +737,7 @@ impl WGPU {
|
||||||
global.device_set_device_lost_closure(device_id, callback);
|
global.device_set_device_lost_closure(device_id, callback);
|
||||||
descriptor
|
descriptor
|
||||||
});
|
});
|
||||||
if let Err(e) = sender.send(WebGPUResponse::Device((device, queue, result)))
|
if let Err(e) = sender.send((device, queue, result)) {
|
||||||
{
|
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to send response to WebGPURequest::RequestDevice ({})",
|
"Failed to send response to WebGPURequest::RequestDevice ({})",
|
||||||
e
|
e
|
||||||
|
@ -1048,7 +1045,7 @@ impl WGPU {
|
||||||
let token = self.poller.token();
|
let token = self.poller.token();
|
||||||
let callback = Box::from(move || {
|
let callback = Box::from(move || {
|
||||||
drop(token);
|
drop(token);
|
||||||
if let Err(e) = sender.send(WebGPUResponse::SubmittedWorkDone) {
|
if let Err(e) = sender.send(()) {
|
||||||
warn!("Could not send SubmittedWorkDone Response ({})", e);
|
warn!("Could not send SubmittedWorkDone Response ({})", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1187,25 +1184,21 @@ impl WGPU {
|
||||||
.expect("Device should not be dropped by this point");
|
.expect("Device should not be dropped by this point");
|
||||||
if let Some(error_scope_stack) = &mut device_scope.error_scope_stack {
|
if let Some(error_scope_stack) = &mut device_scope.error_scope_stack {
|
||||||
if let Some(error_scope) = error_scope_stack.pop() {
|
if let Some(error_scope) = error_scope_stack.pop() {
|
||||||
if let Err(e) = sender.send(WebGPUResponse::PoppedErrorScope(Ok(
|
if let Err(e) = sender.send(Ok(
|
||||||
// TODO: Do actual selection instead of selecting first error
|
// TODO: Do actual selection instead of selecting first error
|
||||||
error_scope.errors.first().cloned(),
|
error_scope.errors.first().cloned(),
|
||||||
))) {
|
)) {
|
||||||
warn!(
|
warn!(
|
||||||
"Unable to send {:?} to poperrorscope: {e:?}",
|
"Unable to send {:?} to poperrorscope: {e:?}",
|
||||||
error_scope.errors
|
error_scope.errors
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if let Err(e) =
|
} else if let Err(e) = sender.send(Err(PopError::Empty)) {
|
||||||
sender.send(WebGPUResponse::PoppedErrorScope(Err(PopError::Empty)))
|
|
||||||
{
|
|
||||||
warn!("Unable to send PopError::Empty: {e:?}");
|
warn!("Unable to send PopError::Empty: {e:?}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// device lost
|
// device lost
|
||||||
if let Err(e) =
|
if let Err(e) = sender.send(Err(PopError::Lost)) {
|
||||||
sender.send(WebGPUResponse::PoppedErrorScope(Err(PopError::Lost)))
|
|
||||||
{
|
|
||||||
warn!("Unable to send PopError::Lost due {e:?}");
|
warn!("Unable to send PopError::Lost due {e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue