diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 9aef15d26fd..8fc311a1982 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -11,6 +11,7 @@ use gleam::gl; use half::f16; use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods}; use pixels::{self, PixelFormat}; +use std::borrow::Cow; use std::thread; /// WebGL Threading API entry point that lives in the constellation. @@ -1057,7 +1058,7 @@ impl WebGLImpl { alpha_treatment, y_axis_treatment, pixel_format, - ref receiver, + ref data, } => { let pixels = prepare_pixels( format, @@ -1067,7 +1068,7 @@ impl WebGLImpl { alpha_treatment, y_axis_treatment, pixel_format, - receiver.recv().unwrap(), + Cow::Borrowed(data), ); ctx.gl() @@ -1097,7 +1098,7 @@ impl WebGLImpl { alpha_treatment, y_axis_treatment, pixel_format, - ref receiver, + ref data, } => { let pixels = prepare_pixels( format, @@ -1107,7 +1108,7 @@ impl WebGLImpl { alpha_treatment, y_axis_treatment, pixel_format, - receiver.recv().unwrap(), + Cow::Borrowed(data), ); ctx.gl() @@ -1743,8 +1744,8 @@ fn prepare_pixels( alpha_treatment: Option, y_axis_treatment: YAxisTreatment, pixel_format: Option, - mut pixels: Vec, -) -> Vec { + mut pixels: Cow<[u8]>, +) -> Cow<[u8]> { match alpha_treatment { Some(AlphaTreatment::Premultiply) => { if let Some(pixel_format) = pixel_format { @@ -1752,20 +1753,26 @@ fn prepare_pixels( PixelFormat::BGRA8 | PixelFormat::RGBA8 => {}, _ => unimplemented!("unsupported pixel format ({:?})", pixel_format), } - premultiply_inplace(TexFormat::RGBA, TexDataType::UnsignedByte, &mut pixels); + premultiply_inplace(TexFormat::RGBA, TexDataType::UnsignedByte, pixels.to_mut()); } else { - premultiply_inplace(internal_format, data_type, &mut pixels); + premultiply_inplace(internal_format, data_type, pixels.to_mut()); } }, Some(AlphaTreatment::Unmultiply) => { assert!(pixel_format.is_some()); - unmultiply_inplace(&mut pixels); + unmultiply_inplace(pixels.to_mut()); }, None => {}, } if let Some(pixel_format) = pixel_format { - pixels = image_to_tex_image_data(pixel_format, internal_format, data_type, pixels); + pixels = image_to_tex_image_data( + pixel_format, + internal_format, + data_type, + pixels.into_owned(), + ) + .into(); } if y_axis_treatment == YAxisTreatment::Flipped { @@ -1776,8 +1783,9 @@ fn prepare_pixels( size.width as usize, size.height as usize, unpacking_alignment as usize, - pixels, - ); + pixels.into_owned(), + ) + .into(); } pixels diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 7e0efd67bcd..3ef88844e50 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -4,7 +4,7 @@ use euclid::{Rect, Size2D}; use gleam::gl; -use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender}; +use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSharedMemory}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use pixels::PixelFormat; use serde_bytes::ByteBuf; @@ -284,7 +284,7 @@ pub enum WebGLCommand { alpha_treatment: Option, y_axis_treatment: YAxisTreatment, pixel_format: Option, - receiver: IpcBytesReceiver, + data: IpcSharedMemory, }, TexSubImage2D { target: u32, @@ -300,7 +300,7 @@ pub enum WebGLCommand { alpha_treatment: Option, y_axis_treatment: YAxisTreatment, pixel_format: Option, - receiver: IpcBytesReceiver, + data: IpcSharedMemory, }, DrawingBufferWidth(WebGLSender), DrawingBufferHeight(WebGLSender), diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index 2d7fb22ba09..9566c7b0f39 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; use euclid::{Rect, Size2D}; +use ipc_channel::ipc::IpcSharedMemory; use js::jsapi::{Heap, JSContext, JSObject}; use js::rust::Runtime; use js::typedarray::{CreateWith, Uint8ClampedArray}; @@ -156,8 +157,8 @@ impl ImageData { } #[allow(unsafe_code)] - pub fn to_vec(&self) -> Vec { - unsafe { self.as_slice().into() } + pub fn to_shared_memory(&self) -> IpcSharedMemory { + IpcSharedMemory::from_bytes(unsafe { self.as_slice() }) } #[allow(unsafe_code)] diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 49d3a9d05ff..07ab777e631 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -57,7 +57,7 @@ use crate::dom::webglvertexarrayobjectoes::WebGLVertexArrayObjectOES; use crate::dom::window::Window; use dom_struct::dom_struct; use euclid::{Point2D, Rect, Size2D}; -use ipc_channel::ipc; +use ipc_channel::ipc::{self, IpcSharedMemory}; use js::jsapi::{JSContext, JSObject, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, UInt32Value}; use js::jsval::{NullValue, ObjectValue, UndefinedValue}; @@ -504,7 +504,12 @@ impl WebGLRenderingContext { level, 0, 1, - TexPixels::new(pixels, size, PixelFormat::RGBA8, true), + TexPixels::new( + IpcSharedMemory::from_bytes(&pixels), + size, + PixelFormat::RGBA8, + true, + ), ); false @@ -527,7 +532,7 @@ impl WebGLRenderingContext { fn get_image_pixels(&self, source: TexImageSource) -> Fallible> { Ok(Some(match source { TexImageSource::ImageData(image_data) => TexPixels::new( - image_data.to_vec(), + image_data.to_shared_memory(), image_data.get_size(), PixelFormat::RGBA8, false, @@ -554,7 +559,7 @@ impl WebGLRenderingContext { let size = Size2D::new(img.width, img.height); - TexPixels::new(img.bytes.to_vec(), size, img.format, false) + TexPixels::new(img.bytes.clone(), size, img.format, false) }, // TODO(emilio): Getting canvas data is implemented in CanvasRenderingContext2D, // but we need to refactor it moving it to `HTMLCanvasElement` and support @@ -564,7 +569,12 @@ impl WebGLRenderingContext { return Err(Error::Security); } if let Some((data, size)) = canvas.fetch_all_data() { - TexPixels::new(data, size, PixelFormat::BGRA8, true) + TexPixels::new( + IpcSharedMemory::from_bytes(&data), + size, + PixelFormat::BGRA8, + true, + ) } else { return Ok(None); } @@ -676,8 +686,7 @@ impl WebGLRenderingContext { .extension_manager .effective_type(data_type.as_gl_constant()); - // TODO(emilio): convert colorspace if requested - let (sender, receiver) = ipc::bytes_channel().unwrap(); + // TODO(emilio): convert colorspace if requested. self.send_command(WebGLCommand::TexImage2D { target: target.as_gl_constant(), level, @@ -690,9 +699,8 @@ impl WebGLRenderingContext { alpha_treatment, y_axis_treatment, pixel_format: pixels.pixel_format, - receiver, + data: pixels.data, }); - sender.send(&pixels.data).unwrap(); if let Some(fb) = self.bound_framebuffer.get() { fb.invalidate_texture(&*texture); @@ -752,8 +760,7 @@ impl WebGLRenderingContext { .extension_manager .effective_type(data_type.as_gl_constant()); - // TODO(emilio): convert colorspace if requested - let (sender, receiver) = ipc::bytes_channel().unwrap(); + // TODO(emilio): convert colorspace if requested. self.send_command(WebGLCommand::TexSubImage2D { target: target.as_gl_constant(), level, @@ -767,9 +774,8 @@ impl WebGLRenderingContext { alpha_treatment, y_axis_treatment, pixel_format: pixels.pixel_format, - receiver, + data: pixels.data, }); - sender.send(&pixels.data).unwrap(); } fn get_gl_extensions(&self) -> String { @@ -3548,6 +3554,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + #[allow(unsafe_code)] fn TexImage2D( &self, target: u32, @@ -3609,8 +3616,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // If data is null, a buffer of sufficient size // initialized to 0 is passed. let buff = match *pixels { - None => vec![0u8; expected_byte_length as usize], - Some(ref data) => data.to_vec(), + None => IpcSharedMemory::from_bytes(&vec![0u8; expected_byte_length as usize]), + Some(ref data) => IpcSharedMemory::from_bytes(unsafe { data.as_slice() }), }; // From the WebGL spec: @@ -3763,6 +3770,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + #[allow(unsafe_code)] fn TexSubImage2D( &self, target: u32, @@ -3808,11 +3816,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Err(()) => return Ok(()), }; - // If data is null, a buffer of sufficient size - // initialized to 0 is passed. let buff = handle_potential_webgl_error!( self, - pixels.as_ref().map(|p| p.to_vec()).ok_or(InvalidValue), + pixels + .as_ref() + .map(|p| IpcSharedMemory::from_bytes(unsafe { p.as_slice() })) + .ok_or(InvalidValue), return Ok(()) ); @@ -4163,7 +4172,7 @@ impl TextureUnit { } struct TexPixels { - data: Vec, + data: IpcSharedMemory, size: Size2D, pixel_format: Option, premultiplied: bool, @@ -4171,7 +4180,7 @@ struct TexPixels { impl TexPixels { fn new( - data: Vec, + data: IpcSharedMemory, size: Size2D, pixel_format: PixelFormat, premultiplied: bool, @@ -4184,7 +4193,7 @@ impl TexPixels { } } - fn from_array(data: Vec, size: Size2D) -> Self { + fn from_array(data: IpcSharedMemory, size: Size2D) -> Self { Self { data, size,