mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
canvas: Make script/canvas thread boundry mostly stateless (#38164)
This PR removes all `Set*` commands as we will send needed options on each request. This will allow us to remove most of state handling from canvas paint thread (currently it's still stateful). Testing: Existing WPT tests work towards #38022 try run: https://github.com/sagudev/servo/actions/runs/16413823963 --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
8a1cc69717
commit
cd340fa8b9
3 changed files with 379 additions and 116 deletions
|
@ -5,7 +5,7 @@
|
|||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::{f32, thread};
|
||||
|
||||
use canvas_traits::ConstellationCanvasMsg;
|
||||
use canvas_traits::canvas::*;
|
||||
|
@ -134,76 +134,149 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
|
||||
fn process_canvas_2d_message(&mut self, message: Canvas2dMsg, canvas_id: CanvasId) {
|
||||
match message {
|
||||
Canvas2dMsg::FillText(text, x, y, max_width, style, is_rtl) => {
|
||||
self.canvas(canvas_id).set_fill_style(style);
|
||||
self.canvas(canvas_id)
|
||||
.fill_text(text, x, y, max_width, is_rtl);
|
||||
Canvas2dMsg::FillText(
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
max_width,
|
||||
style,
|
||||
is_rtl,
|
||||
text_options,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_fill_style(style);
|
||||
canvas.set_text_options(text_options);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.fill_text(text, x, y, max_width, is_rtl);
|
||||
},
|
||||
Canvas2dMsg::FillRect(rect, style) => {
|
||||
self.canvas(canvas_id).set_fill_style(style);
|
||||
self.canvas(canvas_id).fill_rect(&rect);
|
||||
Canvas2dMsg::FillRect(rect, style, shadow_options, composition_options, transform) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_fill_style(style);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.fill_rect(&rect);
|
||||
},
|
||||
Canvas2dMsg::StrokeRect(rect, style) => {
|
||||
self.canvas(canvas_id).set_stroke_style(style);
|
||||
self.canvas(canvas_id).stroke_rect(&rect);
|
||||
Canvas2dMsg::StrokeRect(
|
||||
rect,
|
||||
style,
|
||||
line_options,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_stroke_style(style);
|
||||
canvas.set_line_options(line_options);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.stroke_rect(&rect);
|
||||
},
|
||||
Canvas2dMsg::ClearRect(ref rect) => self.canvas(canvas_id).clear_rect(rect),
|
||||
Canvas2dMsg::FillPath(style, path) => {
|
||||
self.canvas(canvas_id).set_fill_style(style);
|
||||
self.canvas(canvas_id).fill_path(&path);
|
||||
Canvas2dMsg::ClearRect(ref rect, transform) => {
|
||||
self.canvas(canvas_id).set_transform(&transform);
|
||||
self.canvas(canvas_id).clear_rect(rect)
|
||||
},
|
||||
Canvas2dMsg::StrokePath(style, path) => {
|
||||
self.canvas(canvas_id).set_stroke_style(style);
|
||||
self.canvas(canvas_id).stroke_path(&path);
|
||||
Canvas2dMsg::FillPath(style, path, shadow_options, composition_options, transform) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_fill_style(style);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.fill_path(&path);
|
||||
},
|
||||
Canvas2dMsg::ClipPath(path) => self.canvas(canvas_id).clip_path(&path),
|
||||
Canvas2dMsg::DrawImage(snapshot, dest_rect, source_rect, smoothing_enabled) => {
|
||||
self.canvas(canvas_id).draw_image(
|
||||
Canvas2dMsg::StrokePath(
|
||||
path,
|
||||
style,
|
||||
line_options,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_stroke_style(style);
|
||||
canvas.set_line_options(line_options);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.stroke_path(&path);
|
||||
},
|
||||
Canvas2dMsg::ClipPath(path, transform) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.clip_path(&path);
|
||||
},
|
||||
Canvas2dMsg::DrawImage(
|
||||
snapshot,
|
||||
dest_rect,
|
||||
source_rect,
|
||||
smoothing_enabled,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.draw_image(
|
||||
snapshot.to_owned(),
|
||||
dest_rect,
|
||||
source_rect,
|
||||
smoothing_enabled,
|
||||
)
|
||||
},
|
||||
Canvas2dMsg::DrawEmptyImage(image_size, dest_rect, source_rect) => self
|
||||
.canvas(canvas_id)
|
||||
.draw_image(Snapshot::cleared(image_size), dest_rect, source_rect, false),
|
||||
Canvas2dMsg::DrawEmptyImage(
|
||||
image_size,
|
||||
dest_rect,
|
||||
source_rect,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.set_composition_options(composition_options);
|
||||
self.canvas(canvas_id).draw_image(
|
||||
Snapshot::cleared(image_size),
|
||||
dest_rect,
|
||||
source_rect,
|
||||
false,
|
||||
)
|
||||
},
|
||||
Canvas2dMsg::DrawImageInOther(
|
||||
other_canvas_id,
|
||||
image_size,
|
||||
dest_rect,
|
||||
source_rect,
|
||||
smoothing,
|
||||
shadow_options,
|
||||
composition_options,
|
||||
transform,
|
||||
) => {
|
||||
let snapshot = self
|
||||
.canvas(canvas_id)
|
||||
.read_pixels(Some(source_rect.to_u32()), Some(image_size));
|
||||
self.canvas(other_canvas_id).draw_image(
|
||||
snapshot,
|
||||
dest_rect,
|
||||
source_rect,
|
||||
smoothing,
|
||||
);
|
||||
let canvas = self.canvas(other_canvas_id);
|
||||
canvas.set_transform(&transform);
|
||||
canvas.set_composition_options(composition_options);
|
||||
canvas.set_shadow_options(shadow_options);
|
||||
canvas.draw_image(snapshot, dest_rect, source_rect, smoothing);
|
||||
},
|
||||
Canvas2dMsg::MeasureText(text, sender) => {
|
||||
let metrics = self.canvas(canvas_id).measure_text(text);
|
||||
Canvas2dMsg::MeasureText(text, sender, text_options) => {
|
||||
let canvas = self.canvas(canvas_id);
|
||||
canvas.set_text_options(text_options);
|
||||
let metrics = canvas.measure_text(text);
|
||||
sender.send(metrics).unwrap();
|
||||
},
|
||||
Canvas2dMsg::RestoreContext => self.canvas(canvas_id).restore_context_state(),
|
||||
Canvas2dMsg::SaveContext => self.canvas(canvas_id).save_context_state(),
|
||||
Canvas2dMsg::SetLineWidth(width) => self.canvas(canvas_id).set_line_width(width),
|
||||
Canvas2dMsg::SetLineCap(cap) => self.canvas(canvas_id).set_line_cap(cap),
|
||||
Canvas2dMsg::SetLineJoin(join) => self.canvas(canvas_id).set_line_join(join),
|
||||
Canvas2dMsg::SetMiterLimit(limit) => self.canvas(canvas_id).set_miter_limit(limit),
|
||||
Canvas2dMsg::SetLineDash(items) => self.canvas(canvas_id).set_line_dash(items),
|
||||
Canvas2dMsg::SetLineDashOffset(offset) => {
|
||||
self.canvas(canvas_id).set_line_dash_offset(offset)
|
||||
},
|
||||
Canvas2dMsg::SetTransform(ref matrix) => self.canvas(canvas_id).set_transform(matrix),
|
||||
Canvas2dMsg::SetGlobalAlpha(alpha) => self.canvas(canvas_id).set_global_alpha(alpha),
|
||||
Canvas2dMsg::SetGlobalComposition(op) => {
|
||||
self.canvas(canvas_id).set_global_composition(op)
|
||||
},
|
||||
Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender) => {
|
||||
let snapshot = self
|
||||
.canvas(canvas_id)
|
||||
|
@ -214,21 +287,6 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
self.canvas(canvas_id)
|
||||
.put_image_data(snapshot.to_owned(), rect);
|
||||
},
|
||||
Canvas2dMsg::SetShadowOffsetX(value) => {
|
||||
self.canvas(canvas_id).set_shadow_offset_x(value)
|
||||
},
|
||||
Canvas2dMsg::SetShadowOffsetY(value) => {
|
||||
self.canvas(canvas_id).set_shadow_offset_y(value)
|
||||
},
|
||||
Canvas2dMsg::SetShadowBlur(value) => self.canvas(canvas_id).set_shadow_blur(value),
|
||||
Canvas2dMsg::SetShadowColor(color) => self.canvas(canvas_id).set_shadow_color(color),
|
||||
Canvas2dMsg::SetFont(font_style) => self.canvas(canvas_id).set_font(font_style),
|
||||
Canvas2dMsg::SetTextAlign(text_align) => {
|
||||
self.canvas(canvas_id).set_text_align(text_align)
|
||||
},
|
||||
Canvas2dMsg::SetTextBaseline(text_baseline) => {
|
||||
self.canvas(canvas_id).set_text_baseline(text_baseline)
|
||||
},
|
||||
Canvas2dMsg::UpdateImage(sender) => {
|
||||
self.canvas(canvas_id).update_image_rendering();
|
||||
sender.send(()).unwrap();
|
||||
|
@ -455,4 +513,41 @@ impl Canvas<'_> {
|
|||
Canvas::Raqote(canvas_data) => canvas_data.recreate(size),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_text_options(&mut self, text_options: TextOptions) {
|
||||
if let Some(font) = text_options.font {
|
||||
self.set_font(font);
|
||||
}
|
||||
self.set_text_align(text_options.align);
|
||||
self.set_text_baseline(text_options.baseline);
|
||||
}
|
||||
|
||||
fn set_shadow_options(&mut self, shadow_options: ShadowOptions) {
|
||||
self.set_shadow_color(shadow_options.color);
|
||||
self.set_shadow_offset_x(shadow_options.offset_x);
|
||||
self.set_shadow_offset_y(shadow_options.offset_y);
|
||||
self.set_shadow_blur(shadow_options.blur);
|
||||
}
|
||||
|
||||
fn set_composition_options(&mut self, composition_options: CompositionOptions) {
|
||||
self.set_global_alpha(composition_options.alpha as f32);
|
||||
self.set_global_composition(composition_options.composition_operation);
|
||||
}
|
||||
|
||||
fn set_line_options(&mut self, line_options: LineOptions) {
|
||||
let LineOptions {
|
||||
width,
|
||||
cap_style,
|
||||
join_style,
|
||||
miter_limit,
|
||||
dash,
|
||||
dash_offset,
|
||||
} = line_options;
|
||||
self.set_line_width(width as f32);
|
||||
self.set_line_cap(cap_style);
|
||||
self.set_line_join(join_style);
|
||||
self.set_miter_limit(miter_limit as f32);
|
||||
self.set_line_dash(dash);
|
||||
self.set_line_dash_offset(dash_offset as f32);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue