New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial implementation of WebGPU API #24708
Changes from all commits
File filter...
Jump to…
Large diffs are not rendered by default.
| @@ -0,0 +1,158 @@ | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||||||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
| * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||||||
|
|
||||||
| use crate::compartments::InCompartment; | ||||||
| use crate::dom::bindings::codegen::Bindings::GPUBinding::GPURequestAdapterOptions; | ||||||
| use crate::dom::bindings::codegen::Bindings::GPUBinding::{self, GPUMethods, GPUPowerPreference}; | ||||||
| use crate::dom::bindings::error::Error; | ||||||
| use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; | ||||||
| use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; | ||||||
| use crate::dom::bindings::root::DomRoot; | ||||||
| use crate::dom::bindings::str::DOMString; | ||||||
| use crate::dom::globalscope::GlobalScope; | ||||||
| use crate::dom::gpuadapter::GPUAdapter; | ||||||
| use crate::dom::promise::Promise; | ||||||
| use crate::task_source::TaskSource; | ||||||
| use dom_struct::dom_struct; | ||||||
| use ipc_channel::ipc::{self, IpcSender}; | ||||||
| use ipc_channel::router::ROUTER; | ||||||
| use js::jsapi::Heap; | ||||||
| use std::rc::Rc; | ||||||
| use webgpu::wgpu; | ||||||
| use webgpu::{WebGPU, WebGPURequest, WebGPUResponse, WebGPUResponseResult}; | ||||||
|
|
||||||
| #[dom_struct] | ||||||
| pub struct GPU { | ||||||
| reflector_: Reflector, | ||||||
| } | ||||||
|
|
||||||
| impl GPU { | ||||||
| pub fn new_inherited() -> GPU { | ||||||
| GPU { | ||||||
| reflector_: Reflector::new(), | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| pub fn new(global: &GlobalScope) -> DomRoot<GPU> { | ||||||
| reflect_dom_object(Box::new(GPU::new_inherited()), global, GPUBinding::Wrap) | ||||||
| } | ||||||
|
|
||||||
| fn wgpu_channel(&self) -> Option<WebGPU> { | ||||||
| self.global().as_window().webgpu_channel() | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| pub trait AsyncWGPUListener { | ||||||
| fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>); | ||||||
| } | ||||||
|
|
||||||
| struct WGPUResponse<T: AsyncWGPUListener + DomObject> { | ||||||
| trusted: TrustedPromise, | ||||||
| receiver: Trusted<T>, | ||||||
| } | ||||||
|
|
||||||
| impl<T: AsyncWGPUListener + DomObject> WGPUResponse<T> { | ||||||
| #[allow(unrooted_must_root)] | ||||||
| fn response(self, response: WebGPUResponseResult) { | ||||||
| let promise = self.trusted.root(); | ||||||
| match response { | ||||||
| Ok(response) => self.receiver.root().handle_response(response, &promise), | ||||||
| Err(error) => promise.reject_error(Error::Type(format!( | ||||||
| "Received error from WebGPU thread: {}", | ||||||
| error | ||||||
| ))), | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>( | ||||||
zakorgy
Author
Contributor
|
||||||
| pub enum MessagePortState { |
servo/components/script/dom/globalscope.rs
Line 616 in 2caa227
| // Setup a route for IPC, for messages from the constellation to our ports. |
I guess for now it's fine to keep it as it is, however I'm not sure that you can scale the response_async pattern to handle all those interfaces. We'll see.
I'm wondering if the
AsyncWGPUListenertrait is necessary. Unless things other than theGPUcan be passed to the those methods, I would say you can simply pass it as is and just define a "handle_adapter_response" method on it.From reading the spec it seems different adapters can be returned(software or GPU), however requesting one seems to go through a single
GPUobject.