diff options
author | Kunal Mohan <kunalmohan99@gmail.com> | 2020-06-04 19:28:25 +0530 |
---|---|---|
committer | Kunal Mohan <kunalmohan99@gmail.com> | 2020-06-13 17:46:12 +0530 |
commit | 71401e0855c24e4cf86a754171f0162ae08d8e55 (patch) | |
tree | 34587c934aa127849ed943c44ec79f71ee904935 /components/script/dom/htmlcanvaselement.rs | |
parent | 73760ea59434971d24e6aac7e5fe3c79c1ba5bf6 (diff) | |
download | servo-71401e0855c24e4cf86a754171f0162ae08d8e55.tar.gz servo-71401e0855c24e4cf86a754171f0162ae08d8e55.zip |
Implement GPUSwapChain and GPUCanvasContext and interface with Webrender
Diffstat (limited to 'components/script/dom/htmlcanvaselement.rs')
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 87edeaeaab8..4b7d54b323d 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -20,13 +20,12 @@ use crate::dom::canvasrenderingcontext2d::{ use crate::dom::document::Document; use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers}; use crate::dom::globalscope::GlobalScope; +use crate::dom::gpucanvascontext::GPUCanvasContext; use crate::dom::htmlelement::HTMLElement; use crate::dom::node::{window_from_node, Node}; use crate::dom::virtualmethods::VirtualMethods; use crate::dom::webgl2renderingcontext::WebGL2RenderingContext; -use crate::dom::webglrenderingcontext::{ - LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext, -}; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::script_runtime::JSContext; use base64; use canvas_traits::canvas::{CanvasId, CanvasMsg, FromScriptMsg}; @@ -36,11 +35,12 @@ use euclid::default::{Rect, Size2D}; use html5ever::{LocalName, Prefix}; use image::png::PNGEncoder; use image::ColorType; -use ipc_channel::ipc::IpcSharedMemory; +use ipc_channel::ipc::{self as ipcchan, IpcSharedMemory}; use js::error::throw_type_error; use js::rust::HandleValue; use profile_traits::ipc; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; +use script_traits::ScriptMsg; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; const DEFAULT_WIDTH: u32 = 300; @@ -52,6 +52,7 @@ pub enum CanvasContext { Context2d(Dom<CanvasRenderingContext2D>), WebGL(Dom<WebGLRenderingContext>), WebGL2(Dom<WebGL2RenderingContext>), + WebGPU(Dom<GPUCanvasContext>), } #[dom_struct] @@ -95,6 +96,7 @@ impl HTMLCanvasElement { }, CanvasContext::WebGL(ref context) => context.recreate(size), CanvasContext::WebGL2(ref context) => context.recreate(size), + CanvasContext::WebGPU(_) => unimplemented!(), } } } @@ -111,6 +113,11 @@ impl HTMLCanvasElement { } } +pub trait LayoutCanvasRenderingContextHelpers { + #[allow(unsafe_code)] + unsafe fn canvas_data_source(self) -> HTMLCanvasDataSource; +} + pub trait LayoutHTMLCanvasElementHelpers { fn data(self) -> HTMLCanvasData; fn get_width(self) -> LengthOrPercentageOrAuto; @@ -132,6 +139,9 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { Some(&CanvasContext::WebGL2(ref context)) => { context.to_layout().canvas_data_source() }, + Some(&CanvasContext::WebGPU(ref context)) => { + context.to_layout().canvas_data_source() + }, None => HTMLCanvasDataSource::Image(None), } }; @@ -239,6 +249,26 @@ impl HTMLCanvasElement { Some(context) } + fn get_or_init_webgpu_context(&self) -> Option<DomRoot<GPUCanvasContext>> { + if let Some(ctx) = self.context() { + return match *ctx { + CanvasContext::WebGPU(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; + } + let (sender, receiver) = ipcchan::channel().unwrap(); + let _ = self + .global() + .script_to_constellation_chan() + .send(ScriptMsg::GetWebGPUChan(sender)); + let window = window_from_node(self); + let size = self.get_size(); + let channel = receiver.recv().expect("Failed to get WebGPU channel"); + let context = GPUCanvasContext::new(window.upcast::<GlobalScope>(), self, size, channel); + *self.context.borrow_mut() = Some(CanvasContext::WebGPU(Dom::from_ref(&*context))); + Some(context) + } + /// Gets the base WebGLRenderingContext for WebGL or WebGL 2, if exists. pub fn get_base_webgl_context(&self) -> Option<DomRoot<WebGLRenderingContext>> { match *self.context.borrow() { @@ -296,6 +326,10 @@ impl HTMLCanvasElement { // TODO: add a method in WebGL2RenderingContext to get the pixels. return None; }, + Some(&CanvasContext::WebGPU(_)) => { + // TODO: add a method in GPUCanvasContext to get the pixels. + return None; + }, None => None, }; @@ -333,6 +367,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { "webgl2" | "experimental-webgl2" => self .get_or_init_webgl2_context(cx, options) .map(RenderingContext::WebGL2RenderingContext), + "gpupresent" => self + .get_or_init_webgpu_context() + .map(RenderingContext::GPUCanvasContext), _ => None, } } @@ -371,6 +408,8 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { None => return Ok(USVString("data:,".into())), } }, + //TODO: Add method get_image_data to GPUCanvasContext + Some(CanvasContext::WebGPU(_)) => return Ok(USVString("data:,".into())), None => { // Each pixel is fully-transparent black. vec![0; (self.Width() * self.Height() * 4) as usize] |