diff options
author | Kunal Mohan <kunalmohan99@gmail.com> | 2020-05-29 12:02:05 +0530 |
---|---|---|
committer | Kunal Mohan <kunalmohan99@gmail.com> | 2020-06-01 23:28:12 +0530 |
commit | af95d922315974dcfae5659b503a672b19026fdb (patch) | |
tree | 312c711c1d90ac33ed538cc1cc5e240bcf70273e /components/script/dom/gputexture.rs | |
parent | d9db350df528628b1f7f2f1da711fc2da790ec49 (diff) | |
download | servo-af95d922315974dcfae5659b503a672b19026fdb.tar.gz servo-af95d922315974dcfae5659b503a672b19026fdb.zip |
Implement GPUTexture and GPUTextureView
Diffstat (limited to 'components/script/dom/gputexture.rs')
-rw-r--r-- | components/script/dom/gputexture.rs | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs new file mode 100644 index 00000000000..036c1a57307 --- /dev/null +++ b/components/script/dom/gputexture.rs @@ -0,0 +1,188 @@ +/* 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::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::{ + GPUExtent3DDict, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods, +}; +use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::{ + GPUTextureAspect, GPUTextureViewDescriptor, +}; +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::gpudevice::{convert_texture_format, convert_texture_view_dimension}; +use crate::dom::gputextureview::GPUTextureView; +use dom_struct::dom_struct; +use std::cell::Cell; +use webgpu::{wgt, WebGPU, WebGPUDevice, WebGPURequest, WebGPUTexture, WebGPUTextureView}; + +#[dom_struct] +pub struct GPUTexture { + reflector_: Reflector, + texture: WebGPUTexture, + label: DomRefCell<Option<DOMString>>, + device: WebGPUDevice, + #[ignore_malloc_size_of = "channels are hard"] + channel: WebGPU, + #[ignore_malloc_size_of = "defined in webgpu"] + texture_size: GPUExtent3DDict, + mip_level_count: u32, + sample_count: u32, + dimension: GPUTextureDimension, + format: GPUTextureFormat, + texture_usage: u32, + valid: Cell<bool>, +} + +impl GPUTexture { + fn new_inherited( + texture: WebGPUTexture, + device: WebGPUDevice, + channel: WebGPU, + texture_size: GPUExtent3DDict, + mip_level_count: u32, + sample_count: u32, + dimension: GPUTextureDimension, + format: GPUTextureFormat, + texture_usage: u32, + valid: bool, + ) -> GPUTexture { + Self { + reflector_: Reflector::new(), + texture, + label: DomRefCell::new(None), + device, + channel, + texture_size, + mip_level_count, + sample_count, + dimension, + format, + texture_usage, + valid: Cell::new(valid), + } + } + + pub fn new( + global: &GlobalScope, + texture: WebGPUTexture, + device: WebGPUDevice, + channel: WebGPU, + texture_size: GPUExtent3DDict, + mip_level_count: u32, + sample_count: u32, + dimension: GPUTextureDimension, + format: GPUTextureFormat, + texture_usage: u32, + valid: bool, + ) -> DomRoot<GPUTexture> { + reflect_dom_object( + Box::new(GPUTexture::new_inherited( + texture, + device, + channel, + texture_size, + mip_level_count, + sample_count, + dimension, + format, + texture_usage, + valid, + )), + global, + ) + } +} + +impl Drop for GPUTexture { + fn drop(&mut self) { + self.Destroy() + } +} + +impl GPUTextureMethods for GPUTexture { + /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label + fn GetLabel(&self) -> Option<DOMString> { + self.label.borrow().clone() + } + + /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label + fn SetLabel(&self, value: Option<DOMString>) { + *self.label.borrow_mut() = value; + } + + /// https://gpuweb.github.io/gpuweb/#dom-gputexture-createview + fn CreateView(&self, descriptor: &GPUTextureViewDescriptor) -> DomRoot<GPUTextureView> { + let desc = wgt::TextureViewDescriptor { + label: Default::default(), + format: convert_texture_format(descriptor.format.unwrap_or(self.format)), + dimension: match descriptor.dimension { + Some(d) => convert_texture_view_dimension(d), + None => match self.dimension { + GPUTextureDimension::_1d => wgt::TextureViewDimension::D1, + GPUTextureDimension::_2d => { + if self.texture_size.depth > 1 && descriptor.arrayLayerCount == 0 { + wgt::TextureViewDimension::D2Array + } else { + wgt::TextureViewDimension::D2 + } + }, + GPUTextureDimension::_3d => wgt::TextureViewDimension::D3, + }, + }, + aspect: match descriptor.aspect { + GPUTextureAspect::All => wgt::TextureAspect::All, + GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly, + GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly, + }, + base_mip_level: descriptor.baseMipLevel, + level_count: if descriptor.mipLevelCount == 0 { + self.mip_level_count - descriptor.baseMipLevel + } else { + descriptor.mipLevelCount + }, + base_array_layer: descriptor.baseArrayLayer, + array_layer_count: if descriptor.arrayLayerCount == 0 { + self.texture_size.depth - descriptor.baseArrayLayer + } else { + descriptor.arrayLayerCount + }, + }; + + let texture_view_id = self + .global() + .wgpu_id_hub() + .lock() + .create_texture_view_id(self.device.0.backend()); + + self.channel + .0 + .send(WebGPURequest::CreateTextureView { + texture_id: self.texture.0, + texture_view_id, + descriptor: desc, + }) + .expect("Failed to create WebGPU texture view"); + + let texture_view = WebGPUTextureView(texture_view_id); + + GPUTextureView::new(&self.global(), texture_view, self.device, true) + } + + /// https://gpuweb.github.io/gpuweb/#dom-gputexture-destroy + fn Destroy(&self) { + if let Err(e) = self + .channel + .0 + .send(WebGPURequest::DestroyTexture(self.texture.0)) + { + warn!( + "Failed to send WebGPURequest::DestroyTexture({:?}) ({})", + self.texture.0, e + ); + }; + } +} |