From 6f6840d63c4ff65114f28f5de6a745974faa22a7 Mon Sep 17 00:00:00 2001 From: Samson <16504129+sagudev@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:36:52 +0100 Subject: [PATCH] canvas: Do not update ImageKey during canvas layout (#35719) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- components/canvas/canvas_data.rs | 24 +++++------- components/canvas/canvas_paint_thread.rs | 17 +++++---- components/constellation/constellation.rs | 15 ++++---- components/layout/display_list/builder.rs | 12 +++--- components/layout/fragment.rs | 12 +++--- components/layout_2020/dom.rs | 9 ++--- components/layout_2020/replaced.rs | 12 +++--- components/script/canvas_context.rs | 2 - components/script/canvas_state.rs | 10 ++++- .../script/dom/canvasrenderingcontext2d.rs | 37 ++++++------------- components/script/dom/htmlcanvaselement.rs | 23 +----------- .../script/dom/paintrenderingcontext2d.rs | 13 +++++-- .../script/dom/paintworkletglobalscope.rs | 13 ++----- components/shared/canvas/canvas.rs | 8 +--- components/shared/canvas/lib.rs | 3 +- components/shared/script/script_msg.rs | 3 +- components/shared/script_layout/lib.rs | 3 +- 17 files changed, 90 insertions(+), 126 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index ff93b969561..52f75c85f3a 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -21,7 +21,7 @@ use servo_arc::Arc as ServoArc; use style::color::AbsoluteColor; use style::properties::style_structs::Font as FontStyleStruct; use unicode_script::Script; -use webrender_api::units::{DeviceIntSize, RectExt as RectExt_}; +use webrender_api::units::RectExt as RectExt_; use webrender_api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey}; use webrender_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData}; @@ -465,6 +465,10 @@ impl<'a> CanvasData<'a> { } } + pub fn image_key(&self) -> ImageKey { + self.image_key + } + pub fn draw_image( &mut self, image_data: &[u8], @@ -1249,7 +1253,7 @@ impl<'a> CanvasData<'a> { .create_drawtarget(Size2D::new(size.width, size.height)); self.state = self.backend.recreate_paint_state(&self.state); self.saved_states.clear(); - self.update_wr_image(size.cast().cast_unit()); + self.update_image_rendering(); } pub fn send_pixels(&mut self, chan: IpcSender) { @@ -1260,20 +1264,10 @@ impl<'a> CanvasData<'a> { }); } - pub fn send_data(&mut self, chan: IpcSender) { - let size = self.drawtarget.get_size(); - - self.update_wr_image(size.cast_unit()); - - let data = CanvasImageData { - image_key: self.image_key, - }; - chan.send(data).unwrap(); - } - - fn update_wr_image(&mut self, size: DeviceIntSize) { + /// Update image in WebRender + pub fn update_image_rendering(&mut self) { let descriptor = ImageDescriptor { - size, + size: self.drawtarget.get_size().cast_unit(), stride: None, format: ImageFormat::BGRA8, offset: 0, diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index 5974efa8035..e57e8308b4a 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -16,6 +16,7 @@ use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use log::warn; use net_traits::ResourceThreads; +use webrender_api::ImageKey; use webrender_traits::CrossProcessCompositorApi; use crate::canvas_data::*; @@ -79,8 +80,9 @@ impl<'a> CanvasPaintThread<'a> { }, }, Ok(CanvasMsg::FromLayout(message, canvas_id)) => match message { - FromLayoutMsg::SendData(chan) => { - canvas_paint_thread.canvas(canvas_id).send_data(chan); + FromLayoutMsg::UpdateImage(sender) => { + canvas_paint_thread.canvas(canvas_id).update_image_rendering(); + sender.send(()).unwrap(); }, }, Err(e) => { @@ -90,9 +92,9 @@ impl<'a> CanvasPaintThread<'a> { } recv(create_receiver) -> msg => { match msg { - Ok(ConstellationCanvasMsg::Create { id_sender: creator, size }) => { - let canvas_id = canvas_paint_thread.create_canvas(size); - creator.send(canvas_id).unwrap(); + Ok(ConstellationCanvasMsg::Create { sender: creator, size }) => { + let canvas_data = canvas_paint_thread.create_canvas(size); + creator.send(canvas_data).unwrap(); }, Ok(ConstellationCanvasMsg::Exit) => break, Err(e) => { @@ -109,15 +111,16 @@ impl<'a> CanvasPaintThread<'a> { (create_sender, ipc_sender) } - pub fn create_canvas(&mut self, size: Size2D) -> CanvasId { + pub fn create_canvas(&mut self, size: Size2D) -> (CanvasId, ImageKey) { let canvas_id = self.next_canvas_id; self.next_canvas_id.0 += 1; let canvas_data = CanvasData::new(size, self.compositor_api.clone(), self.font_context.clone()); + let image_key = canvas_data.image_key(); self.canvases.insert(canvas_id, canvas_data); - canvas_id + (canvas_id, image_key) } fn process_canvas_2d_message(&mut self, message: Canvas2dMsg, canvas_id: CanvasId) { diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index f8cedbd4ecd..8094acdfb30 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -159,7 +159,7 @@ use webgpu::{self, WebGPU, WebGPURequest, WebGPUResponse}; #[cfg(feature = "webgpu")] use webrender::RenderApi; use webrender::RenderApiSender; -use webrender_api::DocumentId; +use webrender_api::{DocumentId, ImageKey}; use webrender_traits::{CompositorHitTestResult, WebrenderExternalImageRegistry}; use crate::browsingcontext::{ @@ -4362,21 +4362,22 @@ where fn handle_create_canvas_paint_thread_msg( &mut self, size: UntypedSize2D, - response_sender: IpcSender<(IpcSender, CanvasId)>, + response_sender: IpcSender<(IpcSender, CanvasId, ImageKey)>, ) { - let (canvas_id_sender, canvas_id_receiver) = unbounded(); + let (canvas_data_sender, canvas_data_receiver) = unbounded(); if let Err(e) = self.canvas_sender.send(ConstellationCanvasMsg::Create { - id_sender: canvas_id_sender, + sender: canvas_data_sender, size, }) { return warn!("Create canvas paint thread failed ({})", e); } - let canvas_id = match canvas_id_receiver.recv() { - Ok(canvas_id) => canvas_id, + let (canvas_id, image_key) = match canvas_data_receiver.recv() { + Ok(canvas_data) => canvas_data, Err(e) => return warn!("Create canvas paint thread id response failed ({})", e), }; - if let Err(e) = response_sender.send((self.canvas_ipc_sender.clone(), canvas_id)) { + if let Err(e) = response_sender.send((self.canvas_ipc_sender.clone(), canvas_id, image_key)) + { warn!("Create canvas paint thread response failed ({})", e); } } diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 314a3c20db5..5b93fee53c7 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -21,7 +21,6 @@ use euclid::default::{Point2D, Rect, SideOffsets2D as UntypedSideOffsets2D, Size use euclid::{Scale, SideOffsets2D, rect}; use fnv::FnvHashMap; use fonts::ByteIndex; -use ipc_channel::ipc; use log::{debug, warn}; use net_traits::image_cache::UsePlaceholder; use range::Range; @@ -1770,16 +1769,17 @@ impl Fragment { let image_key = match canvas_fragment_info.source { CanvasFragmentSource::WebGL(image_key) => image_key, CanvasFragmentSource::WebGPU(image_key) => image_key, - CanvasFragmentSource::Image(ref ipc_renderer) => { + CanvasFragmentSource::Image((image_key, canvas_id, ref ipc_renderer)) => { let ipc_renderer = ipc_renderer.lock().unwrap(); - let (sender, receiver) = ipc::channel().unwrap(); + let (sender, receiver) = ipc_channel::ipc::channel().unwrap(); ipc_renderer .send(CanvasMsg::FromLayout( - FromLayoutMsg::SendData(sender), - canvas_fragment_info.canvas_id, + FromLayoutMsg::UpdateImage(sender), + canvas_id, )) .unwrap(); - receiver.recv().unwrap().image_key + receiver.recv().unwrap(); + image_key }, CanvasFragmentSource::Empty => return, }; diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 3d818045203..a580e89ee07 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -338,7 +338,7 @@ impl InlineAbsoluteFragmentInfo { #[derive(Clone)] pub enum CanvasFragmentSource { WebGL(ImageKey), - Image(Arc>>), + Image((ImageKey, CanvasId, Arc>>)), WebGPU(ImageKey), /// Transparent black Empty, @@ -349,15 +349,18 @@ pub struct CanvasFragmentInfo { pub source: CanvasFragmentSource, pub dom_width: Au, pub dom_height: Au, - pub canvas_id: CanvasId, } impl CanvasFragmentInfo { pub fn new(data: HTMLCanvasData) -> CanvasFragmentInfo { let source = match data.source { HTMLCanvasDataSource::WebGL(texture_id) => CanvasFragmentSource::WebGL(texture_id), - HTMLCanvasDataSource::Image(ipc_sender) => { - CanvasFragmentSource::Image(Arc::new(Mutex::new(ipc_sender))) + HTMLCanvasDataSource::Image((image_key, canvas_id, ipc_sender)) => { + CanvasFragmentSource::Image(( + image_key, + canvas_id, + Arc::new(Mutex::new(ipc_sender)), + )) }, HTMLCanvasDataSource::WebGPU(image_key) => CanvasFragmentSource::WebGPU(image_key), HTMLCanvasDataSource::Empty => CanvasFragmentSource::Empty, @@ -367,7 +370,6 @@ impl CanvasFragmentInfo { source, dom_width: Au::from_px(data.width as i32), dom_height: Au::from_px(data.height as i32), - canvas_id: data.canvas_id, } } } diff --git a/components/layout_2020/dom.rs b/components/layout_2020/dom.rs index 6722b0c400d..919b04e0bc9 100644 --- a/components/layout_2020/dom.rs +++ b/components/layout_2020/dom.rs @@ -155,17 +155,14 @@ where let canvas_data = node.canvas_data()?; let source = match canvas_data.source { HTMLCanvasDataSource::WebGL(texture_id) => CanvasSource::WebGL(texture_id), - HTMLCanvasDataSource::Image(ipc_sender) => { - CanvasSource::Image(Arc::new(Mutex::new(ipc_sender))) + HTMLCanvasDataSource::Image((image_key, canvas_id, ipc_sender)) => { + CanvasSource::Image((image_key, canvas_id, Arc::new(Mutex::new(ipc_sender)))) }, HTMLCanvasDataSource::WebGPU(image_key) => CanvasSource::WebGPU(image_key), HTMLCanvasDataSource::Empty => CanvasSource::Empty, }; Some(( - CanvasInfo { - source, - canvas_id: canvas_data.canvas_id, - }, + CanvasInfo { source }, PhysicalSize::new(canvas_data.width.into(), canvas_data.height.into()), )) } diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index 00d273ccf74..5039b8cb91a 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -98,7 +98,7 @@ impl NaturalSizes { pub(crate) enum CanvasSource { WebGL(ImageKey), - Image(Arc>>), + Image((ImageKey, CanvasId, Arc>>)), WebGPU(ImageKey), /// transparent black Empty, @@ -122,7 +122,6 @@ impl fmt::Debug for CanvasSource { #[derive(Debug)] pub(crate) struct CanvasInfo { pub source: CanvasSource, - pub canvas_id: CanvasId, } #[derive(Debug)] @@ -382,16 +381,17 @@ impl ReplacedContents { let image_key = match canvas_info.source { CanvasSource::WebGL(image_key) => image_key, CanvasSource::WebGPU(image_key) => image_key, - CanvasSource::Image(ref ipc_renderer) => { + CanvasSource::Image((image_key, canvas_id, ref ipc_renderer)) => { let ipc_renderer = ipc_renderer.lock().unwrap(); let (sender, receiver) = ipc::channel().unwrap(); ipc_renderer .send(CanvasMsg::FromLayout( - FromLayoutMsg::SendData(sender), - canvas_info.canvas_id, + FromLayoutMsg::UpdateImage(sender), + canvas_id, )) .unwrap(); - receiver.recv().unwrap().image_key + receiver.recv().unwrap(); + image_key }, CanvasSource::Empty => return vec![], }; diff --git a/components/script/canvas_context.rs b/components/script/canvas_context.rs index 62e104d720f..752b749c97c 100644 --- a/components/script/canvas_context.rs +++ b/components/script/canvas_context.rs @@ -4,7 +4,6 @@ //! Common interfaces for Canvas Contexts -use canvas_traits::canvas::CanvasId; use euclid::default::Size2D; use ipc_channel::ipc::IpcSharedMemory; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; @@ -20,7 +19,6 @@ pub(crate) trait LayoutCanvasRenderingContextHelpers { pub(crate) trait LayoutHTMLCanvasElementHelpers { fn data(self) -> HTMLCanvasData; - fn get_canvas_id_for_layout(self) -> CanvasId; } pub(crate) trait CanvasContext { diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index a950b5909e4..9394e3785a2 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -34,6 +34,7 @@ use style::values::specified::color::Color; use style_traits::values::ToCss; use style_traits::{CssWriter, ParsingMode}; use url::Url; +use webrender_api::ImageKey; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ @@ -145,6 +146,8 @@ pub(crate) struct CanvasState { ipc_renderer: IpcSender, #[no_trace] canvas_id: CanvasId, + #[no_trace] + image_key: ImageKey, state: DomRefCell, origin_clean: Cell, #[ignore_malloc_size_of = "Arc"] @@ -172,7 +175,7 @@ impl CanvasState { script_to_constellation_chan .send(ScriptMsg::CreateCanvasPaintThread(size, sender)) .unwrap(); - let (ipc_renderer, canvas_id) = receiver.recv().unwrap(); + let (ipc_renderer, canvas_id, image_key) = receiver.recv().unwrap(); debug!("Done."); // Worklets always receive a unique origin. This messes with fetching // cached images in the case of paint worklets, since the image cache @@ -191,6 +194,7 @@ impl CanvasState { base_url: global.api_base_url(), missing_image_urls: DomRefCell::new(Vec::new()), saved_states: DomRefCell::new(Vec::new()), + image_key, origin, } } @@ -199,6 +203,10 @@ impl CanvasState { &self.ipc_renderer } + pub(crate) fn image_key(&self) -> ImageKey { + self.image_key + } + pub(crate) fn get_missing_image_urls(&self) -> &DomRefCell> { &self.missing_image_urls } diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 909ea6a4d89..cda7bed08f7 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -2,16 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use canvas_traits::canvas::{ - Canvas2dMsg, CanvasId, CanvasImageData, CanvasMsg, FromLayoutMsg, FromScriptMsg, -}; +use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg, FromScriptMsg}; use dom_struct::dom_struct; use euclid::default::{Point2D, Rect, Size2D}; -use ipc_channel::ipc::{IpcSender, IpcSharedMemory}; +use ipc_channel::ipc::IpcSharedMemory; use profile_traits::ipc; +use script_layout_interface::HTMLCanvasDataSource; use servo_url::ServoUrl; -use crate::canvas_context::CanvasContext; +use crate::canvas_context::{CanvasContext, LayoutCanvasRenderingContextHelpers}; use crate::canvas_state::CanvasState; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin, @@ -112,28 +111,16 @@ impl CanvasRenderingContext2D { ); self.canvas_state.get_rect(self.canvas.size(), rect) } - - pub(crate) fn send_data(&self, sender: IpcSender) { - let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender), self.get_canvas_id()); - let _ = self.canvas_state.get_ipc_renderer().send(msg); - } } -pub(crate) trait LayoutCanvasRenderingContext2DHelpers { - fn get_ipc_renderer(self) -> IpcSender; - fn get_canvas_id(self) -> CanvasId; -} - -impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingContext2D> { - fn get_ipc_renderer(self) -> IpcSender { - (self.unsafe_get()).canvas_state.get_ipc_renderer().clone() - } - - fn get_canvas_id(self) -> CanvasId { - // FIXME(nox): This relies on the fact that CanvasState::get_canvas_id - // does nothing fancy but it would be easier to trust a - // LayoutDom<_>-like type that would wrap the &CanvasState. - self.unsafe_get().canvas_state.get_canvas_id() +impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, CanvasRenderingContext2D> { + fn canvas_data_source(self) -> HTMLCanvasDataSource { + let canvas_state = &self.unsafe_get().canvas_state; + HTMLCanvasDataSource::Image(( + canvas_state.image_key(), + canvas_state.get_canvas_id(), + canvas_state.get_ipc_renderer().clone(), + )) } } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index fa3a48f6a6a..b12a6cd0f4a 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -6,7 +6,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::rc::Rc; -use canvas_traits::canvas::CanvasId; use canvas_traits::webgl::{GLContextAttributes, WebGLVersion}; use dom_struct::dom_struct; use euclid::default::Size2D; @@ -48,9 +47,7 @@ use crate::dom::bindings::reflector::{DomGlobal, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, ToLayout}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::blob::Blob; -use crate::dom::canvasrenderingcontext2d::{ - CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers, -}; +use crate::dom::canvasrenderingcontext2d::CanvasRenderingContext2D; use crate::dom::document::Document; use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers}; #[cfg(not(feature = "webgpu"))] @@ -208,9 +205,7 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { fn data(self) -> HTMLCanvasData { let source = unsafe { match self.unsafe_get().context.borrow_for_layout().as_ref() { - Some(CanvasContext::Context2d(context)) => { - HTMLCanvasDataSource::Image(context.to_layout().get_ipc_renderer()) - }, + Some(CanvasContext::Context2d(context)) => context.to_layout().canvas_data_source(), Some(CanvasContext::WebGL(context)) => context.to_layout().canvas_data_source(), Some(CanvasContext::WebGL2(context)) => context.to_layout().canvas_data_source(), #[cfg(feature = "webgpu")] @@ -229,20 +224,6 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { source, width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()), height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()), - canvas_id: self.get_canvas_id_for_layout(), - } - } - - #[allow(unsafe_code)] - fn get_canvas_id_for_layout(self) -> CanvasId { - let canvas = self.unsafe_get(); - unsafe { - if let &Some(CanvasContext::Context2d(ref context)) = canvas.context.borrow_for_layout() - { - context.to_layout().get_canvas_id() - } else { - CanvasId(0) - } } } } diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs index b65eee99e63..396d53ee330 100644 --- a/components/script/dom/paintrenderingcontext2d.rs +++ b/components/script/dom/paintrenderingcontext2d.rs @@ -4,13 +4,14 @@ use std::cell::Cell; -use canvas_traits::canvas::{CanvasId, CanvasImageData, CanvasMsg, FromLayoutMsg}; +use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg}; use dom_struct::dom_struct; use euclid::{Scale, Size2D}; -use ipc_channel::ipc::IpcSender; +use ipc_channel::ipc; use script_bindings::reflector::Reflector; use servo_url::ServoUrl; use style_traits::CSSPixel; +use webrender_api::ImageKey; use webrender_api::units::DevicePixel; use super::bindings::reflector::DomGlobal as _; @@ -64,9 +65,13 @@ impl PaintRenderingContext2D { self.canvas_state.get_canvas_id() } - pub(crate) fn send_data(&self, sender: IpcSender) { - let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender), self.get_canvas_id()); + /// Send update to canvas paint thread and returns [`ImageKey`] + pub(crate) fn image_key(&self) -> ImageKey { + let (sender, receiver) = ipc::channel().unwrap(); + let msg = CanvasMsg::FromLayout(FromLayoutMsg::UpdateImage(sender), self.get_canvas_id()); let _ = self.canvas_state.get_ipc_renderer().send(msg); + receiver.recv().unwrap(); + self.canvas_state.image_key() } pub(crate) fn take_missing_image_urls(&self) -> Vec { diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs index a40884da746..0a8046d9508 100644 --- a/components/script/dom/paintworkletglobalscope.rs +++ b/components/script/dom/paintworkletglobalscope.rs @@ -23,7 +23,6 @@ use js::rust::wrappers::{Call, Construct1}; use js::rust::{HandleValue, Runtime}; use net_traits::image_cache::ImageCache; use pixels::PixelFormat; -use profile_traits::ipc; use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter}; use servo_config::pref; use servo_url::ServoUrl; @@ -40,7 +39,7 @@ use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction; use crate::dom::bindings::conversions::{get_property, get_property_jsval}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::reflector::{DomGlobal, DomObject}; +use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::DOMString; use crate::dom::cssstylevalue::CSSStyleValue; @@ -354,19 +353,13 @@ impl PaintWorkletGlobalScope { return self.invalid_image(size_in_dpx, missing_image_urls); } - let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()) - .expect("IPC channel creation."); - rendering_context.send_data(sender); - let image_key = match receiver.recv() { - Ok(data) => Some(data.image_key), - _ => None, - }; + let image_key = rendering_context.image_key(); DrawAPaintImageResult { width: size_in_dpx.width, height: size_in_dpx.height, format: PixelFormat::BGRA8, - image_key, + image_key: Some(image_key), missing_image_urls, } } diff --git a/components/shared/canvas/canvas.rs b/components/shared/canvas/canvas.rs index 3be14565603..1c04e3c9cc6 100644 --- a/components/shared/canvas/canvas.rs +++ b/components/shared/canvas/canvas.rs @@ -12,7 +12,6 @@ use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; use style::color::AbsoluteColor; use style::properties::style_structs::Font as FontStyleStruct; -use webrender_api::ImageKey; #[derive(Clone, Debug, Deserialize, Serialize)] pub enum FillRule { @@ -32,11 +31,6 @@ pub enum CanvasMsg { Close(CanvasId), } -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct CanvasImageData { - pub image_key: ImageKey, -} - #[derive(Debug, Deserialize, Serialize)] pub enum Canvas2dMsg { Arc(Point2D, f32, f32, f32, bool), @@ -84,7 +78,7 @@ pub enum Canvas2dMsg { #[derive(Clone, Debug, Deserialize, Serialize)] pub enum FromLayoutMsg { - SendData(IpcSender), + UpdateImage(IpcSender<()>), } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/components/shared/canvas/lib.rs b/components/shared/canvas/lib.rs index 8d72c818284..826db54b0f6 100644 --- a/components/shared/canvas/lib.rs +++ b/components/shared/canvas/lib.rs @@ -8,6 +8,7 @@ use crossbeam_channel::Sender; use euclid::default::Size2D; +use webrender_api::ImageKey; use crate::canvas::CanvasId; @@ -17,7 +18,7 @@ pub mod webgl; pub enum ConstellationCanvasMsg { Create { - id_sender: Sender, + sender: Sender<(CanvasId, ImageKey)>, size: Size2D, }, Exit, diff --git a/components/shared/script/script_msg.rs b/components/shared/script/script_msg.rs index 90e3bb8e6fd..7af7272c715 100644 --- a/components/shared/script/script_msg.rs +++ b/components/shared/script/script_msg.rs @@ -25,6 +25,7 @@ use servo_url::{ImmutableOrigin, ServoUrl}; use style_traits::CSSPixel; #[cfg(feature = "webgpu")] use webgpu::{WebGPU, WebGPUResponse, wgc}; +use webrender_api::ImageKey; use crate::mem::MemoryReportResult; use crate::{ @@ -144,7 +145,7 @@ pub enum ScriptMsg { /// 2D canvases may use the GPU and we don't want to give untrusted content access to the GPU.) CreateCanvasPaintThread( UntypedSize2D, - IpcSender<(IpcSender, CanvasId)>, + IpcSender<(IpcSender, CanvasId, ImageKey)>, ), /// Notifies the constellation that this frame has received focus. Focus, diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index de70ae64df0..caceb776829 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -120,7 +120,7 @@ pub enum LayoutElementType { pub enum HTMLCanvasDataSource { WebGL(ImageKey), - Image(IpcSender), + Image((ImageKey, CanvasId, IpcSender)), WebGPU(ImageKey), /// transparent black Empty, @@ -130,7 +130,6 @@ pub struct HTMLCanvasData { pub source: HTMLCanvasDataSource, pub width: u32, pub height: u32, - pub canvas_id: CanvasId, } pub struct SVGSVGData {