mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +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
|
@ -5,26 +5,24 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::Heap;
|
||||
use script_traits::ScriptMsg;
|
||||
use webgpu::wgt::PowerPreference;
|
||||
use webgpu::{WebGPUResponse, wgc};
|
||||
use webgpu::{WebGPUAdapterResponse, wgc};
|
||||
|
||||
use super::wgsllanguagefeatures::WGSLLanguageFeatures;
|
||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||
GPUMethods, GPUPowerPreference, GPURequestAdapterOptions, GPUTextureFormat,
|
||||
};
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||
use crate::dom::bindings::reflector::{DomGlobal, DomObject, Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::dom::webgpu::gpuadapter::GPUAdapter;
|
||||
use crate::realms::InRealm;
|
||||
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[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 {
|
||||
// https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter
|
||||
fn RequestAdapter(
|
||||
|
@ -111,7 +56,7 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
|
|||
) -> Rc<Promise> {
|
||||
let global = &self.global();
|
||||
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 {
|
||||
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,
|
||||
Some(GPUPowerPreference::High_performance) => PowerPreference::HighPerformance,
|
||||
|
@ -150,10 +95,15 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsyncWGPUListener for GPU {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) {
|
||||
impl RoutedPromiseListener<WebGPUAdapterResponse> for GPU {
|
||||
fn handle_response(
|
||||
&self,
|
||||
response: WebGPUAdapterResponse,
|
||||
promise: &Rc<Promise>,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
match response {
|
||||
WebGPUResponse::Adapter(Ok(adapter)) => {
|
||||
Some(Ok(adapter)) => {
|
||||
let adapter = GPUAdapter::new(
|
||||
&self.global(),
|
||||
adapter.channel,
|
||||
|
@ -170,15 +120,14 @@ impl AsyncWGPUListener for GPU {
|
|||
);
|
||||
promise.resolve_native(&adapter, can_gc);
|
||||
},
|
||||
WebGPUResponse::Adapter(Err(e)) => {
|
||||
Some(Err(e)) => {
|
||||
warn!("Could not get GPUAdapter ({:?})", e);
|
||||
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
||||
},
|
||||
WebGPUResponse::None => {
|
||||
None => {
|
||||
warn!("Couldn't get a response, because WebGPU is disabled");
|
||||
promise.resolve_native(&None::<GPUAdapter>, can_gc);
|
||||
},
|
||||
_ => unreachable!("GPU received wrong WebGPUResponse"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue