mirror of
https://github.com/servo/servo.git
synced 2025-07-29 10:10:34 +01:00
WebGL context hardware acceleration + error detection
This commit is contained in:
parent
ea00e949a4
commit
79a5dae170
10 changed files with 172 additions and 94 deletions
|
@ -169,24 +169,37 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
|
|||
|
||||
fn GetContext(self, id: DOMString) -> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||
match &*id {
|
||||
"2d" => {
|
||||
let context_2d = self.context_2d.or_init(|| {
|
||||
let window = window_from_node(self).root();
|
||||
let size = self.get_size();
|
||||
CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size)
|
||||
});
|
||||
Some(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(Unrooted::from_temporary(context_2d)))
|
||||
}
|
||||
"webgl" | "experimental-webgl" => {
|
||||
let context_webgl = self.context_webgl.or_init(|| {
|
||||
let window = window_from_node(self).root();
|
||||
let size = self.get_size();
|
||||
WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size)
|
||||
});
|
||||
Some(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(Unrooted::from_temporary(context_webgl)))
|
||||
}
|
||||
_ => return None
|
||||
}
|
||||
"2d" => {
|
||||
if self.context_webgl.get().is_some() {
|
||||
debug!("Trying to get a 2d context for a canvas with an already initialized WebGL context");
|
||||
return None;
|
||||
}
|
||||
|
||||
let context_2d = self.context_2d.or_init(|| {
|
||||
let window = window_from_node(self).root();
|
||||
let size = self.get_size();
|
||||
CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size)
|
||||
});
|
||||
Some(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(Unrooted::from_temporary(context_2d)))
|
||||
}
|
||||
"webgl" | "experimental-webgl" => {
|
||||
if self.context_2d.get().is_some() {
|
||||
debug!("Trying to get a WebGL context for a canvas with an already initialized 2d context");
|
||||
return None;
|
||||
}
|
||||
|
||||
if !self.context_webgl.get().is_some() {
|
||||
let window = window_from_node(self).root();
|
||||
let size = self.get_size();
|
||||
|
||||
self.context_webgl.assign(WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size))
|
||||
}
|
||||
|
||||
self.context_webgl.get().map( |ctx|
|
||||
CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(Unrooted::from_temporary(ctx)))
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,11 +239,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> {
|
|||
let value = attr.value();
|
||||
let recreate = match attr.local_name() {
|
||||
&atom!("width") => {
|
||||
self.width.set(parse_unsigned_integer(value.chars()).unwrap_or(DEFAULT_WIDTH));
|
||||
self.width.set(parse_unsigned_integer(value.as_slice().chars()).unwrap_or(DEFAULT_WIDTH));
|
||||
true
|
||||
}
|
||||
&atom!("height") => {
|
||||
self.height.set(parse_unsigned_integer(value.chars()).unwrap_or(DEFAULT_HEIGHT));
|
||||
self.height.set(parse_unsigned_integer(value.as_slice().chars()).unwrap_or(DEFAULT_HEIGHT));
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
|
|
|
@ -23,25 +23,32 @@ pub struct WebGLRenderingContext {
|
|||
|
||||
impl WebGLRenderingContext {
|
||||
fn new_inherited(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
|
||||
-> WebGLRenderingContext {
|
||||
WebGLRenderingContext {
|
||||
-> Result<WebGLRenderingContext, &'static str> {
|
||||
let chan = try!(WebGLPaintTask::start(size));
|
||||
|
||||
Ok(WebGLRenderingContext {
|
||||
reflector_: Reflector::new(),
|
||||
global: GlobalField::from_rooted(&global),
|
||||
renderer: WebGLPaintTask::start(size),
|
||||
renderer: chan,
|
||||
canvas: JS::from_rooted(canvas),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
|
||||
-> Temporary<WebGLRenderingContext> {
|
||||
reflect_dom_object(box WebGLRenderingContext::new_inherited(global, canvas, size),
|
||||
global, WebGLRenderingContextBinding::Wrap)
|
||||
-> Option<Temporary<WebGLRenderingContext>> {
|
||||
match WebGLRenderingContext::new_inherited(global, canvas, size) {
|
||||
Ok(ctx) => Some(reflect_dom_object(box ctx, global,
|
||||
WebGLRenderingContextBinding::Wrap)),
|
||||
Err(msg) => {
|
||||
error!("Couldn't create WebGLRenderingContext: {}", msg);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recreate(&self, size: Size2D<i32>) {
|
||||
self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
|
@ -72,4 +79,3 @@ impl LayoutCanvasWebGLRenderingContextHelpers for LayoutJS<WebGLRenderingContext
|
|||
(*self.unsafe_get()).renderer.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://www.whatwg.org/html/#htmlcanvaselement
|
||||
// https://www.whatwg.org/html/#htmlcanvaselement
|
||||
typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
|
||||
|
||||
interface HTMLCanvasElement : HTMLElement {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue