gecko-dev/gfx/wr/webrender/res/snap.glsl

69 строки
2.7 KiB
GLSL

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef WR_VERTEX_SHADER
vec4 compute_snap_positions(
mat4 transform,
RectWithSize snap_rect,
float device_pixel_scale
) {
// Ensure that the snap rect is at *least* one device pixel in size.
// TODO(gw): It's not clear to me that this is "correct". Specifically,
// how should it interact with sub-pixel snap rects when there
// is a transform with scale present? But it does fix
// the test cases we have in Servo that are failing without it
// and seem better than not having this at all.
snap_rect.size = max(snap_rect.size, vec2(1.0 / device_pixel_scale));
// Transform the snap corners to the world space.
vec4 world_snap_p0 = transform * vec4(snap_rect.p0, 0.0, 1.0);
vec4 world_snap_p1 = transform * vec4(snap_rect.p0 + snap_rect.size, 0.0, 1.0);
// Snap bounds in world coordinates, adjusted for pixel ratio. XY = top left, ZW = bottom right
vec4 world_snap = device_pixel_scale * vec4(world_snap_p0.xy, world_snap_p1.xy) /
vec4(world_snap_p0.ww, world_snap_p1.ww);
return world_snap;
}
/// Given a point within a local rectangle, and the device space corners
/// of a snapped primitive, return the snap offsets. This *must* exactly
/// match the logic in the GLSL compute_snap_offset_impl function.
vec2 compute_snap_offset_impl(
vec2 reference_pos,
RectWithSize reference_rect,
vec4 snap_positions
) {
/// World offsets applied to the corners of the snap rectangle.
vec4 snap_offsets = floor(snap_positions + 0.5) - snap_positions;
/// Compute the position of this vertex inside the snap rectangle.
vec2 normalized_snap_pos = (reference_pos - reference_rect.p0) / reference_rect.size;
/// Compute the actual world offset for this vertex needed to make it snap.
return mix(snap_offsets.xy, snap_offsets.zw, normalized_snap_pos);
}
// Compute a snapping offset in world space (adjusted to pixel ratio),
// given local position on the transform and a snap rectangle.
vec2 compute_snap_offset(vec2 local_pos,
mat4 transform,
RectWithSize snap_rect,
float device_pixel_scale) {
vec4 snap_positions = compute_snap_positions(
transform,
snap_rect,
device_pixel_scale
);
vec2 snap_offsets = compute_snap_offset_impl(
local_pos,
snap_rect,
snap_positions
);
return snap_offsets;
}
#endif //WR_VERTEX_SHADER