servo: Merge #11506 - Make canvas send their data themselves to other canvas (from nox:slither); r=emilio
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 17 Jun 2016 02:07:37 -0500
changeset 339084 b8c8c76a17aa915dd8e2bfa63d98ab862173db78
parent 339083 22f916cd1fa7df071afc8a603d44dad470ae9158
child 339085 0bfaf96930a643e7be24851204deb6af383356e9
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #11506 - Make canvas send their data themselves to other canvas (from nox:slither); r=emilio Source-Repo: https://github.com/servo/servo Source-Revision: 5a0c98afb2998e7990e1c813f2bc15fe3c191638
servo/components/canvas/canvas_paint_thread.rs
servo/components/canvas_traits/lib.rs
servo/components/script/Cargo.toml
servo/components/script/dom/canvasrenderingcontext2d.rs
servo/components/script/lib.rs
servo/components/servo/Cargo.lock
servo/ports/cef/Cargo.lock
--- a/servo/components/canvas/canvas_paint_thread.rs
+++ b/servo/components/canvas/canvas_paint_thread.rs
@@ -143,16 +143,22 @@ impl<'a> CanvasPaintThread<'a> {
                             },
                             Canvas2dMsg::DrawImage(imagedata, image_size, dest_rect, source_rect,
                                                    smoothing_enabled) => {
                                 painter.draw_image(imagedata, image_size, dest_rect, source_rect, smoothing_enabled)
                             }
                             Canvas2dMsg::DrawImageSelf(image_size, dest_rect, source_rect, smoothing_enabled) => {
                                 painter.draw_image_self(image_size, dest_rect, source_rect, smoothing_enabled)
                             }
+                            Canvas2dMsg::DrawImageInOther(
+                                renderer, image_size, dest_rect, source_rect, smoothing, sender
+                            ) => {
+                                painter.draw_image_in_other(
+                                    renderer, image_size, dest_rect, source_rect, smoothing, sender)
+                            }
                             Canvas2dMsg::MoveTo(ref point) => painter.move_to(point),
                             Canvas2dMsg::LineTo(ref point) => painter.line_to(point),
                             Canvas2dMsg::Rect(ref rect) => painter.rect(rect),
                             Canvas2dMsg::QuadraticCurveTo(ref cp, ref pt) => {
                                 painter.quadratic_curve_to(cp, pt)
                             }
                             Canvas2dMsg::BezierCurveTo(ref cp1, ref cp2, ref pt) => {
                                 painter.bezier_curve_to(cp1, cp2, pt)
@@ -366,16 +372,36 @@ impl<'a> CanvasPaintThread<'a> {
         } else {
             // Writes on target canvas
             write_image(&self.drawtarget, image_data, image_size, dest_rect,
                         smoothing_enabled, self.state.draw_options.composition,
                         self.state.draw_options.alpha);
         }
     }
 
+    fn draw_image_in_other(&self,
+                           renderer: IpcSender<CanvasMsg>,
+                           image_size: Size2D<f64>,
+                           dest_rect: Rect<f64>,
+                           source_rect: Rect<f64>,
+                           smoothing_enabled: bool,
+                           sender: IpcSender<()>) {
+        let mut image_data = self.read_pixels(source_rect.to_i32(), image_size);
+        // TODO: avoid double byte_swap.
+        byte_swap(&mut image_data);
+
+        let msg = CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(
+            image_data, source_rect.size, dest_rect, source_rect, smoothing_enabled));
+        renderer.send(msg).unwrap();
+        // We acknowledge to the caller here that the data was sent to the
+        // other canvas so that if JS immediately afterwards try to get the
+        // pixels of the other one, it won't retrieve the other values.
+        sender.send(()).unwrap();
+    }
+
     fn move_to(&self, point: &Point2D<AzFloat>) {
         self.path_builder.move_to(*point)
     }
 
     fn line_to(&self, point: &Point2D<AzFloat>) {
         self.path_builder.line_to(*point)
     }
 
--- a/servo/components/canvas_traits/lib.rs
+++ b/servo/components/canvas_traits/lib.rs
@@ -74,16 +74,18 @@ pub enum FromLayoutMsg {
 }
 
 #[derive(Clone, Deserialize, Serialize)]
 pub enum Canvas2dMsg {
     Arc(Point2D<f32>, f32, f32, f32, bool),
     ArcTo(Point2D<f32>, Point2D<f32>, f32),
     DrawImage(Vec<u8>, Size2D<f64>, Rect<f64>, Rect<f64>, bool),
     DrawImageSelf(Size2D<f64>, Rect<f64>, Rect<f64>, bool),
+    DrawImageInOther(
+        IpcSender<CanvasMsg>, Size2D<f64>, Rect<f64>, Rect<f64>, bool, IpcSender<()>),
     BeginPath,
     BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>),
     ClearRect(Rect<f32>),
     Clip,
     ClosePath,
     Fill,
     FillRect(Rect<f32>),
     GetImageData(Rect<i32>, Size2D<f64>, IpcSender<Vec<u8>>),
