canvas: Cleanup CanvasData and layout and script messages.

This commit is contained in:
Emilio Cobos Álvarez 2016-11-06 16:50:39 +01:00
parent 1c26f44cbb
commit 2e69143f6b
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
5 changed files with 49 additions and 24 deletions

View file

@ -12,7 +12,6 @@ use euclid::point::Point2D;
use euclid::rect::Rect; use euclid::rect::Rect;
use euclid::size::Size2D; use euclid::size::Size2D;
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::ipc::IpcSharedMemory;
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::mem; use std::mem;
@ -195,6 +194,13 @@ impl<'a> CanvasPaintThread<'a> {
CanvasCommonMsg::Recreate(size) => painter.recreate(size), CanvasCommonMsg::Recreate(size) => painter.recreate(size),
} }
}, },
CanvasMsg::FromScript(message) => {
match message {
FromScriptMsg::SendPixels(chan) => {
painter.send_pixels(chan)
}
}
}
CanvasMsg::FromLayout(message) => { CanvasMsg::FromLayout(message) => {
match message { match message {
FromLayoutMsg::SendData(chan) => { FromLayoutMsg::SendData(chan) => {
@ -539,6 +545,12 @@ impl<'a> CanvasPaintThread<'a> {
self.drawtarget = CanvasPaintThread::create(size); self.drawtarget = CanvasPaintThread::create(size);
} }
fn send_pixels(&mut self, chan: IpcSender<Option<Vec<u8>>>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
chan.send(Some(element.into())).unwrap();
})
}
fn send_data(&mut self, chan: IpcSender<CanvasData>) { fn send_data(&mut self, chan: IpcSender<CanvasData>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| { self.drawtarget.snapshot().get_data_surface().with_data(|element| {
let size = self.drawtarget.get_size(); let size = self.drawtarget.get_size();
@ -548,11 +560,10 @@ impl<'a> CanvasPaintThread<'a> {
webrender_traits::ImageFormat::RGBA8, webrender_traits::ImageFormat::RGBA8,
element.into()); element.into());
let pixel_data = CanvasPixelData { let data = CanvasImageData {
image_data: IpcSharedMemory::from_bytes(element),
image_key: self.webrender_image_key, image_key: self.webrender_image_key,
}; };
chan.send(CanvasData::Pixels(pixel_data)).unwrap(); chan.send(CanvasData::Image(data)).unwrap();
}) })
} }

View file

@ -2,11 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use canvas_traits::{CanvasCommonMsg, CanvasData, CanvasMsg, CanvasPixelData}; use canvas_traits::{CanvasCommonMsg, CanvasData, CanvasMsg, CanvasImageData};
use canvas_traits::{FromLayoutMsg, byte_swap}; use canvas_traits::{FromLayoutMsg, FromScriptMsg, byte_swap};
use euclid::size::Size2D; use euclid::size::Size2D;
use gleam::gl; use gleam::gl;
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; use ipc_channel::ipc::{self, IpcSender};
use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits}; use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits};
use offscreen_gl_context::{GLContextAttributes, NativeGLContext, OSMesaContext}; use offscreen_gl_context::{GLContextAttributes, NativeGLContext, OSMesaContext};
use std::borrow::ToOwned; use std::borrow::ToOwned;
@ -173,6 +173,15 @@ impl WebGLPaintThread {
CanvasCommonMsg::Recreate(size) => painter.recreate(size).unwrap(), CanvasCommonMsg::Recreate(size) => painter.recreate(size).unwrap(),
} }
}, },
CanvasMsg::FromScript(message) => {
match message {
FromScriptMsg::SendPixels(chan) =>{
// Read the comment on
// HTMLCanvasElement::fetch_all_data.
chan.send(None).unwrap();
}
}
}
CanvasMsg::FromLayout(message) => { CanvasMsg::FromLayout(message) => {
match message { match message {
FromLayoutMsg::SendData(chan) => FromLayoutMsg::SendData(chan) =>
@ -218,12 +227,11 @@ impl WebGLPaintThread {
webrender_traits::ImageFormat::RGBA8, webrender_traits::ImageFormat::RGBA8,
pixels.clone()); pixels.clone());
let pixel_data = CanvasPixelData { let image_data = CanvasImageData {
image_data: IpcSharedMemory::from_bytes(&pixels[..]),
image_key: image_key, image_key: image_key,
}; };
chan.send(CanvasData::Pixels(pixel_data)).unwrap(); chan.send(CanvasData::Image(image_data)).unwrap();
} }
WebGLPaintTaskData::WebRender(_, id) => { WebGLPaintTaskData::WebRender(_, id) => {
chan.send(CanvasData::WebGL(id)).unwrap(); chan.send(CanvasData::WebGL(id)).unwrap();

View file

@ -31,7 +31,7 @@ use euclid::matrix2d::Matrix2D;
use euclid::point::Point2D; use euclid::point::Point2D;
use euclid::rect::Rect; use euclid::rect::Rect;
use euclid::size::Size2D; use euclid::size::Size2D;
use ipc_channel::ipc::{IpcSender, IpcSharedMemory}; use ipc_channel::ipc::IpcSender;
use std::default::Default; use std::default::Default;
use std::str::FromStr; use std::str::FromStr;
use webrender_traits::{WebGLCommand, WebGLContextId}; use webrender_traits::{WebGLCommand, WebGLContextId};
@ -47,6 +47,7 @@ pub enum CanvasMsg {
Canvas2d(Canvas2dMsg), Canvas2d(Canvas2dMsg),
Common(CanvasCommonMsg), Common(CanvasCommonMsg),
FromLayout(FromLayoutMsg), FromLayout(FromLayoutMsg),
FromScript(FromScriptMsg),
WebGL(WebGLCommand), WebGL(WebGLCommand),
} }
@ -58,13 +59,12 @@ pub enum CanvasCommonMsg {
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
pub enum CanvasData { pub enum CanvasData {
Pixels(CanvasPixelData), Image(CanvasImageData),
WebGL(WebGLContextId), WebGL(WebGLContextId),
} }
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
pub struct CanvasPixelData { pub struct CanvasImageData {
pub image_data: IpcSharedMemory,
pub image_key: webrender_traits::ImageKey, pub image_key: webrender_traits::ImageKey,
} }
@ -73,6 +73,11 @@ pub enum FromLayoutMsg {
SendData(IpcSender<CanvasData>), SendData(IpcSender<CanvasData>),
} }
#[derive(Clone, Deserialize, Serialize)]
pub enum FromScriptMsg {
SendPixels(IpcSender<Option<Vec<u8>>>),
}
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
pub enum Canvas2dMsg { pub enum Canvas2dMsg {
Arc(Point2D<f32>, f32, f32, f32, bool), Arc(Point2D<f32>, f32, f32, f32, bool),

View file

@ -1436,16 +1436,16 @@ impl FragmentDisplayListBuilding for Fragment {
self.style.get_cursor(Cursor::Default), self.style.get_cursor(Cursor::Default),
DisplayListSection::Content); DisplayListSection::Content);
let display_item = match canvas_data { let display_item = match canvas_data {
CanvasData::Pixels(canvas_data) => { CanvasData::Image(canvas_data) => {
DisplayItem::Image(box ImageDisplayItem { DisplayItem::Image(box ImageDisplayItem {
base: base, base: base,
image_data: Some(Arc::new(canvas_data.image_data)),
webrender_image: WebRenderImageInfo { webrender_image: WebRenderImageInfo {
width: computed_width as u32, width: computed_width as u32,
height: computed_height as u32, height: computed_height as u32,
format: PixelFormat::RGBA8, format: PixelFormat::RGBA8,
key: Some(canvas_data.image_key), key: Some(canvas_data.image_key),
}, },
image_data: None,
stretch_size: stacking_relative_content_box.size, stretch_size: stacking_relative_content_box.size,
tile_spacing: Size2D::zero(), tile_spacing: Size2D::zero(),
image_rendering: image_rendering::T::auto, image_rendering: image_rendering::T::auto,

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use canvas_traits::{CanvasMsg, FromLayoutMsg, CanvasData}; use canvas_traits::{CanvasMsg, FromScriptMsg};
use dom::attr::Attr; use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods; use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
@ -202,16 +202,17 @@ impl HTMLCanvasElement {
let data = if let Some(renderer) = self.ipc_renderer() { let data = if let Some(renderer) = self.ipc_renderer() {
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender)); let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
renderer.send(msg).unwrap(); renderer.send(msg).unwrap();
match receiver.recv().unwrap() { match receiver.recv().unwrap() {
CanvasData::Pixels(pixel_data) Some(pixels) => pixels,
=> pixel_data.image_data.to_vec(), None => {
CanvasData::WebGL(_) // TODO(emilio, #14109): Not sure if WebGL canvas is
// TODO(emilio): Not sure if WebGL canvas is required for 2d spec, // required for 2d spec, but I think it's not, if so, make
// but I think it's not. // this return a readback from the GL context.
=> return None, return None;
}
} }
} else { } else {
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect() repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()