webgpu: Factor out swapchain to separate file (#33367)

* Move some stuff to swapchain.rs

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Use typed WebGPUContextId instead of u64

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Extract create_swapchain function and move more stuff in it

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* extract destroy_swapchain

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* extract swapchain_present

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* extract update_wr_image callback

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* fixup

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
Samson 2024-09-09 15:29:04 +02:00 committed by GitHub
parent 938fd8c12f
commit 687f356db9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 403 additions and 328 deletions

View file

@ -61,7 +61,6 @@ use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::gpucanvascontext::WebGPUContextId;
use crate::dom::htmlimageelement::SourceSet;
use crate::dom::htmlmediaelement::HTMLMediaElementFetchContext;
use crate::dom::windowproxy::WindowProxyHandler;
@ -364,7 +363,6 @@ unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt);
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
unsafe_no_jsmanaged_fields!(DOMString);
unsafe_no_jsmanaged_fields!(USVString);
unsafe_no_jsmanaged_fields!(WebGPUContextId);
unsafe_no_jsmanaged_fields!(SourceSet);
unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext);
unsafe_no_jsmanaged_fields!(StreamConsumer);

View file

@ -65,6 +65,7 @@ use style::stylesheet_set::DocumentStylesheetSet;
use style::stylesheets::{Origin, OriginSet, Stylesheet};
use url::Host;
use uuid::Uuid;
use webgpu::swapchain::WebGPUContextId;
use webrender_api::units::DeviceIntRect;
use crate::animation_timeline::AnimationTimeline;
@ -123,7 +124,7 @@ 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, WebGPUContextId};
use crate::dom::gpucanvascontext::GPUCanvasContext;
use crate::dom::hashchangeevent::HashChangeEvent;
use crate::dom::htmlanchorelement::HTMLAnchorElement;
use crate::dom::htmlareaelement::HTMLAreaElement;
@ -442,7 +443,7 @@ pub struct Document {
dirty_webgl_contexts:
DomRefCell<HashMapTracedValues<WebGLContextId, Dom<WebGLRenderingContext>>>,
/// List of all WebGPU context IDs that need flushing.
dirty_webgpu_contexts: DomRefCell<HashMap<WebGPUContextId, Dom<GPUCanvasContext>>>,
dirty_webgpu_contexts: DomRefCell<HashMapTracedValues<WebGPUContextId, Dom<GPUCanvasContext>>>,
/// <https://html.spec.whatwg.org/multipage/#concept-document-csp-list>
#[ignore_malloc_size_of = "Defined in rust-content-security-policy"]
#[no_trace]
@ -3278,7 +3279,7 @@ impl Document {
shadow_roots_styles_changed: Cell::new(false),
media_controls: DomRefCell::new(HashMap::new()),
dirty_webgl_contexts: DomRefCell::new(HashMapTracedValues::new()),
dirty_webgpu_contexts: DomRefCell::new(HashMap::new()),
dirty_webgpu_contexts: DomRefCell::new(HashMapTracedValues::new()),
csp_list: DomRefCell::new(None),
selection: MutNullableDom::new(None),
animation_timeline: if pref!(layout.animations.test.enabled) {

View file

@ -9,12 +9,10 @@ use dom_struct::dom_struct;
use euclid::default::Size2D;
use ipc_channel::ipc;
use script_layout_interface::HTMLCanvasDataSource;
use webgpu::swapchain::WebGPUContextId;
use webgpu::wgc::id;
use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, PRESENTATION_BUFFER_COUNT};
use webrender_api::{
units, ExternalImageData, ExternalImageId, ExternalImageType, ImageData, ImageDescriptor,
ImageDescriptorFlags, ImageFormat, ImageKey,
};
use webgpu::{WebGPU, WebGPURequest, WebGPUTexture, PRESENTATION_BUFFER_COUNT};
use webrender_api::{units, ImageFormat, ImageKey};
use super::bindings::codegen::Bindings::WebGPUBinding::GPUTextureUsageConstants;
use super::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
@ -35,9 +33,6 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutCanvasRenderingContextHelpers};
use crate::dom::node::{document_from_node, Node, NodeDamage};
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd)]
pub struct WebGPUContextId(pub u64);
// TODO: make all this derivables available via new Bindings.conf option
impl Clone for GPUCanvasConfiguration {
fn clone(&self) -> Self {
@ -104,6 +99,7 @@ pub struct GPUCanvasContext {
#[ignore_malloc_size_of = "Defined in webrender"]
#[no_trace]
webrender_image: Cell<Option<webrender_api::ImageKey>>,
#[no_trace]
context_id: WebGPUContextId,
/// <https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-currenttexture-slot>
texture: MutNullableDom<GPUTexture>,
@ -154,7 +150,7 @@ impl GPUCanvasContext {
.wgpu_id_hub()
.create_command_encoder_id(texture_id.backend());
if let Err(e) = self.channel.0.send(WebGPURequest::SwapChainPresent {
external_id: self.context_id.0,
context_id: self.context_id,
texture_id,
encoder_id,
}) {
@ -250,22 +246,6 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
};
// Step 8
let image_desc = ImageDescriptor {
format,
size: units::DeviceIntSize::new(size.width as i32, size.height as i32),
stride: Some(
(((size.width as u32 * 4) | (wgt::COPY_BYTES_PER_ROW_ALIGNMENT - 1)) + 1) as i32,
),
offset: 0,
flags: ImageDescriptorFlags::from_bits(1).unwrap(),
};
let image_data = ImageData::External(ExternalImageData {
id: ExternalImageId(self.context_id.0),
channel_index: 0,
image_type: ExternalImageType::Buffer,
});
let (sender, receiver) = ipc::channel().unwrap();
let mut buffer_ids = ArrayVec::<id::BufferId, PRESENTATION_BUFFER_COUNT>::new();
@ -283,10 +263,10 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
device_id: descriptor.device.id().0,
queue_id: descriptor.device.GetQueue().id().0,
buffer_ids,
external_id: self.context_id.0,
context_id: self.context_id,
sender,
image_desc,
image_data,
format,
size: units::DeviceIntSize::new(size.width as i32, size.height as i32),
})
.expect("Failed to create WebGPU SwapChain");
@ -301,7 +281,7 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
fn Unconfigure(&self) {
if let Some(image_key) = self.webrender_image.take() {
if let Err(e) = self.channel.0.send(WebGPURequest::DestroySwapChain {
external_id: self.context_id.0,
context_id: self.context_id,
image_key,
}) {
warn!(