/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script/dom/webgpu/gpucomputepipeline.rs
173 строки
5 KB
Sam
script: Support `no_gc` in codegen, add `safe_borrow_mut` and use it in webgpu (#46050)
28 июн 2026, 22:42
Не верифицирован
28 июн 2026, 22:42
2bb4ff5
Код
Авторство
О чём код?
/* 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 js::context::{JSContext, NoGC}; use script_bindings::cell::DomRefCell; use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx}; use servo_base::generic_channel::GenericCallback; use webgpu_traits::{ WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPUComputePipelineResponse, WebGPURequest, }; use wgpu_core::pipeline::ComputePipelineDescriptor; use crate::conversions::Convert; use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ GPUComputePipelineDescriptor, GPUComputePipelineMethods, }; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::DomGlobal; 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; #[derive(JSTraceable, MallocSizeOf)] struct DroppableGPUComputePipeline { #[no_trace] channel: WebGPU, #[no_trace] compute_pipeline: WebGPUComputePipeline, } impl Drop for DroppableGPUComputePipeline { 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 ); }; } } #[dom_struct] pub(crate) struct GPUComputePipeline { reflector_: Reflector, label: DomRefCell<USVString>, device: Dom<GPUDevice>, droppable: DroppableGPUComputePipeline, } impl GPUComputePipeline { fn new_inherited( compute_pipeline: WebGPUComputePipeline, label: USVString, device: &GPUDevice, ) -> Self { Self { reflector_: Reflector::new(), label: DomRefCell::new(label), device: Dom::from_ref(device), droppable: DroppableGPUComputePipeline { channel: device.channel(), compute_pipeline, }, } } pub(crate) fn new( cx: &mut JSContext, global: &GlobalScope, compute_pipeline: WebGPUComputePipeline, label: USVString, device: &GPUDevice, ) -> DomRoot<Self> { reflect_dom_object_with_cx( Box::new(GPUComputePipeline::new_inherited( compute_pipeline, label, device, )), global, cx, ) } } impl GPUComputePipeline { pub(crate) fn id(&self) -> &WebGPUComputePipeline { &self.droppable.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, 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, no_gc: &NoGC, value: USVString) { *self.label.safe_borrow_mut(no_gc) = value; } /// <https://gpuweb.github.io/gpuweb/#dom-gpupipelinebase-getbindgrouplayout> fn GetBindGroupLayout( &self, cx: &mut JSContext, index: u32, ) -> Fallible<DomRoot<GPUBindGroupLayout>> { let id = self.global().wgpu_id_hub().create_bind_group_layout_id(); if let Err(e) = self .droppable .channel .0 .send(WebGPURequest::ComputeGetBindGroupLayout { device_id: self.device.id().0, pipeline_id: self.id().0, index, id, }) { warn!("Failed to send WebGPURequest::ComputeGetBindGroupLayout {e:?}"); } Ok(GPUBindGroupLayout::new( cx, &self.global(), self.droppable.channel.clone(), WebGPUBindGroupLayout(id), USVString::default(), )) } }