--- a/servo/components/script/Cargo.toml
+++ b/servo/components/script/Cargo.toml
@@ -15,17 +15,16 @@ debugmozjs = ['js/debugmozjs']
 
 [target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
 tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}
 
 [dependencies]
 angle = {git = "https://github.com/servo/angle", branch = "servo"}
 app_units = {version = "0.2.3", features = ["plugins"]}
 bitflags = "0.7"
-canvas = {path = "../canvas"}
 canvas_traits = {path = "../canvas_traits"}
 caseless = "0.1.0"
 cssparser = {version = "0.5.4", features = ["heap_size", "serde-serialization"]}
 devtools_traits = {path = "../devtools_traits"}
 encoding = "0.2"
 euclid = {version = "0.6.4", features = ["plugins"]}
 fnv = "1.0"
 gfx_traits = {path = "../gfx_traits"}
--- a/servo/components/script/dom/canvasrenderingcontext2d.rs
+++ b/servo/components/script/dom/canvasrenderingcontext2d.rs
@@ -1,13 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
-use canvas::canvas_paint_thread::RectToi32;
 use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg};
 use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle};
 use canvas_traits::{FillOrStrokeStyle, FillRule, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
 use cssparser::Color as CSSColor;
 use cssparser::{Parser, RGBA};
 use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
 use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding;
@@ -358,46 +357,40 @@ impl CanvasRenderingContext2D {
                                                                      dh);
 
         if !is_rect_valid(source_rect) || !is_rect_valid(dest_rect) {
             return Err(Error::IndexSize);
         }
 
         let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
 
-        // If the source and target canvas are the same
-        let msg = if &*self.canvas == canvas {
-            CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageSelf(image_size,
-                                                           dest_rect,
-                                                           source_rect,
-                                                           smoothing_enabled))
+        if &*self.canvas == canvas {
+            let msg = CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageSelf(
+                image_size, dest_rect, source_rect, smoothing_enabled));
+            self.ipc_renderer.send(msg).unwrap();
         } else {
-            // Source and target canvases are different
             let context = match canvas.get_or_init_2d_context() {
                 Some(context) => context,
                 None => return Err(Error::InvalidState),
             };
 
+            let (sender, receiver) = ipc::channel().unwrap();
+            let msg = CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageInOther(
+                self.ipc_renderer.clone(),
+                image_size,
+                dest_rect,
+                source_rect,
+                smoothing_enabled,
+                sender));
+
             let renderer = context.get_ipc_renderer();
-            let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
-            // Reads pixels from source image
-            renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect.to_i32(),
-                                                                        image_size,
-                                                                        sender)))
-                    .unwrap();
-            let imagedata = receiver.recv().unwrap();
-            // Writes pixels to destination canvas
-            CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(imagedata,
-                                                       source_rect.size,
-                                                       dest_rect,
-                                                       source_rect,
-                                                       smoothing_enabled))
+            renderer.send(msg).unwrap();
+            receiver.recv().unwrap();
         };
 
-        self.ipc_renderer.send(msg).unwrap();
         self.mark_as_dirty();
         Ok(())
     }
 
     fn draw_image_data(&self,
                        image_data: Vec<u8>,
                        image_size: Size2D<f64>,
                        sx: f64,
--- a/servo/components/script/lib.rs
+++ b/servo/components/script/lib.rs
@@ -29,17 +29,16 @@
 #![plugin(phf_macros)]
 #![plugin(plugins)]
 
 extern crate angle;
 extern crate app_units;
 #[allow(unused_extern_crates)]
 #[macro_use]
 extern crate bitflags;
-extern crate canvas;
 extern crate canvas_traits;
 extern crate caseless;
 extern crate core;
 #[macro_use]
 extern crate cssparser;
 extern crate devtools_traits;
 extern crate encoding;
 extern crate euclid;
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -1869,17 +1869,16 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "script"
 version = "0.0.1"
 dependencies = [
  "angle 0.1.0 (git+https://github.com/servo/angle?branch=servo)",
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "canvas 0.0.1",
  "canvas_traits 0.0.1",
  "caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "devtools_traits 0.0.1",
  "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx_traits 0.0.1",
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -1727,17 +1727,16 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "script"
 version = "0.0.1"
 dependencies = [
  "angle 0.1.0 (git+https://github.com/servo/angle?branch=servo)",
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "canvas 0.0.1",
  "canvas_traits 0.0.1",
  "caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "devtools_traits 0.0.1",
  "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx_traits 0.0.1",