Skip to content

Commit e0145b1

Browse files
committed
Bug 1918529 - fix some subpixel misalignment issues with gfx.webrender.svg-filter-effects r=gfx-reviewers,gw
Differential Revision: https://phabricator.services.mozilla.com/D223453
1 parent 929691f commit e0145b1

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

webrender/src/picture.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,6 +4183,8 @@ struct SurfaceAllocInfo {
41834183
// Only used for SVGFEGraph currently, this is the source pixels needed to
41844184
// render the pixels in clipped.
41854185
source: DeviceRect,
4186+
// Only used for SVGFEGraph, this is the same as clipped before rounding.
4187+
clipped_notsnapped: DeviceRect,
41864188
clipped_local: PictureRect,
41874189
uv_rect_kind: UvRectKind,
41884190
}
@@ -6378,6 +6380,14 @@ impl PicturePrimitive {
63786380
)
63796381
);
63806382

6383+
// Determine the local space to device pixel scaling in the most robust
6384+
// way, this accounts for local to device transform and
6385+
// device_pixel_scale (if the task is shrunk in get_surface_rects).
6386+
let subregion_to_device_scale_x = surface_rects.clipped_notsnapped.width() / surface_rects.clipped_local.width();
6387+
let subregion_to_device_scale_y = surface_rects.clipped_notsnapped.height() / surface_rects.clipped_local.height();
6388+
let subregion_to_device_offset_x = surface_rects.clipped_notsnapped.min.x - (surface_rects.clipped_local.min.x * subregion_to_device_scale_x).floor();
6389+
let subregion_to_device_offset_y = surface_rects.clipped_notsnapped.min.y - (surface_rects.clipped_local.min.y * subregion_to_device_scale_y).floor();
6390+
63816391
// Produce the target pixels, this is the result of the
63826392
// composite op
63836393
let filter_task_id = request_render_task(
@@ -6396,8 +6406,10 @@ impl PicturePrimitive {
63966406
source_subregion.cast_unit(),
63976407
target_subregion.cast_unit(),
63986408
prim_subregion.cast_unit(),
6399-
surface_rects.clipped.cast_unit(),
6400-
surface_rects.clipped_local.cast_unit(),
6409+
subregion_to_device_scale_x,
6410+
subregion_to_device_scale_y,
6411+
subregion_to_device_offset_x,
6412+
subregion_to_device_offset_y,
64016413
)
64026414
}
64036415
);
@@ -8151,6 +8163,7 @@ fn get_surface_rects(
81518163
clipped: clipped_snapped,
81528164
unclipped,
81538165
source,
8166+
clipped_notsnapped: clipped,
81548167
clipped_local,
81558168
uv_rect_kind,
81568169
})

webrender/src/render_task.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,8 +1649,10 @@ impl RenderTask {
16491649
source_subregion: LayoutRect,
16501650
target_subregion: LayoutRect,
16511651
prim_subregion: LayoutRect,
1652-
surface_rects_clipped: LayoutRect,
1653-
surface_rects_clipped_local: LayoutRect,
1652+
subregion_to_device_scale_x: f32,
1653+
subregion_to_device_scale_y: f32,
1654+
subregion_to_device_offset_x: f32,
1655+
subregion_to_device_offset_y: f32,
16541656
) -> RenderTaskId {
16551657
const BUFFER_LIMIT: usize = SVGFE_GRAPH_MAX;
16561658
let mut task_by_buffer_id: [RenderTaskId; BUFFER_LIMIT] = [RenderTaskId::INVALID; BUFFER_LIMIT];
@@ -1699,20 +1701,6 @@ impl RenderTask {
16991701
}
17001702
}
17011703

1702-
// Determine the local space to device pixel scaling in the most robust
1703-
// way, this accounts for local to device transform and
1704-
// device_pixel_scale (if the task is shrunk in get_surface_rects).
1705-
//
1706-
// This has some precision issues because surface_rects_clipped was
1707-
// rounded already, so it's not exactly the same transform that
1708-
// get_surface_rects performed, but it is very close, since it is not
1709-
// quite the same we have to round the offset a certain way to avoid
1710-
// introducing subpixel offsets caused by the slight deviation.
1711-
let subregion_to_device_scale_x = surface_rects_clipped.width() / surface_rects_clipped_local.width();
1712-
let subregion_to_device_scale_y = surface_rects_clipped.height() / surface_rects_clipped_local.height();
1713-
let subregion_to_device_offset_x = surface_rects_clipped.min.x - (surface_rects_clipped_local.min.x * subregion_to_device_scale_x).floor();
1714-
let subregion_to_device_offset_y = surface_rects_clipped.min.y - (surface_rects_clipped_local.min.y * subregion_to_device_scale_y).floor();
1715-
17161704
// Iterate the filter nodes and create tasks
17171705
let mut made_dependency_on_source = false;
17181706
for (filter_index, (filter_node, op)) in filter_nodes.iter().enumerate() {

0 commit comments

Comments
 (0)