Add webgpu feature flag (#34444)

* Move script gpu files into webgpu folder

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* Modify gpu webidls

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* move gpu realted webidl

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* add webgpu feature to script

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* add dummy implementation for gpucanvascontext

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* fmt

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* add skip-if CARGO_FEATURE_WEBGPU

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* Move NavigatorGPU and workerNavigator GPU to webgpu idl

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* fmt and cleanup

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* review fix

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* enable webgpu by default and also some fmt fix

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

* Add pref back, fix imports, small cleanups

Signed-off-by: atbrakhi <atbrakhi@igalia.com>

---------

Signed-off-by: atbrakhi <atbrakhi@igalia.com>
This commit is contained in:
atbrakhi 2024-12-05 17:07:27 +01:00 committed by GitHub
parent bba3bc6ac2
commit 1591a3b506
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 295 additions and 105 deletions

View file

@ -15,6 +15,7 @@ path = "lib.rs"
default = []
multiview = []
tracing = ["dep:tracing"]
webgpu = ["script_traits/webgpu"]
[dependencies]
background_hang_monitor_api = { workspace = true }

View file

@ -151,9 +151,13 @@ use servo_config::{opts, pref};
use servo_rand::{random, Rng, ServoRng, SliceRandom};
use servo_url::{Host, ImmutableOrigin, ServoUrl};
use style_traits::CSSPixel;
#[cfg(feature = "webgpu")]
use webgpu::swapchain::WGPUImageMap;
#[cfg(feature = "webgpu")]
use webgpu::{self, WebGPU, WebGPURequest, WebGPUResponse};
use webrender::{RenderApi, RenderApiSender};
#[cfg(feature = "webgpu")]
use webrender::RenderApi;
use webrender::RenderApiSender;
use webrender_api::DocumentId;
use webrender_traits::WebrenderExternalImageRegistry;
@ -209,6 +213,7 @@ struct MessagePortInfo {
entangled_with: Option<MessagePortId>,
}
#[cfg(feature = "webgpu")]
/// Webrender related objects required by WebGPU threads
struct WebrenderWGPU {
/// Webrender API.
@ -251,6 +256,7 @@ struct BrowsingContextGroup {
event_loops: HashMap<Host, Weak<EventLoop>>,
/// The set of all WebGPU channels in this BrowsingContextGroup.
#[cfg(feature = "webgpu")]
webgpus: HashMap<Host, WebGPU>,
}
@ -388,6 +394,7 @@ pub struct Constellation<STF, SWF> {
webrender_document: DocumentId,
/// Webrender related objects required by WebGPU threads
#[cfg(feature = "webgpu")]
webrender_wgpu: WebrenderWGPU,
/// A map of message-port Id to info.
@ -543,6 +550,7 @@ pub struct InitialConstellationState {
/// User agent string to report in network requests.
pub user_agent: Cow<'static, str>,
#[cfg(feature = "webgpu")]
pub wgpu_image_map: WGPUImageMap,
}
@ -704,6 +712,7 @@ where
// Zero is reserved for the embedder.
PipelineNamespace::install(PipelineNamespaceId(1));
#[cfg(feature = "webgpu")]
let webrender_wgpu = WebrenderWGPU {
webrender_api: state.webrender_api_sender.create_api(),
webrender_external_images: state.webrender_external_images,
@ -758,6 +767,7 @@ where
scheduler_receiver,
document_states: HashMap::new(),
webrender_document: state.webrender_document,
#[cfg(feature = "webgpu")]
webrender_wgpu,
shutting_down: false,
handled_warnings: VecDeque::new(),
@ -1830,12 +1840,14 @@ where
EmbedderMsg::MediaSessionEvent(event),
));
},
#[cfg(feature = "webgpu")]
FromScriptMsg::RequestAdapter(response_sender, options, ids) => self
.handle_wgpu_request(
source_pipeline_id,
BrowsingContextId::from(source_top_ctx_id),
FromScriptMsg::RequestAdapter(response_sender, options, ids),
),
#[cfg(feature = "webgpu")]
FromScriptMsg::GetWebGPUChan(response_sender) => self.handle_wgpu_request(
source_pipeline_id,
BrowsingContextId::from(source_top_ctx_id),
@ -2034,6 +2046,7 @@ where
feature = "tracing",
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
)]
#[cfg(feature = "webgpu")]
fn handle_wgpu_request(
&mut self,
source_pipeline_id: PipelineId,
@ -2747,6 +2760,7 @@ where
}
debug!("Exiting WebGPU threads.");
#[cfg(feature = "webgpu")]
let receivers = self
.browsing_context_group_set
.values()
@ -2763,6 +2777,7 @@ where
})
.flatten();
#[cfg(feature = "webgpu")]
for receiver in receivers {
if let Err(e) = receiver.recv() {
warn!("Failed to receive exit response from WebGPU ({:?})", e);

View file

@ -183,7 +183,9 @@ mod from_script {
Self::ForwardDOMMessage(..) => target!("ForwardDOMMessage"),
Self::ScheduleJob(..) => target!("ScheduleJob"),
Self::MediaSessionEvent(..) => target!("MediaSessionEvent"),
#[cfg(feature = "webgpu")]
Self::RequestAdapter(..) => target!("RequestAdapter"),
#[cfg(feature = "webgpu")]
Self::GetWebGPUChan(..) => target!("GetWebGPUChan"),
Self::TitleChanged(..) => target!("TitleChanged"),
}

View file

@ -21,6 +21,7 @@ webgl_backtrace = ["canvas_traits/webgl_backtrace"]
js_backtrace = []
refcell_backtrace = ["accountable-refcell"]
webxr = ["webxr-api"]
webgpu = []
[build-dependencies]
phf_codegen = "0.11"

View file

@ -47,8 +47,9 @@ use crate::dom::errorevent::ErrorEvent;
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::identityhub::IdentityHub;
use crate::dom::messageevent::MessageEvent;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::worker::{TrustedWorkerAddress, Worker};
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::fetch::load_whole_resource;
@ -253,7 +254,7 @@ impl DedicatedWorkerGlobalScope {
closing: Arc<AtomicBool>,
image_cache: Arc<dyn ImageCache>,
browsing_context: Option<BrowsingContextId>,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
control_receiver: Receiver<DedicatedWorkerControlMsg>,
) -> DedicatedWorkerGlobalScope {
DedicatedWorkerGlobalScope {
@ -265,6 +266,7 @@ impl DedicatedWorkerGlobalScope {
runtime,
from_devtools_receiver,
closing,
#[cfg(feature = "webgpu")]
gpu_id_hub,
),
task_queue: TaskQueue::new(receiver, own_sender.clone()),
@ -291,7 +293,7 @@ impl DedicatedWorkerGlobalScope {
closing: Arc<AtomicBool>,
image_cache: Arc<dyn ImageCache>,
browsing_context: Option<BrowsingContextId>,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
control_receiver: Receiver<DedicatedWorkerControlMsg>,
) -> DomRoot<DedicatedWorkerGlobalScope> {
let cx = runtime.cx();
@ -308,6 +310,7 @@ impl DedicatedWorkerGlobalScope {
closing,
image_cache,
browsing_context,
#[cfg(feature = "webgpu")]
gpu_id_hub,
control_receiver,
));
@ -330,7 +333,7 @@ impl DedicatedWorkerGlobalScope {
closing: Arc<AtomicBool>,
image_cache: Arc<dyn ImageCache>,
browsing_context: Option<BrowsingContextId>,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
control_receiver: Receiver<DedicatedWorkerControlMsg>,
context_sender: Sender<ThreadSafeJSContext>,
) -> JoinHandle<()> {
@ -416,6 +419,7 @@ impl DedicatedWorkerGlobalScope {
closing,
image_cache,
browsing_context,
#[cfg(feature = "webgpu")]
gpu_id_hub,
control_receiver,
);

View file

@ -64,6 +64,7 @@ impl DissimilarOriginWindow {
global_to_clone_from.microtask_queue().clone(),
global_to_clone_from.is_headless(),
global_to_clone_from.get_user_agent(),
#[cfg(feature = "webgpu")]
global_to_clone_from.wgpu_id_hub(),
Some(global_to_clone_from.is_secure_context()),
false,

View file

@ -67,6 +67,7 @@ use style::stylesheet_set::DocumentStylesheetSet;
use style::stylesheets::{Origin, OriginSet, Stylesheet};
use url::Host;
use uuid::Uuid;
#[cfg(feature = "webgpu")]
use webgpu::swapchain::WebGPUContextId;
use webrender_api::units::DeviceIntRect;
@ -126,7 +127,6 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::focusevent::FocusEvent;
use crate::dom::fontfaceset::FontFaceSet;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpucanvascontext::GPUCanvasContext;
use crate::dom::hashchangeevent::HashChangeEvent;
use crate::dom::htmlanchorelement::HTMLAnchorElement;
use crate::dom::htmlareaelement::HTMLAreaElement;
@ -175,6 +175,8 @@ use crate::dom::types::VisibilityStateEntry;
use crate::dom::uievent::UIEvent;
use crate::dom::virtualmethods::vtable_for;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpucanvascontext::GPUCanvasContext;
use crate::dom::wheelevent::WheelEvent;
use crate::dom::window::{ReflowReason, Window};
use crate::dom::windowproxy::WindowProxy;
@ -446,6 +448,7 @@ pub struct Document {
dirty_webgl_contexts:
DomRefCell<HashMapTracedValues<WebGLContextId, Dom<WebGLRenderingContext>>>,
/// List of all WebGPU context IDs that need flushing.
#[cfg(feature = "webgpu")]
dirty_webgpu_contexts: DomRefCell<HashMapTracedValues<WebGPUContextId, Dom<GPUCanvasContext>>>,
/// <https://w3c.github.io/slection-api/#dfn-selection>
selection: MutNullableDom<Selection>,
@ -3026,6 +3029,7 @@ impl Document {
receiver.recv().unwrap();
}
#[cfg(feature = "webgpu")]
pub fn add_dirty_webgpu_canvas(&self, context: &GPUCanvasContext) {
self.dirty_webgpu_contexts
.borrow_mut()
@ -3034,6 +3038,7 @@ impl Document {
}
#[allow(crown::unrooted_must_root)]
#[cfg(feature = "webgpu")]
pub fn flush_dirty_webgpu_canvases(&self) {
self.dirty_webgpu_contexts
.borrow_mut()
@ -3424,6 +3429,7 @@ impl Document {
shadow_roots_styles_changed: Cell::new(false),
media_controls: DomRefCell::new(HashMap::new()),
dirty_webgl_contexts: DomRefCell::new(HashMapTracedValues::new()),
#[cfg(feature = "webgpu")]
dirty_webgpu_contexts: DomRefCell::new(HashMapTracedValues::new()),
selection: MutNullableDom::new(None),
animation_timeline: if pref!(layout.animations.test.enabled) {

View file

@ -62,9 +62,11 @@ use script_traits::{
};
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use uuid::Uuid;
#[cfg(feature = "webgpu")]
use webgpu::{DeviceLostReason, WebGPUDevice};
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
#[cfg(feature = "webgpu")]
use super::bindings::codegen::Bindings::WebGPUBinding::GPUDeviceLostReason;
use super::bindings::error::Fallible;
use super::bindings::trace::{HashMapTracedValues, RootedTraceableBox};
@ -104,9 +106,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::file::File;
use crate::dom::gamepad::{contains_user_gesture, Gamepad};
use crate::dom::gamepadevent::GamepadEventType;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::htmlscriptelement::{ScriptId, SourceCode};
use crate::dom::identityhub::IdentityHub;
use crate::dom::imagebitmap::ImageBitmap;
use crate::dom::messageevent::MessageEvent;
use crate::dom::messageport::MessagePort;
@ -117,6 +117,10 @@ use crate::dom::promise::Promise;
use crate::dom::readablestream::{ExternalUnderlyingSource, ReadableStream};
use crate::dom::serviceworker::ServiceWorker;
use crate::dom::serviceworkerregistration::ServiceWorkerRegistration;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpudevice::GPUDevice;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::window::Window;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::dom::workletglobalscope::WorkletGlobalScope;
@ -331,9 +335,11 @@ pub struct GlobalScope {
/// Identity Manager for WebGPU resources
#[ignore_malloc_size_of = "defined in wgpu"]
#[no_trace]
#[cfg(feature = "webgpu")]
gpu_id_hub: Arc<IdentityHub>,
/// WebGPU devices
#[cfg(feature = "webgpu")]
gpu_devices: DomRefCell<HashMapTracedValues<WebGPUDevice, WeakRef<GPUDevice>>>,
// https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute
@ -767,7 +773,7 @@ impl GlobalScope {
microtask_queue: Rc<MicrotaskQueue>,
is_headless: bool,
user_agent: Cow<'static, str>,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
inherited_secure_context: Option<bool>,
unminify_js: bool,
) -> Self {
@ -803,7 +809,9 @@ impl GlobalScope {
consumed_rejections: Default::default(),
is_headless,
user_agent,
#[cfg(feature = "webgpu")]
gpu_id_hub,
#[cfg(feature = "webgpu")]
gpu_devices: DomRefCell::new(HashMapTracedValues::new()),
frozen_supported_performance_entry_types: CachedFrozenArray::new(),
https_state: Cell::new(HttpsState::None),
@ -3148,16 +3156,19 @@ impl GlobalScope {
None
}
#[cfg(feature = "webgpu")]
pub fn wgpu_id_hub(&self) -> Arc<IdentityHub> {
self.gpu_id_hub.clone()
}
#[cfg(feature = "webgpu")]
pub fn add_gpu_device(&self, device: &GPUDevice) {
self.gpu_devices
.borrow_mut()
.insert(device.id(), WeakRef::new(device));
}
#[cfg(feature = "webgpu")]
pub fn remove_gpu_device(&self, device: WebGPUDevice) {
let device = self
.gpu_devices
@ -3167,6 +3178,7 @@ impl GlobalScope {
assert!(device.root().is_none())
}
#[cfg(feature = "webgpu")]
pub fn gpu_device_lost(&self, device: WebGPUDevice, reason: DeviceLostReason, msg: String) {
let reason = match reason {
DeviceLostReason::Unknown => GPUDeviceLostReason::Unknown,
@ -3184,6 +3196,7 @@ impl GlobalScope {
}
}
#[cfg(feature = "webgpu")]
pub fn handle_uncaptured_gpu_error(
&self,
device: WebGPUDevice,

View file

@ -0,0 +1,41 @@
/* 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 dom_struct::dom_struct;
use script_layout_interface::HTMLCanvasDataSource;
use crate::dom::bindings::codegen::Bindings::GPUCanvasContextBinding::GPUCanvasContextMethods;
use crate::dom::bindings::codegen::UnionTypes;
use crate::dom::bindings::reflector::Reflector;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutCanvasRenderingContextHelpers};
#[dom_struct]
pub struct GPUCanvasContext {
reflector_: Reflector,
}
impl GPUCanvasContext {
#[allow(dead_code)]
fn new_inherited() -> Self {
unimplemented!()
}
pub fn new(_global: &GlobalScope, _canvas: &HTMLCanvasElement) -> DomRoot<Self> {
unimplemented!()
}
}
impl GPUCanvasContextMethods<crate::DomTypeHolder> for GPUCanvasContext {
fn Canvas(&self) -> UnionTypes::HTMLCanvasElementOrOffscreenCanvas {
unimplemented!()
}
}
impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, GPUCanvasContext> {
fn canvas_data_source(self) -> HTMLCanvasDataSource {
unimplemented!()
}
}

View file

@ -9,11 +9,14 @@ use euclid::default::{Rect, Size2D};
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
use image::codecs::png::PngEncoder;
use image::{ColorType, ImageEncoder};
use ipc_channel::ipc::{self as ipcchan, IpcSharedMemory};
use ipc_channel::ipc::IpcSharedMemory;
#[cfg(feature = "webgpu")]
use ipc_channel::ipc::{self as ipcchan};
use js::error::throw_type_error;
use js::rust::{HandleObject, HandleValue};
use profile_traits::ipc;
use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
#[cfg(feature = "webgpu")]
use script_traits::ScriptMsg;
use servo_media::streams::registry::MediaStreamId;
use servo_media::streams::MediaStreamType;
@ -40,6 +43,7 @@ use crate::dom::canvasrenderingcontext2d::{
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::globalscope::GlobalScope;
#[cfg(not(feature = "webgpu"))]
use crate::dom::gpucanvascontext::GPUCanvasContext;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::mediastream::MediaStream;
@ -48,6 +52,8 @@ use crate::dom::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::dom::webgl2renderingcontext::WebGL2RenderingContext;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpucanvascontext::GPUCanvasContext;
use crate::script_runtime::{CanGc, JSContext};
const DEFAULT_WIDTH: u32 = 300;
@ -59,6 +65,7 @@ pub enum CanvasContext {
Context2d(Dom<CanvasRenderingContext2D>),
WebGL(Dom<WebGLRenderingContext>),
WebGL2(Dom<WebGL2RenderingContext>),
#[cfg(feature = "webgpu")]
WebGPU(Dom<GPUCanvasContext>),
}
@ -107,6 +114,7 @@ impl HTMLCanvasElement {
},
CanvasContext::WebGL(ref context) => context.recreate(size),
CanvasContext::WebGL2(ref context) => context.recreate(size),
#[cfg(feature = "webgpu")]
CanvasContext::WebGPU(ref context) => context.resize(),
}
}
@ -143,6 +151,7 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> {
},
Some(CanvasContext::WebGL(context)) => context.to_layout().canvas_data_source(),
Some(CanvasContext::WebGL2(context)) => context.to_layout().canvas_data_source(),
#[cfg(feature = "webgpu")]
Some(CanvasContext::WebGPU(context)) => context.to_layout().canvas_data_source(),
None => HTMLCanvasDataSource::Empty,
}
@ -248,6 +257,12 @@ impl HTMLCanvasElement {
Some(context)
}
#[cfg(not(feature = "webgpu"))]
fn get_or_init_webgpu_context(&self) -> Option<DomRoot<GPUCanvasContext>> {
None
}
#[cfg(feature = "webgpu")]
fn get_or_init_webgpu_context(&self) -> Option<DomRoot<GPUCanvasContext>> {
if let Some(ctx) = self.context() {
return match *ctx {
@ -328,6 +343,7 @@ impl HTMLCanvasElement {
// TODO: add a method in WebGL2RenderingContext to get the pixels.
return None;
},
#[cfg(feature = "webgpu")]
Some(&CanvasContext::WebGPU(_)) => {
// TODO: add a method in GPUCanvasContext to get the pixels.
return None;
@ -370,6 +386,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
"webgl2" | "experimental-webgl2" => self
.get_or_init_webgl2_context(cx, options, can_gc)
.map(RenderingContext::WebGL2RenderingContext),
#[cfg(feature = "webgpu")]
"webgpu" => self
.get_or_init_webgpu_context()
.map(RenderingContext::GPUCanvasContext),
@ -412,6 +429,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
}
},
//TODO: Add method get_image_data to GPUCanvasContext
#[cfg(feature = "webgpu")]
Some(CanvasContext::WebGPU(_)) => return Ok(USVString("data:,".into())),
None => {
// Each pixel is fully-transparent black.

View file

@ -402,7 +402,6 @@ pub mod htmltrackelement;
pub mod htmlulistelement;
pub mod htmlunknownelement;
pub mod htmlvideoelement;
pub mod identityhub;
pub mod iirfilternode;
pub mod imagebitmap;
pub mod imagedata;
@ -580,8 +579,14 @@ pub mod websocket;
mod webxr;
#[cfg(feature = "webxr")]
pub use self::webxr::*;
mod webgpu;
#[cfg(feature = "webgpu")]
pub mod webgpu;
#[cfg(feature = "webgpu")]
pub use self::webgpu::*;
#[cfg(not(feature = "webgpu"))]
pub mod gpucanvascontext;
#[cfg(not(feature = "webgpu"))]
pub use gpucanvascontext::GPUCanvasContext;
pub mod wheelevent;
pub mod window;
pub mod windowproxy;

View file

@ -26,6 +26,7 @@ use crate::dom::navigatorinfo;
use crate::dom::permissions::Permissions;
use crate::dom::pluginarray::PluginArray;
use crate::dom::serviceworkercontainer::ServiceWorkerContainer;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpu::GPU;
use crate::dom::window::Window;
#[cfg(feature = "webxr")]
@ -52,6 +53,7 @@ pub struct Navigator {
gamepads: DomRefCell<Vec<MutNullableDom<Gamepad>>>,
permissions: MutNullableDom<Permissions>,
mediasession: MutNullableDom<MediaSession>,
#[cfg(feature = "webgpu")]
gpu: MutNullableDom<GPU>,
/// <https://www.w3.org/TR/gamepad/#dfn-hasgamepadgesture>
has_gamepad_gesture: Cell<bool>,
@ -71,6 +73,7 @@ impl Navigator {
gamepads: Default::default(),
permissions: Default::default(),
mediasession: Default::default(),
#[cfg(feature = "webgpu")]
gpu: Default::default(),
has_gamepad_gesture: Cell::new(false),
}
@ -282,6 +285,7 @@ impl NavigatorMethods<crate::DomTypeHolder> for Navigator {
}
// https://gpuweb.github.io/gpuweb/#dom-navigator-gpu
#[cfg(feature = "webgpu")]
fn Gpu(&self) -> DomRoot<GPU> {
self.gpu.or_init(|| GPU::new(&self.global()))
}

View file

@ -39,7 +39,8 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::extendableevent::ExtendableEvent;
use crate::dom::extendablemessageevent::ExtendableMessageEvent;
use crate::dom::globalscope::GlobalScope;
use crate::dom::identityhub::IdentityHub;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::worker::TrustedWorkerAddress;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::fetch::load_whole_resource;
@ -240,6 +241,7 @@ impl ServiceWorkerGlobalScope {
runtime,
from_devtools_receiver,
closing,
#[cfg(feature = "webgpu")]
Arc::new(IdentityHub::default()),
),
task_queue: TaskQueue::new(receiver, own_sender.clone()),

View file

@ -21,8 +21,8 @@ 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::dom::webgpu::gpuadapter::GPUAdapter;
use crate::realms::InRealm;
use crate::script_runtime::CanGc;
use crate::task_source::{TaskSource, TaskSourceName};

View file

@ -20,11 +20,11 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpusupportedfeatures::gpu_to_wgt_feature;
use crate::dom::promise::Promise;
use crate::dom::types::{GPUAdapterInfo, GPUSupportedLimits};
use crate::dom::webgpu::gpu::{response_async, AsyncWGPUListener};
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::dom::webgpu::gpusupportedfeatures::gpu_to_wgt_feature;
use crate::realms::InRealm;
use crate::script_runtime::CanGc;

View file

@ -16,8 +16,8 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::webgpu::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUBindGroup {

View file

@ -17,8 +17,8 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpuconvert::convert_bind_group_layout_entry;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::webgpu::gpuconvert::convert_bind_group_layout_entry;
use crate::dom::webgpu::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUBindGroupLayout {

View file

@ -23,9 +23,9 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::promise::Promise;
use crate::dom::webgpu::gpu::{response_async, AsyncWGPUListener};
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::realms::InRealm;
use crate::script_runtime::{CanGc, JSContext};

View file

@ -20,11 +20,12 @@ use webrender_api::ImageKey;
use super::gpuconvert::convert_texture_descriptor;
use super::gputexture::GPUTexture;
use crate::dom::bindings::codegen::Bindings::GPUCanvasContextBinding::GPUCanvasContextMethods;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUTexture_Binding::GPUTextureMethods;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
GPUCanvasAlphaMode, GPUCanvasConfiguration, GPUCanvasContextMethods, GPUDeviceMethods,
GPUExtent3D, GPUExtent3DDict, GPUObjectDescriptorBase, GPUTextureDescriptor,
GPUTextureDimension, GPUTextureFormat, GPUTextureUsageConstants,
GPUCanvasAlphaMode, GPUCanvasConfiguration, GPUDeviceMethods, GPUExtent3D, GPUExtent3DDict,
GPUObjectDescriptorBase, GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat,
GPUTextureUsageConstants,
};
use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
use crate::dom::bindings::error::{Error, Fallible};

View file

@ -20,12 +20,12 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandbuffer::GPUCommandBuffer;
use crate::dom::gpucomputepassencoder::GPUComputePassEncoder;
use crate::dom::gpuconvert::{convert_load_op, convert_store_op};
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpurenderpassencoder::GPURenderPassEncoder;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpucommandbuffer::GPUCommandBuffer;
use crate::dom::webgpu::gpucomputepassencoder::GPUComputePassEncoder;
use crate::dom::webgpu::gpuconvert::{convert_load_op, convert_store_op};
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::dom::webgpu::gpurenderpassencoder::GPURenderPassEncoder;
#[dom_struct]
pub struct GPUCommandEncoder {

View file

@ -11,10 +11,10 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpucommandencoder::GPUCommandEncoder;
use crate::dom::webgpu::gpucomputepipeline::GPUComputePipeline;
#[dom_struct]
pub struct GPUComputePassEncoder {

View file

@ -16,8 +16,8 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::webgpu::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUComputePipeline {

View file

@ -42,24 +42,24 @@ use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpuadapter::GPUAdapter;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::gpuqueue::GPUQueue;
use crate::dom::gpurenderbundleencoder::GPURenderBundleEncoder;
use crate::dom::gpurenderpipeline::GPURenderPipeline;
use crate::dom::gpusampler::GPUSampler;
use crate::dom::gpushadermodule::GPUShaderModule;
use crate::dom::gpusupportedfeatures::GPUSupportedFeatures;
use crate::dom::gputexture::GPUTexture;
use crate::dom::gpuuncapturederrorevent::GPUUncapturedErrorEvent;
use crate::dom::promise::Promise;
use crate::dom::types::GPUError;
use crate::dom::webgpu::gpu::response_async;
use crate::dom::webgpu::gpuadapter::GPUAdapter;
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpucommandencoder::GPUCommandEncoder;
use crate::dom::webgpu::gpucomputepipeline::GPUComputePipeline;
use crate::dom::webgpu::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::webgpu::gpuqueue::GPUQueue;
use crate::dom::webgpu::gpurenderbundleencoder::GPURenderBundleEncoder;
use crate::dom::webgpu::gpurenderpipeline::GPURenderPipeline;
use crate::dom::webgpu::gpusampler::GPUSampler;
use crate::dom::webgpu::gpushadermodule::GPUShaderModule;
use crate::dom::webgpu::gpusupportedfeatures::GPUSupportedFeatures;
use crate::dom::webgpu::gputexture::GPUTexture;
use crate::dom::webgpu::gpuuncapturederrorevent::GPUUncapturedErrorEvent;
use crate::realms::InRealm;
use crate::script_runtime::CanGc;

View file

@ -16,7 +16,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::webgpu::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUPipelineLayout {

View file

@ -19,10 +19,10 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandbuffer::GPUCommandBuffer;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::promise::Promise;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpucommandbuffer::GPUCommandBuffer;
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::script_runtime::CanGc;
#[dom_struct]

View file

@ -20,11 +20,11 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpurenderbundle::GPURenderBundle;
use crate::dom::gpurenderpipeline::GPURenderPipeline;
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::dom::webgpu::gpurenderbundle::GPURenderBundle;
use crate::dom::webgpu::gpurenderpipeline::GPURenderPipeline;
#[dom_struct]
pub struct GPURenderBundleEncoder {

View file

@ -15,11 +15,11 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpurenderbundle::GPURenderBundle;
use crate::dom::gpurenderpipeline::GPURenderPipeline;
use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
use crate::dom::webgpu::gpubuffer::GPUBuffer;
use crate::dom::webgpu::gpucommandencoder::GPUCommandEncoder;
use crate::dom::webgpu::gpurenderbundle::GPURenderBundle;
use crate::dom::webgpu::gpurenderpipeline::GPURenderPipeline;
#[dom_struct]
pub struct GPURenderPassEncoder {

View file

@ -14,8 +14,8 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpudevice::{GPUDevice, PipelineLayout};
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::webgpu::gpudevice::{GPUDevice, PipelineLayout};
#[dom_struct]
pub struct GPURenderPipeline {

View file

@ -14,7 +14,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::webgpu::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUSampler {

View file

@ -19,8 +19,8 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gputextureview::GPUTextureView;
use crate::dom::webgpu::gpudevice::GPUDevice;
use crate::dom::webgpu::gputextureview::GPUTextureView;
#[dom_struct]
pub struct GPUTexture {

View file

@ -11,7 +11,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gputexture::GPUTexture;
use crate::dom::webgpu::gputexture::GPUTexture;
#[dom_struct]
pub struct GPUTextureView {

View file

@ -15,7 +15,7 @@ use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpuerror::GPUError;
use crate::dom::webgpu::gpuerror::GPUError;
use crate::script_runtime::CanGc;
#[dom_struct]

View file

@ -42,3 +42,4 @@ pub mod gputextureusage;
pub mod gputextureview;
pub mod gpuuncapturederrorevent;
pub mod gpuvalidationerror;
pub mod identityhub;

View file

@ -0,0 +1,9 @@
/* 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/. */
// https://html.spec.whatwg.org/multipage/#htmlcanvaselement
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
interface GPUCanvasContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
};

View file

@ -14,7 +14,6 @@ Navigator includes NavigatorLanguage;
//Navigator includes NavigatorStorageUtils;
Navigator includes NavigatorPlugins;
Navigator includes NavigatorCookies;
Navigator includes NavigatorGPU;
Navigator includes NavigatorConcurrentHardware;
// https://html.spec.whatwg.org/multipage/#navigatorid

View file

@ -2,6 +2,8 @@
* 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/. */
// skip-unless CARGO_FEATURE_WEBGPU
// Source: WebGPU (https://gpuweb.github.io/gpuweb/)
// Direct source: https://github.com/w3c/webref/blob/curated/ed/idl/webgpu.idl
@ -66,10 +68,9 @@ interface GPUAdapterInfo {
interface mixin NavigatorGPU {
[SameObject, Pref="dom.webgpu.enabled", Exposed=(Window /* ,DedicatedWorker */)] readonly attribute GPU gpu;
};
// NOTE: see `Navigator.webidl`
// Navigator includes NavigatorGPU;
// NOTE: see `WorkerNavigator.webidl`
// WorkerNavigator includes NavigatorGPU;
Navigator includes NavigatorGPU;
WorkerNavigator includes NavigatorGPU;
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
interface GPU {
@ -1137,17 +1138,12 @@ enum GPUQueryType {
"timestamp"
};
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
interface GPUCanvasContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
// Calling configure() a second time invalidates the previous one,
// and all of the textures it's produced.
[Throws]
partial interface GPUCanvasContext {
[Throws, Pref="dom.webgpu.enabled"]
undefined configure(GPUCanvasConfiguration descriptor);
undefined unconfigure();
[Throws]
[Pref="dom.webgpu.enabled"] undefined unconfigure();
[Throws, Pref="dom.webgpu.enabled"]
GPUTexture getCurrentTexture();
};

View file

@ -17,7 +17,3 @@ partial interface WorkerNavigator {
[Pref="dom.permissions.enabled"] readonly attribute Permissions permissions;
};
[Exposed=DedicatedWorker]
partial interface WorkerNavigator {
[SameObject, Pref="dom.webgpu.enabled"] readonly attribute GPU gpu;
};

View file

@ -124,7 +124,6 @@ use crate::dom::hashchangeevent::HashChangeEvent;
use crate::dom::history::History;
use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::identityhub::IdentityHub;
use crate::dom::location::Location;
use crate::dom::mediaquerylist::{MediaQueryList, MediaQueryListMatchState};
use crate::dom::mediaquerylistevent::MediaQueryListEvent;
@ -138,6 +137,8 @@ use crate::dom::selection::Selection;
use crate::dom::storage::Storage;
use crate::dom::testrunner::TestRunner;
use crate::dom::webglrenderingcontext::WebGLCommandSender;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::windowproxy::{WindowProxy, WindowProxyHandler};
use crate::dom::worklet::Worklet;
use crate::dom::workletglobalscope::WorkletGlobalScopeType;
@ -1875,6 +1876,7 @@ impl Window {
// If this reflow is for display, ensure webgl canvases are composited with
// up-to-date contents.
if for_display {
#[cfg(feature = "webgpu")]
document.flush_dirty_webgpu_canvases();
document.flush_dirty_webgl_canvases();
}
@ -2601,7 +2603,7 @@ impl Window {
replace_surrogates: bool,
user_agent: Cow<'static, str>,
player_context: WindowGLContext,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
inherited_secure_context: Option<bool>,
) -> DomRoot<Self> {
let error_reporter = CSSErrorReporter {
@ -2628,6 +2630,7 @@ impl Window {
microtask_queue,
is_headless,
user_agent,
#[cfg(feature = "webgpu")]
gpu_id_hub,
inherited_secure_context,
unminify_js,

View file

@ -234,6 +234,7 @@ impl WorkerMethods<crate::DomTypeHolder> for Worker {
closing.clone(),
global.image_cache(),
browsing_context,
#[cfg(feature = "webgpu")]
global.wgpu_id_hub(),
control_receiver,
context_sender,

View file

@ -46,10 +46,11 @@ use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::crypto::Crypto;
use crate::dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
use crate::dom::globalscope::GlobalScope;
use crate::dom::identityhub::IdentityHub;
use crate::dom::performance::Performance;
use crate::dom::promise::Promise;
use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::window::{base64_atob, base64_btoa};
use crate::dom::workerlocation::WorkerLocation;
use crate::dom::workernavigator::WorkerNavigator;
@ -140,7 +141,7 @@ impl WorkerGlobalScope {
runtime: Runtime,
devtools_receiver: Receiver<DevtoolScriptControlMsg>,
closing: Arc<AtomicBool>,
gpu_id_hub: Arc<IdentityHub>,
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
) -> Self {
// Install a pipeline-namespace in the current thread.
PipelineNamespace::auto_install();
@ -164,6 +165,7 @@ impl WorkerGlobalScope {
runtime.microtask_queue.clone(),
init.is_headless,
init.user_agent,
#[cfg(feature = "webgpu")]
gpu_id_hub,
init.inherited_secure_context,
false,

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::utils::to_frozen_array;
use crate::dom::navigator::hardware_concurrency;
use crate::dom::navigatorinfo;
use crate::dom::permissions::Permissions;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::gpu::GPU;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::script_runtime::JSContext;
@ -22,6 +23,7 @@ use crate::script_runtime::JSContext;
pub struct WorkerNavigator {
reflector_: Reflector,
permissions: MutNullableDom<Permissions>,
#[cfg(feature = "webgpu")]
gpu: MutNullableDom<GPU>,
}
@ -30,6 +32,7 @@ impl WorkerNavigator {
WorkerNavigator {
reflector_: Reflector::new(),
permissions: Default::default(),
#[cfg(feature = "webgpu")]
gpu: Default::default(),
}
}
@ -108,6 +111,7 @@ impl WorkerNavigatorMethods<crate::DomTypeHolder> for WorkerNavigator {
}
// https://gpuweb.github.io/gpuweb/#dom-navigator-gpu
#[cfg(feature = "webgpu")]
fn Gpu(&self) -> DomRoot<GPU> {
self.gpu.or_init(|| GPU::new(&self.global()))
}

View file

@ -22,9 +22,10 @@ use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::identityhub::IdentityHub;
use crate::dom::paintworkletglobalscope::{PaintWorkletGlobalScope, PaintWorkletTask};
use crate::dom::testworkletglobalscope::{TestWorkletGlobalScope, TestWorkletTask};
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::worklet::WorkletExecutor;
use crate::script_module::ScriptFetchOptions;
use crate::script_runtime::{CanGc, JSContext};
@ -99,6 +100,7 @@ impl WorkletGlobalScope {
Default::default(),
init.is_headless,
init.user_agent.clone(),
#[cfg(feature = "webgpu")]
init.gpu_id_hub.clone(),
init.inherited_secure_context,
false,
@ -193,6 +195,7 @@ pub struct WorkletGlobalScopeInit {
/// An optional string allowing the user agent to be set for testing
pub user_agent: Cow<'static, str>,
/// Identity manager for WebGPU resources
#[cfg(feature = "webgpu")]
pub gpu_id_hub: Arc<IdentityHub>,
/// Is considered secure
pub inherited_secure_context: Option<bool>,

View file

@ -158,6 +158,7 @@ pub enum ScriptThreadEventCategory {
EnterFullscreen,
ExitFullscreen,
PerformanceTimelineTask,
#[cfg(feature = "webgpu")]
WebGPUMsg,
}

View file

@ -94,6 +94,7 @@ use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use style::dom::OpaqueNode;
use style::thread_state::{self, ThreadState};
use url::Position;
#[cfg(feature = "webgpu")]
use webgpu::{WebGPUDevice, WebGPUMsg};
use webrender_api::DocumentId;
use webrender_traits::CrossProcessCompositorApi;
@ -128,7 +129,6 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlanchorelement::HTMLAnchorElement;
use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::identityhub::IdentityHub;
use crate::dom::mutationobserver::MutationObserver;
use crate::dom::node::{window_from_node, Node, ShadowIncluding};
use crate::dom::performanceentry::PerformanceEntry;
@ -136,6 +136,8 @@ use crate::dom::performancepainttiming::PerformancePaintTiming;
use crate::dom::serviceworker::TrustedServiceWorkerAddress;
use crate::dom::servoparser::{ParserContext, ServoParser};
use crate::dom::uievent::UIEvent;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
use crate::dom::window::{ReflowReason, Window};
use crate::dom::windowproxy::{CreatorBrowsingContextInfo, WindowProxy};
use crate::dom::worker::TrustedWorkerAddress;
@ -279,6 +281,7 @@ enum MixedMessage {
FromScript(MainThreadScriptMsg),
FromDevtools(DevtoolScriptControlMsg),
FromImageCache((PipelineId, PendingImageResponse)),
#[cfg(feature = "webgpu")]
FromWebGPUServer(WebGPUMsg),
}
@ -739,10 +742,12 @@ pub struct ScriptThread {
/// Identity manager for WebGPU resources
#[no_trace]
#[cfg(feature = "webgpu")]
gpu_id_hub: Arc<IdentityHub>,
/// Receiver to receive commands from optional WebGPU server.
#[no_trace]
#[cfg(feature = "webgpu")]
webgpu_port: RefCell<Option<Receiver<WebGPUMsg>>>,
// Secure context
@ -1136,6 +1141,7 @@ impl ScriptThread {
image_cache: script_thread.image_cache.clone(),
is_headless: script_thread.headless,
user_agent: script_thread.user_agent.clone(),
#[cfg(feature = "webgpu")]
gpu_id_hub: script_thread.gpu_id_hub.clone(),
inherited_secure_context: script_thread.inherited_secure_context,
};
@ -1359,7 +1365,9 @@ impl ScriptThread {
node_ids: Default::default(),
is_user_interacting: Cell::new(false),
#[cfg(feature = "webgpu")]
gpu_id_hub: Arc::new(IdentityHub::default()),
#[cfg(feature = "webgpu")]
webgpu_port: RefCell::new(None),
inherited_secure_context: state.inherited_secure_context,
layout_factory,
@ -1739,9 +1747,9 @@ impl ScriptThread {
/// Handle incoming messages from other tasks and the task queue.
fn handle_msgs(&self, can_gc: CanGc) -> bool {
use self::MixedMessage::{
FromConstellation, FromDevtools, FromImageCache, FromScript, FromWebGPUServer,
};
#[cfg(feature = "webgpu")]
use self::MixedMessage::FromWebGPUServer;
use self::MixedMessage::{FromConstellation, FromDevtools, FromImageCache, FromScript};
// Proritize rendering tasks and others, and gather all other events as `sequential`.
let mut sequential = vec![];
@ -1764,8 +1772,25 @@ impl ScriptThread {
recv(self.devtools_chan.as_ref().map(|_| &self.devtools_port).unwrap_or(&crossbeam_channel::never())) -> msg
=> FromDevtools(msg.unwrap()),
recv(self.image_cache_port) -> msg => FromImageCache(msg.unwrap()),
recv(self.webgpu_port.borrow().as_ref().unwrap_or(&crossbeam_channel::never())) -> msg
=> FromWebGPUServer(msg.unwrap()),
recv({
#[cfg(feature = "webgpu")]
{
self.webgpu_port.borrow().as_ref().unwrap_or(&crossbeam_channel::never())
}
#[cfg(not(feature = "webgpu"))]
{
&crossbeam_channel::never::<()>()
}
}) -> msg => {
#[cfg(feature = "webgpu")]
{
FromWebGPUServer(msg.unwrap())
}
#[cfg(not(feature = "webgpu"))]
{
unreachable!("This should never be hit when webgpu is disabled");
}
},
};
debug!("Got event.");
@ -1890,6 +1915,7 @@ impl ScriptThread {
Err(_) => match self.task_queue.take_tasks_and_recv() {
Err(_) => match self.devtools_port.try_recv() {
Err(_) => match self.image_cache_port.try_recv() {
#[cfg(feature = "webgpu")]
Err(_) => match &*self.webgpu_port.borrow() {
Some(p) => match p.try_recv() {
Err(_) => break,
@ -1898,6 +1924,8 @@ impl ScriptThread {
None => break,
},
Ok(ev) => event = FromImageCache(ev),
#[cfg(not(feature = "webgpu"))]
Err(_) => break,
},
Ok(ev) => event = FromDevtools(ev),
},
@ -1953,6 +1981,7 @@ impl ScriptThread {
FromScript(inner_msg) => self.handle_msg_from_script(inner_msg),
FromDevtools(inner_msg) => self.handle_msg_from_devtools(inner_msg, can_gc),
FromImageCache(inner_msg) => self.handle_msg_from_image_cache(inner_msg),
#[cfg(feature = "webgpu")]
FromWebGPUServer(inner_msg) => {
self.handle_msg_from_webgpu_server(inner_msg, can_gc)
},
@ -2053,6 +2082,7 @@ impl ScriptThread {
},
_ => ScriptThreadEventCategory::ScriptEvent,
},
#[cfg(feature = "webgpu")]
MixedMessage::FromWebGPUServer(_) => ScriptThreadEventCategory::WebGPUMsg,
}
}
@ -2093,6 +2123,7 @@ impl ScriptThread {
ScriptHangAnnotation::PerformanceTimelineTask
},
ScriptThreadEventCategory::PortMessage => ScriptHangAnnotation::PortMessage,
#[cfg(feature = "webgpu")]
ScriptThreadEventCategory::WebGPUMsg => ScriptHangAnnotation::WebGPUMsg,
};
self.background_hang_monitor
@ -2139,6 +2170,7 @@ impl ScriptThread {
PaintMetric(id, ..) => Some(id),
ExitFullScreen(id, ..) => Some(id),
MediaSessionAction(..) => None,
#[cfg(feature = "webgpu")]
SetWebGPUPort(..) => None,
SetScrollStates(id, ..) => Some(id),
SetEpochPaintTime(id, ..) => Some(id),
@ -2155,6 +2187,7 @@ impl ScriptThread {
MainThreadScriptMsg::WakeUp => None,
},
MixedMessage::FromImageCache((pipeline_id, _)) => Some(pipeline_id),
#[cfg(feature = "webgpu")]
MixedMessage::FromWebGPUServer(..) => None,
}
}
@ -2287,6 +2320,7 @@ impl ScriptThread {
profiler_chan,
f
),
#[cfg(feature = "webgpu")]
ScriptThreadEventCategory::WebGPUMsg => {
time_profile!(ProfilerCategory::ScriptWebGPUMsg, None, profiler_chan, f)
},
@ -2438,6 +2472,7 @@ impl ScriptThread {
ConstellationControlMsg::MediaSessionAction(pipeline_id, action) => {
self.handle_media_session_action(pipeline_id, action, can_gc)
},
#[cfg(feature = "webgpu")]
ConstellationControlMsg::SetWebGPUPort(port) => {
if self.webgpu_port.borrow().is_some() {
warn!("WebGPU port already exists for this content process");
@ -2509,6 +2544,7 @@ impl ScriptThread {
window.layout_mut().set_epoch_paint_time(epoch, time);
}
#[cfg(feature = "webgpu")]
fn handle_msg_from_webgpu_server(&self, msg: WebGPUMsg, can_gc: CanGc) {
match msg {
WebGPUMsg::FreeAdapter(id) => self.gpu_id_hub.free_adapter_id(id),
@ -3768,6 +3804,7 @@ impl ScriptThread {
self.replace_surrogates,
self.user_agent.clone(),
self.player_context.clone(),
#[cfg(feature = "webgpu")]
self.gpu_id_hub.clone(),
incomplete.inherited_secure_context,
);

View file

@ -39,6 +39,10 @@ webxr = [
"canvas/webxr",
"script/webxr",
]
webgpu = [
"script/webgpu",
"constellation/webgpu",
]
[dependencies]
background_hang_monitor = { path = "../background_hang_monitor" }

View file

@ -88,6 +88,9 @@ use surfman::platform::generic::multi::context::NativeContext as LinuxNativeCont
use surfman::{GLApi, GLVersion};
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
use surfman::{NativeConnection, NativeContext};
#[cfg(feature = "webgpu")]
pub use webgpu;
#[cfg(feature = "webgpu")]
use webgpu::swapchain::WGPUImageMap;
use webrender::{RenderApiSender, ShaderPrecacheFlags, UploadMethod, ONE_TIME_USAGE_HINT};
use webrender_api::{ColorF, DocumentId, FramePublishId};
@ -100,7 +103,7 @@ pub use {
constellation, devtools, devtools_traits, embedder_traits, euclid, fonts, ipc_channel,
keyboard_types, layout_thread_2020, media, net, net_traits, profile, profile_traits, script,
script_layout_interface, script_traits, servo_config as config, servo_config, servo_geometry,
servo_url as url, servo_url, style, style_traits, webgpu, webrender_api, webrender_traits,
servo_url as url, servo_url, style, style_traits, webrender_api, webrender_traits,
};
#[cfg(feature = "webdriver")]
@ -424,8 +427,11 @@ where
embedder.register_webxr(&mut webxr_main_thread, embedder_proxy.clone());
}
#[cfg(feature = "webgpu")]
let wgpu_image_handler = webgpu::WGPUExternalImages::default();
#[cfg(feature = "webgpu")]
let wgpu_image_map = wgpu_image_handler.images.clone();
#[cfg(feature = "webgpu")]
external_image_handlers.set_handler(
Box::new(wgpu_image_handler),
WebrenderImageHandlerType::WebGPU,
@ -468,6 +474,7 @@ where
glplayer_threads,
window_size,
external_images,
#[cfg(feature = "webgpu")]
wgpu_image_map,
protocols,
);
@ -1058,7 +1065,7 @@ fn create_constellation(
glplayer_threads: Option<GLPlayerThreads>,
initial_window_size: WindowSizeData,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
wgpu_image_map: WGPUImageMap,
#[cfg(feature = "webgpu")] wgpu_image_map: WGPUImageMap,
protocols: ProtocolRegistry,
) -> Sender<ConstellationMsg> {
// Global configuration options, parsed from the command line.
@ -1110,6 +1117,7 @@ fn create_constellation(
player_context,
user_agent,
webrender_external_images: external_images,
#[cfg(feature = "webgpu")]
wgpu_image_map,
};

View file

@ -11,6 +11,9 @@ rust-version.workspace = true
name = "script_traits"
path = "lib.rs"
[features]
webgpu = []
[dependencies]
background_hang_monitor_api = { workspace = true }
base = { workspace = true }

View file

@ -55,6 +55,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use servo_atoms::Atom;
use servo_url::{ImmutableOrigin, ServoUrl};
use style_traits::{CSSPixel, SpeculativePainter};
#[cfg(feature = "webgpu")]
use webgpu::WebGPUMsg;
use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel};
use webrender_api::{DocumentId, ExternalScrollId, ImageKey};
@ -380,6 +381,7 @@ pub enum ConstellationControlMsg {
/// Notifies the media session about a user requested media session action.
MediaSessionAction(PipelineId, MediaSessionActionType),
/// Notifies script thread that WebGPU server has started
#[cfg(feature = "webgpu")]
SetWebGPUPort(IpcReceiver<WebGPUMsg>),
/// The compositor scrolled and is updating the scroll states of the nodes in the given
/// pipeline via the Constellation.
@ -422,6 +424,7 @@ impl fmt::Debug for ConstellationControlMsg {
PaintMetric(..) => "PaintMetric",
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
#[cfg(feature = "webgpu")]
SetWebGPUPort(..) => "SetWebGPUPort",
SetScrollStates(..) => "SetScrollStates",
SetEpochPaintTime(..) => "SetEpochPaintTime",

View file

@ -23,6 +23,7 @@ use net_traits::CoreResourceMsg;
use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl};
use style_traits::CSSPixel;
#[cfg(feature = "webgpu")]
use webgpu::{wgc, WebGPU, WebGPUResponse};
use crate::{
@ -247,12 +248,14 @@ pub enum ScriptMsg {
/// Notifies the constellation about media session events
/// (i.e. when there is metadata for the active media session, playback state changes...).
MediaSessionEvent(PipelineId, MediaSessionEvent),
#[cfg(feature = "webgpu")]
/// Create a WebGPU Adapter instance
RequestAdapter(
IpcSender<WebGPUResponse>,
wgc::instance::RequestAdapterOptions,
wgc::id::AdapterId,
),
#[cfg(feature = "webgpu")]
/// Get WebGPU channel
GetWebGPUChan(IpcSender<Option<WebGPU>>),
/// Notify the constellation of a pipeline's document's title.
@ -312,7 +315,9 @@ impl fmt::Debug for ScriptMsg {
ForwardDOMMessage(..) => "ForwardDOMMessage",
ScheduleJob(..) => "ScheduleJob",
MediaSessionEvent(..) => "MediaSessionEvent",
#[cfg(feature = "webgpu")]
RequestAdapter(..) => "RequestAdapter",
#[cfg(feature = "webgpu")]
GetWebGPUChan(..) => "GetWebGPUChan",
TitleChanged(..) => "TitleChanged",
};

View file

@ -39,7 +39,7 @@ ProductName = "Servo"
[features]
debugmozjs = ["libservo/debugmozjs"]
default = ["max_log_level", "webdriver", "webxr"]
default = ["max_log_level", "webdriver", "webxr", "webgpu"]
jitspew = ["libservo/jitspew"]
js_backtrace = ["libservo/js_backtrace"]
layout_2013 = ["libservo/layout_2013"]
@ -55,6 +55,7 @@ tracing-perfetto = ["tracing", "dep:tracing-perfetto"]
webdriver = ["libservo/webdriver"]
webgl_backtrace = ["libservo/webgl_backtrace"]
webxr = ["dep:webxr", "libservo/webxr"]
webgpu = ["libservo/webgpu"]
[dependencies]
libc = { workspace = true }