aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlcanvaselement.rs
diff options
context:
space:
mode:
authorKunal Mohan <kunalmohan99@gmail.com>2020-06-04 19:28:25 +0530
committerKunal Mohan <kunalmohan99@gmail.com>2020-06-13 17:46:12 +0530
commit71401e0855c24e4cf86a754171f0162ae08d8e55 (patch)
tree34587c934aa127849ed943c44ec79f71ee904935 /components/script/dom/htmlcanvaselement.rs
parent73760ea59434971d24e6aac7e5fe3c79c1ba5bf6 (diff)
downloadservo-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.rs47
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]