mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Don't create 2D canvas contexts arbitrarily
Sometimes, the canvas still has no rendering context, in this case it represents a transparent black rectangle.
This commit is contained in:
parent
ed673f8070
commit
f1e8eb640c
4 changed files with 107 additions and 90 deletions
|
@ -37,9 +37,10 @@ use js::jsapi::JSContext;
|
|||
use js::rust::HandleValue;
|
||||
use offscreen_gl_context::GLContextAttributes;
|
||||
use profile_traits::ipc;
|
||||
use ref_filter_map;
|
||||
use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
|
||||
use servo_config::prefs::PREFS;
|
||||
use std::iter::repeat;
|
||||
use std::cell::Ref;
|
||||
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
||||
|
||||
const DEFAULT_WIDTH: u32 = 300;
|
||||
|
@ -174,18 +175,22 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<HTMLCanvasElement> {
|
|||
|
||||
|
||||
impl HTMLCanvasElement {
|
||||
pub fn get_or_init_2d_context(&self) -> Option<DomRoot<CanvasRenderingContext2D>> {
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let context = CanvasRenderingContext2D::new(window.upcast::<GlobalScope>(), self, size);
|
||||
*self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context)));
|
||||
}
|
||||
pub fn context(&self) -> Option<Ref<CanvasContext>> {
|
||||
ref_filter_map::ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref())
|
||||
}
|
||||
|
||||
match *self.context.borrow().as_ref().unwrap() {
|
||||
CanvasContext::Context2d(ref context) => Some(DomRoot::from_ref(&*context)),
|
||||
_ => None,
|
||||
fn get_or_init_2d_context(&self) -> Option<DomRoot<CanvasRenderingContext2D>> {
|
||||
if let Some(ctx) = self.context() {
|
||||
return match *ctx {
|
||||
CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let context = CanvasRenderingContext2D::new(window.upcast::<GlobalScope>(), self, size);
|
||||
*self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context)));
|
||||
Some(context)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -194,20 +199,18 @@ impl HTMLCanvasElement {
|
|||
cx: *mut JSContext,
|
||||
options: HandleValue,
|
||||
) -> Option<DomRoot<WebGLRenderingContext>> {
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let attrs = Self::get_gl_attributes(cx, options)?;
|
||||
let maybe_ctx = WebGLRenderingContext::new(&window, self, WebGLVersion::WebGL1, size, attrs);
|
||||
|
||||
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(Dom::from_ref(&*ctx)));
|
||||
}
|
||||
|
||||
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||
Some(DomRoot::from_ref(&*context))
|
||||
} else {
|
||||
None
|
||||
if let Some(ctx) = self.context() {
|
||||
return match *ctx {
|
||||
CanvasContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let attrs = Self::get_gl_attributes(cx, options)?;
|
||||
let context = WebGLRenderingContext::new(&window, self, WebGLVersion::WebGL1, size, attrs)?;
|
||||
*self.context.borrow_mut() = Some(CanvasContext::WebGL(Dom::from_ref(&*context)));
|
||||
Some(context)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -219,20 +222,18 @@ impl HTMLCanvasElement {
|
|||
if !PREFS.is_webgl2_enabled() {
|
||||
return None
|
||||
}
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let attrs = Self::get_gl_attributes(cx, options)?;
|
||||
let maybe_ctx = WebGL2RenderingContext::new(&window, self, size, attrs);
|
||||
|
||||
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL2(Dom::from_ref(&*ctx)));
|
||||
}
|
||||
|
||||
if let Some(CanvasContext::WebGL2(ref context)) = *self.context.borrow() {
|
||||
Some(DomRoot::from_ref(&*context))
|
||||
} else {
|
||||
None
|
||||
if let Some(ctx) = self.context() {
|
||||
return match *ctx {
|
||||
CanvasContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let attrs = Self::get_gl_attributes(cx, options)?;
|
||||
let context = WebGL2RenderingContext::new(&window, self, size, attrs)?;
|
||||
*self.context.borrow_mut() = Some(CanvasContext::WebGL2(Dom::from_ref(&*context)));
|
||||
Some(context)
|
||||
}
|
||||
|
||||
/// Gets the base WebGLRenderingContext for WebGL or WebGL 2, if exists.
|
||||
|
@ -289,9 +290,7 @@ impl HTMLCanvasElement {
|
|||
// TODO: add a method in WebGL2RenderingContext to get the pixels.
|
||||
return None;
|
||||
},
|
||||
None => {
|
||||
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||
}
|
||||
None => vec![0; size.height as usize * size.width as usize * 4]
|
||||
};
|
||||
|
||||
Some((data, size))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue