mirror of
https://github.com/servo/servo
synced 2026-05-10 09:02:30 +02:00
Reviewable per commits: As noted in https://github.com/servo/servo/pull/42180#discussion_r2749861902 transmuting `&Reflector<AssociatedMemory>` to `&Reflector<()>` will ignore AssociatedMemory information and thus it will not remove extra associated memory. By returning `&Reflector<Self::ReflectorType>` from `DomObject::reflector()` we will preserve this information and thus correctly handle cases with associated memory. We also do not need `overrideMemoryUsage` in bindings.conf anymore. 🎉 Instead of removing associated memory in drop code we should do it as part of finalizers, otherwise we have problems in nested (inherited) structs, where drop is run for both parent and child, but we only added associated memory for child (on init_reflector) which already included size of parent. The only exception here is promise, because it is RCed and not finalized. Testing: Tested locally that it fixes speedometer. Fixes #42269 --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
163 lines
5.0 KiB
Rust
163 lines
5.0 KiB
Rust
/* 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 base::generic_channel::GenericCallback;
|
|
use dom_struct::dom_struct;
|
|
use webgpu_traits::{
|
|
WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPUComputePipelineResponse,
|
|
WebGPURequest,
|
|
};
|
|
use wgpu_core::pipeline::ComputePipelineDescriptor;
|
|
|
|
use crate::conversions::Convert;
|
|
use crate::dom::bindings::cell::DomRefCell;
|
|
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
|
GPUComputePipelineDescriptor, GPUComputePipelineMethods,
|
|
};
|
|
use crate::dom::bindings::error::Fallible;
|
|
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
|
use crate::dom::bindings::str::USVString;
|
|
use crate::dom::globalscope::GlobalScope;
|
|
use crate::dom::webgpu::gpubindgrouplayout::GPUBindGroupLayout;
|
|
use crate::dom::webgpu::gpudevice::GPUDevice;
|
|
use crate::script_runtime::CanGc;
|
|
|
|
#[dom_struct]
|
|
pub(crate) struct GPUComputePipeline {
|
|
reflector_: Reflector,
|
|
#[ignore_malloc_size_of = "channels are hard"]
|
|
#[no_trace]
|
|
channel: WebGPU,
|
|
label: DomRefCell<USVString>,
|
|
#[no_trace]
|
|
compute_pipeline: WebGPUComputePipeline,
|
|
device: Dom<GPUDevice>,
|
|
}
|
|
|
|
impl GPUComputePipeline {
|
|
fn new_inherited(
|
|
compute_pipeline: WebGPUComputePipeline,
|
|
label: USVString,
|
|
device: &GPUDevice,
|
|
) -> Self {
|
|
Self {
|
|
reflector_: Reflector::new(),
|
|
channel: device.channel(),
|
|
label: DomRefCell::new(label),
|
|
compute_pipeline,
|
|
device: Dom::from_ref(device),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn new(
|
|
global: &GlobalScope,
|
|
compute_pipeline: WebGPUComputePipeline,
|
|
label: USVString,
|
|
device: &GPUDevice,
|
|
can_gc: CanGc,
|
|
) -> DomRoot<Self> {
|
|
reflect_dom_object(
|
|
Box::new(GPUComputePipeline::new_inherited(
|
|
compute_pipeline,
|
|
label,
|
|
device,
|
|
)),
|
|
global,
|
|
can_gc,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl GPUComputePipeline {
|
|
pub(crate) fn id(&self) -> &WebGPUComputePipeline {
|
|
&self.compute_pipeline
|
|
}
|
|
|
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
|
|
pub(crate) fn create(
|
|
device: &GPUDevice,
|
|
descriptor: &GPUComputePipelineDescriptor,
|
|
async_sender: Option<GenericCallback<WebGPUComputePipelineResponse>>,
|
|
) -> WebGPUComputePipeline {
|
|
let compute_pipeline_id = device.global().wgpu_id_hub().create_compute_pipeline_id();
|
|
|
|
let pipeline_layout = device.get_pipeline_layout_data(&descriptor.parent.layout);
|
|
|
|
let desc = ComputePipelineDescriptor {
|
|
label: (&descriptor.parent.parent).convert(),
|
|
layout: pipeline_layout.explicit(),
|
|
stage: (&descriptor.compute).convert(),
|
|
cache: None,
|
|
};
|
|
|
|
device
|
|
.channel()
|
|
.0
|
|
.send(WebGPURequest::CreateComputePipeline {
|
|
device_id: device.id().0,
|
|
compute_pipeline_id,
|
|
descriptor: desc,
|
|
implicit_ids: pipeline_layout.implicit(),
|
|
async_sender,
|
|
})
|
|
.expect("Failed to create WebGPU ComputePipeline");
|
|
|
|
WebGPUComputePipeline(compute_pipeline_id)
|
|
}
|
|
}
|
|
|
|
impl GPUComputePipelineMethods<crate::DomTypeHolder> for GPUComputePipeline {
|
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
|
|
fn Label(&self) -> USVString {
|
|
self.label.borrow().clone()
|
|
}
|
|
|
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
|
|
fn SetLabel(&self, value: USVString) {
|
|
*self.label.borrow_mut() = value;
|
|
}
|
|
|
|
/// <https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout>
|
|
fn GetBindGroupLayout(&self, index: u32) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
|
let id = self.global().wgpu_id_hub().create_bind_group_layout_id();
|
|
|
|
if let Err(e) = self
|
|
.channel
|
|
.0
|
|
.send(WebGPURequest::ComputeGetBindGroupLayout {
|
|
device_id: self.device.id().0,
|
|
pipeline_id: self.compute_pipeline.0,
|
|
index,
|
|
id,
|
|
})
|
|
{
|
|
warn!("Failed to send WebGPURequest::ComputeGetBindGroupLayout {e:?}");
|
|
}
|
|
|
|
Ok(GPUBindGroupLayout::new(
|
|
&self.global(),
|
|
self.channel.clone(),
|
|
WebGPUBindGroupLayout(id),
|
|
USVString::default(),
|
|
CanGc::note(),
|
|
))
|
|
}
|
|
}
|
|
|
|
impl Drop for GPUComputePipeline {
|
|
fn drop(&mut self) {
|
|
if let Err(e) = self
|
|
.channel
|
|
.0
|
|
.send(WebGPURequest::DropComputePipeline(self.compute_pipeline.0))
|
|
{
|
|
warn!(
|
|
"Failed to send WebGPURequest::DropComputePipeline({:?}) ({})",
|
|
self.compute_pipeline.0, e
|
|
);
|
|
};
|
|
}
|
|
}
|