mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Improve WebGL architecture.
This commit is contained in:
parent
e9cbbc58cc
commit
703962fe61
54 changed files with 3154 additions and 1426 deletions
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use base64;
|
||||
use canvas_traits::{CanvasMsg, FromScriptMsg};
|
||||
use canvas_traits::canvas::{CanvasMsg, FromScriptMsg};
|
||||
use dom::attr::Attr;
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||
|
@ -30,11 +30,11 @@ use euclid::Size2D;
|
|||
use html5ever::{LocalName, Prefix};
|
||||
use image::ColorType;
|
||||
use image::png::PNGEncoder;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::ipc;
|
||||
use js::error::throw_type_error;
|
||||
use js::jsapi::{HandleValue, JSContext};
|
||||
use offscreen_gl_context::GLContextAttributes;
|
||||
use script_layout_interface::HTMLCanvasData;
|
||||
use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
|
||||
use std::iter::repeat;
|
||||
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
||||
|
||||
|
@ -106,21 +106,22 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
|||
fn data(&self) -> HTMLCanvasData {
|
||||
unsafe {
|
||||
let canvas = &*self.unsafe_get();
|
||||
let ipc_renderer = canvas.context.borrow_for_layout().as_ref().map(|context| {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => {
|
||||
context.to_layout().get_ipc_renderer()
|
||||
},
|
||||
CanvasContext::WebGL(ref context) => {
|
||||
context.to_layout().get_ipc_renderer()
|
||||
},
|
||||
let source = match canvas.context.borrow_for_layout().as_ref() {
|
||||
Some(&CanvasContext::Context2d(ref context)) => {
|
||||
HTMLCanvasDataSource::Image(Some(context.to_layout().get_ipc_renderer()))
|
||||
},
|
||||
Some(&CanvasContext::WebGL(ref context)) => {
|
||||
context.to_layout().canvas_data_source()
|
||||
},
|
||||
None => {
|
||||
HTMLCanvasDataSource::Image(None)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let width_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &local_name!("width"));
|
||||
let height_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &local_name!("height"));
|
||||
HTMLCanvasData {
|
||||
ipc_renderer: ipc_renderer,
|
||||
source: source,
|
||||
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
|
||||
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
|
||||
}
|
||||
|
@ -150,15 +151,6 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
|||
|
||||
|
||||
impl HTMLCanvasElement {
|
||||
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||
self.context.borrow().as_ref().map(|context| {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
|
@ -221,22 +213,26 @@ impl HTMLCanvasElement {
|
|||
return None
|
||||
}
|
||||
|
||||
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
|
||||
renderer.send(msg).unwrap();
|
||||
let data = match self.context.borrow().as_ref() {
|
||||
Some(&CanvasContext::Context2d(ref context)) => {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
|
||||
context.get_ipc_renderer().send(msg).unwrap();
|
||||
|
||||
match receiver.recv().unwrap() {
|
||||
Some(pixels) => pixels,
|
||||
None => {
|
||||
// TODO(emilio, #14109): Not sure if WebGL canvas is
|
||||
// required for 2d spec, but I think it's not, if so, make
|
||||
// this return a readback from the GL context.
|
||||
return None;
|
||||
match receiver.recv().unwrap() {
|
||||
Some(pixels) => pixels,
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(&CanvasContext::WebGL(_)) => {
|
||||
// TODO: add a method in WebGLRenderingContext to get the pixels.
|
||||
return None;
|
||||
},
|
||||
None => {
|
||||
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||
}
|
||||
} else {
|
||||
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||
};
|
||||
|
||||
Some((data, size))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue