mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
canvas: Make GetImageData simple and only IPC message to obtain pixels (#38274)
Currently we had `GetImageData` and `SendPixels` to obtain pixels from script thread. This PR unifies those into single `GetImageData` that does not need canvas size and has optional rect (for obtaining sub image). Testing: Existing WPT tests Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
77f85f390e
commit
8b2a5fca54
5 changed files with 26 additions and 63 deletions
|
@ -723,12 +723,8 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
||||||
/// canvas_size: The size of the canvas we're reading from
|
/// canvas_size: The size of the canvas we're reading from
|
||||||
/// read_rect: The area of the canvas we want to read from
|
/// read_rect: The area of the canvas we want to read from
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub(crate) fn read_pixels(
|
pub(crate) fn read_pixels(&mut self, read_rect: Option<Rect<u32>>) -> Snapshot {
|
||||||
&mut self,
|
let canvas_size = self.drawtarget.get_size().cast();
|
||||||
read_rect: Option<Rect<u32>>,
|
|
||||||
canvas_size: Option<Size2D<u32>>,
|
|
||||||
) -> Snapshot {
|
|
||||||
let canvas_size = canvas_size.unwrap_or(self.drawtarget.get_size().cast());
|
|
||||||
|
|
||||||
if let Some(read_rect) = read_rect {
|
if let Some(read_rect) = read_rect {
|
||||||
let canvas_rect = Rect::from_size(canvas_size);
|
let canvas_rect = Rect::from_size(canvas_size);
|
||||||
|
|
|
@ -77,15 +77,6 @@ impl CanvasPaintThread {
|
||||||
Ok(CanvasMsg::Recreate(size, canvas_id)) => {
|
Ok(CanvasMsg::Recreate(size, canvas_id)) => {
|
||||||
canvas_paint_thread.canvas(canvas_id).recreate(size);
|
canvas_paint_thread.canvas(canvas_id).recreate(size);
|
||||||
},
|
},
|
||||||
Ok(CanvasMsg::FromScript(message, canvas_id)) => match message {
|
|
||||||
FromScriptMsg::SendPixels(chan) => {
|
|
||||||
chan.send(canvas_paint_thread
|
|
||||||
.canvas(canvas_id)
|
|
||||||
.read_pixels(None, None)
|
|
||||||
.as_ipc()
|
|
||||||
).unwrap();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Error on CanvasPaintThread receive ({})", e);
|
warn!("Error on CanvasPaintThread receive ({})", e);
|
||||||
},
|
},
|
||||||
|
@ -247,7 +238,6 @@ impl CanvasPaintThread {
|
||||||
),
|
),
|
||||||
Canvas2dMsg::DrawImageInOther(
|
Canvas2dMsg::DrawImageInOther(
|
||||||
other_canvas_id,
|
other_canvas_id,
|
||||||
image_size,
|
|
||||||
dest_rect,
|
dest_rect,
|
||||||
source_rect,
|
source_rect,
|
||||||
smoothing,
|
smoothing,
|
||||||
|
@ -257,7 +247,7 @@ impl CanvasPaintThread {
|
||||||
) => {
|
) => {
|
||||||
let snapshot = self
|
let snapshot = self
|
||||||
.canvas(canvas_id)
|
.canvas(canvas_id)
|
||||||
.read_pixels(Some(source_rect.to_u32()), Some(image_size));
|
.read_pixels(Some(source_rect.to_u32()));
|
||||||
self.canvas(other_canvas_id).draw_image(
|
self.canvas(other_canvas_id).draw_image(
|
||||||
snapshot,
|
snapshot,
|
||||||
dest_rect,
|
dest_rect,
|
||||||
|
@ -272,10 +262,8 @@ impl CanvasPaintThread {
|
||||||
let metrics = self.canvas(canvas_id).measure_text(text, text_options);
|
let metrics = self.canvas(canvas_id).measure_text(text, text_options);
|
||||||
sender.send(metrics).unwrap();
|
sender.send(metrics).unwrap();
|
||||||
},
|
},
|
||||||
Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender) => {
|
Canvas2dMsg::GetImageData(dest_rect, sender) => {
|
||||||
let snapshot = self
|
let snapshot = self.canvas(canvas_id).read_pixels(dest_rect);
|
||||||
.canvas(canvas_id)
|
|
||||||
.read_pixels(Some(dest_rect), Some(canvas_size));
|
|
||||||
sender.send(snapshot.as_ipc()).unwrap();
|
sender.send(snapshot.as_ipc()).unwrap();
|
||||||
},
|
},
|
||||||
Canvas2dMsg::PutImageData(rect, snapshot) => {
|
Canvas2dMsg::PutImageData(rect, snapshot) => {
|
||||||
|
@ -436,13 +424,9 @@ impl Canvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_pixels(
|
fn read_pixels(&mut self, read_rect: Option<Rect<u32>>) -> Snapshot {
|
||||||
&mut self,
|
|
||||||
read_rect: Option<Rect<u32>>,
|
|
||||||
canvas_size: Option<Size2D<u32>>,
|
|
||||||
) -> Snapshot {
|
|
||||||
match self {
|
match self {
|
||||||
Canvas::Raqote(canvas_data) => canvas_data.read_pixels(read_rect, canvas_size),
|
Canvas::Raqote(canvas_data) => canvas_data.read_pixels(read_rect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -443,23 +443,6 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_rect(&self, canvas_size: Size2D<u32>, rect: Rect<u32>) -> Vec<u8> {
|
|
||||||
assert!(self.origin_is_clean());
|
|
||||||
assert!(Rect::from_size(canvas_size).contains_rect(&rect));
|
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
|
||||||
self.send_canvas_2d_msg(Canvas2dMsg::GetImageData(rect, canvas_size, sender));
|
|
||||||
let snapshot = receiver.recv().unwrap().to_owned();
|
|
||||||
snapshot
|
|
||||||
.to_vec(
|
|
||||||
Some(SnapshotAlphaMode::Transparent {
|
|
||||||
premultiplied: false,
|
|
||||||
}),
|
|
||||||
Some(SnapshotPixelFormat::RGBA),
|
|
||||||
)
|
|
||||||
.0
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// drawImage coordinates explained
|
/// drawImage coordinates explained
|
||||||
///
|
///
|
||||||
|
@ -701,7 +684,6 @@ impl CanvasState {
|
||||||
OffscreenRenderingContext::Context2d(ref context) => {
|
OffscreenRenderingContext::Context2d(ref context) => {
|
||||||
context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
||||||
self.get_canvas_id(),
|
self.get_canvas_id(),
|
||||||
image_size,
|
|
||||||
dest_rect,
|
dest_rect,
|
||||||
source_rect,
|
source_rect,
|
||||||
smoothing_enabled,
|
smoothing_enabled,
|
||||||
|
@ -781,7 +763,6 @@ impl CanvasState {
|
||||||
RenderingContext::Context2d(ref context) => {
|
RenderingContext::Context2d(ref context) => {
|
||||||
context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
||||||
self.get_canvas_id(),
|
self.get_canvas_id(),
|
||||||
image_size,
|
|
||||||
dest_rect,
|
dest_rect,
|
||||||
source_rect,
|
source_rect,
|
||||||
smoothing_enabled,
|
smoothing_enabled,
|
||||||
|
@ -813,7 +794,6 @@ impl CanvasState {
|
||||||
OffscreenRenderingContext::Context2d(ref context) => context
|
OffscreenRenderingContext::Context2d(ref context) => context
|
||||||
.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther(
|
||||||
self.get_canvas_id(),
|
self.get_canvas_id(),
|
||||||
image_size,
|
|
||||||
dest_rect,
|
dest_rect,
|
||||||
source_rect,
|
source_rect,
|
||||||
smoothing_enabled,
|
smoothing_enabled,
|
||||||
|
@ -1755,7 +1735,19 @@ impl CanvasState {
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = if self.is_paintable() {
|
let data = if self.is_paintable() {
|
||||||
Some(self.get_rect(canvas_size, read_rect))
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
self.send_canvas_2d_msg(Canvas2dMsg::GetImageData(Some(read_rect), sender));
|
||||||
|
let snapshot = receiver.recv().unwrap().to_owned();
|
||||||
|
Some(
|
||||||
|
snapshot
|
||||||
|
.to_vec(
|
||||||
|
Some(SnapshotAlphaMode::Transparent {
|
||||||
|
premultiplied: false,
|
||||||
|
}),
|
||||||
|
Some(SnapshotPixelFormat::RGBA),
|
||||||
|
)
|
||||||
|
.0,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,12 +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 https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg, FromScriptMsg};
|
use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg};
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use pixels::Snapshot;
|
use pixels::Snapshot;
|
||||||
use profile_traits::ipc;
|
|
||||||
use script_bindings::inheritance::Castable;
|
use script_bindings::inheritance::Castable;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
|
@ -162,10 +161,9 @@ impl CanvasContext for CanvasRenderingContext2D {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender), self.get_canvas_id());
|
self.canvas_state
|
||||||
self.canvas_state.get_ipc_renderer().send(msg).unwrap();
|
.send_canvas_2d_msg(Canvas2dMsg::GetImageData(None, sender));
|
||||||
|
|
||||||
Some(receiver.recv().unwrap().to_owned())
|
Some(receiver.recv().unwrap().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -449,7 +449,6 @@ pub struct TextOptions {
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub enum CanvasMsg {
|
pub enum CanvasMsg {
|
||||||
Canvas2d(Canvas2dMsg, CanvasId),
|
Canvas2d(Canvas2dMsg, CanvasId),
|
||||||
FromScript(FromScriptMsg, CanvasId),
|
|
||||||
Recreate(Option<Size2D<u64>>, CanvasId),
|
Recreate(Option<Size2D<u64>>, CanvasId),
|
||||||
Close(CanvasId),
|
Close(CanvasId),
|
||||||
}
|
}
|
||||||
|
@ -475,7 +474,6 @@ pub enum Canvas2dMsg {
|
||||||
),
|
),
|
||||||
DrawImageInOther(
|
DrawImageInOther(
|
||||||
CanvasId,
|
CanvasId,
|
||||||
Size2D<u32>,
|
|
||||||
Rect<f64>,
|
Rect<f64>,
|
||||||
Rect<f64>,
|
Rect<f64>,
|
||||||
bool,
|
bool,
|
||||||
|
@ -512,7 +510,7 @@ pub enum Canvas2dMsg {
|
||||||
CompositionOptions,
|
CompositionOptions,
|
||||||
Transform2D<f32>,
|
Transform2D<f32>,
|
||||||
),
|
),
|
||||||
GetImageData(Rect<u32>, Size2D<u32>, IpcSender<IpcSnapshot>),
|
GetImageData(Option<Rect<u32>>, IpcSender<IpcSnapshot>),
|
||||||
MeasureText(String, IpcSender<TextMetrics>, TextOptions),
|
MeasureText(String, IpcSender<TextMetrics>, TextOptions),
|
||||||
PutImageData(Rect<u32>, IpcSnapshot),
|
PutImageData(Rect<u32>, IpcSnapshot),
|
||||||
StrokeRect(
|
StrokeRect(
|
||||||
|
@ -534,11 +532,6 @@ pub enum Canvas2dMsg {
|
||||||
UpdateImage(IpcSender<()>),
|
UpdateImage(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub enum FromScriptMsg {
|
|
||||||
SendPixels(IpcSender<IpcSnapshot>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub struct CanvasGradientStop {
|
pub struct CanvasGradientStop {
|
||||||
pub offset: f64,
|
pub offset: f64,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue