mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
canvas: Do not update ImageKey during canvas layout (#35719)
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
f31043602a
commit
6f6840d63c
17 changed files with 90 additions and 126 deletions
|
@ -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<IpcSharedMemory>) {
|
||||
|
@ -1260,20 +1264,10 @@ impl<'a> CanvasData<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn send_data(&mut self, chan: IpcSender<CanvasImageData>) {
|
||||
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,
|
||||
|
|
|
@ -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<u64>) -> CanvasId {
|
||||
pub fn create_canvas(&mut self, size: Size2D<u64>) -> (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) {
|
||||
|
|
|
@ -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<u64>,
|
||||
response_sender: IpcSender<(IpcSender<CanvasMsg>, CanvasId)>,
|
||||
response_sender: IpcSender<(IpcSender<CanvasMsg>, 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -338,7 +338,7 @@ impl InlineAbsoluteFragmentInfo {
|
|||
#[derive(Clone)]
|
||||
pub enum CanvasFragmentSource {
|
||||
WebGL(ImageKey),
|
||||
Image(Arc<Mutex<IpcSender<CanvasMsg>>>),
|
||||
Image((ImageKey, CanvasId, Arc<Mutex<IpcSender<CanvasMsg>>>)),
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ impl NaturalSizes {
|
|||
|
||||
pub(crate) enum CanvasSource {
|
||||
WebGL(ImageKey),
|
||||
Image(Arc<Mutex<IpcSender<CanvasMsg>>>),
|
||||
Image((ImageKey, CanvasId, Arc<Mutex<IpcSender<CanvasMsg>>>)),
|
||||
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![],
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<CanvasMsg>,
|
||||
#[no_trace]
|
||||
canvas_id: CanvasId,
|
||||
#[no_trace]
|
||||
image_key: ImageKey,
|
||||
state: DomRefCell<CanvasContextState>,
|
||||
origin_clean: Cell<bool>,
|
||||
#[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<Vec<ServoUrl>> {
|
||||
&self.missing_image_urls
|
||||
}
|
||||
|
|
|
@ -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<CanvasImageData>) {
|
||||
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<CanvasMsg>;
|
||||
fn get_canvas_id(self) -> CanvasId;
|
||||
}
|
||||
|
||||
impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingContext2D> {
|
||||
fn get_ipc_renderer(self) -> IpcSender<CanvasMsg> {
|
||||
(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(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CanvasImageData>) {
|
||||
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<ServoUrl> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, f32, bool),
|
||||
|
@ -84,7 +78,7 @@ pub enum Canvas2dMsg {
|
|||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub enum FromLayoutMsg {
|
||||
SendData(IpcSender<CanvasImageData>),
|
||||
UpdateImage(IpcSender<()>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
|
|
|
@ -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<CanvasId>,
|
||||
sender: Sender<(CanvasId, ImageKey)>,
|
||||
size: Size2D<u64>,
|
||||
},
|
||||
Exit,
|
||||
|
|
|
@ -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<u64>,
|
||||
IpcSender<(IpcSender<CanvasMsg>, CanvasId)>,
|
||||
IpcSender<(IpcSender<CanvasMsg>, CanvasId, ImageKey)>,
|
||||
),
|
||||
/// Notifies the constellation that this frame has received focus.
|
||||
Focus,
|
||||
|
|
|
@ -120,7 +120,7 @@ pub enum LayoutElementType {
|
|||
|
||||
pub enum HTMLCanvasDataSource {
|
||||
WebGL(ImageKey),
|
||||
Image(IpcSender<CanvasMsg>),
|
||||
Image((ImageKey, CanvasId, IpcSender<CanvasMsg>)),
|
||||
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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue