Skip to content

Commit

Permalink
Full rectangular pixel snapping
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed May 26, 2017
1 parent 9cc838b commit 0a6626b
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 55 deletions.
76 changes: 39 additions & 37 deletions webrender/res/prim_shared.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,16 @@ vec2 clamp_rect(vec2 point, RectWithEndpoint rect) {
return clamp(point, rect.p0, rect.p1);
}

// Clamp 2 points at once.
vec4 clamp_rect(vec4 points, RectWithSize rect) {
return clamp(points, rect.p0.xyxy, rect.p0.xyxy + rect.size.xyxy);
}

vec4 clamp_rect(vec4 points, RectWithEndpoint rect) {
return clamp(points, rect.p0.xyxy, rect.p1.xyxy);
RectWithEndpoint intersect_rect(RectWithEndpoint a, RectWithEndpoint b) {
vec2 p0 = clamp_rect(a.p0, b);
vec2 p1 = clamp_rect(a.p1, b);
return RectWithEndpoint(p0, max(p0, p1));
}

RectWithSize intersect_rect(RectWithSize a, RectWithSize b) {
vec4 p = clamp_rect(vec4(a.p0, a.p0 + a.size), b);
return RectWithSize(p.xy, max(vec2(0.0), p.zw - p.xy));
}

RectWithEndpoint intersect_rect(RectWithEndpoint a, RectWithEndpoint b) {
vec4 p = clamp_rect(vec4(a.p0, a.p1), b);
return RectWithEndpoint(p.xy, max(p.xy, p.zw));
RectWithEndpoint r = intersect_rect(to_rect_with_endpoint(a),
to_rect_with_endpoint(b));
return to_rect_with_size(r);
}

float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
Expand Down Expand Up @@ -573,38 +566,46 @@ VertexInfo write_vertex(RectWithSize instance_rect,
float z,
Layer layer,
AlphaBatchTask task,
vec2 snap_ref) {
RectWithSize snap_rect) {

// Select the corner of the local rect that we are processing.
vec2 local_pos = instance_rect.p0 + instance_rect.size * aPosition.xy;

// xy = top left corner of the local rect, zw = position of current vertex.
vec4 local_p0_pos = vec4(snap_ref, local_pos);

// Clamp to the two local clip rects.
local_p0_pos = clamp_rect(local_p0_pos, local_clip_rect);
local_p0_pos = clamp_rect(local_p0_pos, layer.local_clip_rect);

// Transform the top corner and current vertex to world space.
vec4 world_p0 = layer.transform * vec4(local_p0_pos.xy, 0.0, 1.0);
world_p0.xyz /= world_p0.w;
vec4 world_pos = layer.transform * vec4(local_p0_pos.zw, 0.0, 1.0);
world_pos.xyz /= world_pos.w;

// Convert the world positions to device pixel space. xy=top left corner. zw=current vertex.
vec4 device_p0_pos = vec4(world_p0.xy, world_pos.xy) * uDevicePixelRatio;

// Calculate the distance to snap the vertex by (snap top left corner).
vec2 snap_delta = device_p0_pos.xy - floor(device_p0_pos.xy + 0.5);
vec2 clamped_local_pos = clamp_rect(clamp_rect(local_pos, local_clip_rect),
layer.local_clip_rect);

// Adjust the snap rectangle.
RectWithSize clamped_snap_rect = intersect_rect(intersect_rect(snap_rect, local_clip_rect),
layer.local_clip_rect);
// Transform the snap corners to the world space.
vec4 world_snap_p0 = layer.transform * vec4(clamped_snap_rect.p0, 0.0, 1.0);
vec4 world_snap_p1 = layer.transform * vec4(clamped_snap_rect.p0 + clamped_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 = uDevicePixelRatio * vec4(world_snap_p0.xy, world_snap_p1.xy) /
vec4(world_snap_p0.ww, world_snap_p1.ww);
/// World offsets applied to the corners of the snap rectangle.
vec4 snap_offsets = floor(world_snap + 0.5) - world_snap;

/// Compute the position of this vertex inside the snap rectangle.
vec2 normalized_snap_pos = (clamped_local_pos - clamped_snap_rect.p0) / clamped_snap_rect.size;
/// Compute the actual world offset for this vertex needed to make it snap.
vec2 snap_offset = mix(snap_offsets.xy, snap_offsets.zw, normalized_snap_pos);

// Transform the current vertex to the world cpace.
vec4 world_pos = layer.transform * vec4(clamped_local_pos, 0.0, 1.0);

// Convert the world positions to device pixel space.
vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;

// Apply offsets for the render task to get correct screen location.
vec2 final_pos = device_p0_pos.zw -
snap_delta -
vec2 final_pos = device_pos + snap_offset -
task.screen_space_origin +
task.render_target_origin;

gl_Position = uTransform * vec4(final_pos, z, 1.0);

VertexInfo vi = VertexInfo(local_p0_pos.zw, device_p0_pos.zw);
VertexInfo vi = VertexInfo(clamped_local_pos, device_pos);
return vi;
}

Expand Down Expand Up @@ -639,7 +640,7 @@ TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
float z,
Layer layer,
AlphaBatchTask task,
vec2 snap_ref) {
RectWithSize snap_rect) {
RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);

vec2 current_local_pos, prev_local_pos, next_local_pos;
Expand Down Expand Up @@ -699,7 +700,8 @@ TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
adjusted_next_p1);

// Calculate the snap amount based on the first vertex as a reference point.
vec4 world_p0 = layer.transform * vec4(snap_ref, 0.0, 1.0);
//TODO: full rectangle snapping, similar to `write_vertex`
vec4 world_p0 = layer.transform * vec4(snap_rect.p0, 0.0, 1.0);
vec2 device_p0 = uDevicePixelRatio * world_p0.xy / world_p0.w;
vec2 snap_delta = device_p0 - floor(device_p0 + 0.5);

Expand Down
2 changes: 1 addition & 1 deletion webrender/res/ps_angle_gradient.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vPos = vi.local_pos - prim.local_rect.p0;

Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_border_corner.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,14 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#else
VertexInfo vi = write_vertex(segment_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

vLocalPos = vi.local_pos;
Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_border_edge.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,14 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#else
VertexInfo vi = write_vertex(segment_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

vLocalPos = vi.local_pos;
Expand Down
2 changes: 1 addition & 1 deletion webrender/res/ps_box_shadow.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
Expand Down
2 changes: 1 addition & 1 deletion webrender/res/ps_cache_image.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_gradient.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
vec2 f = (vi.local_pos.xy - prim.local_rect.p0) / prim.local_rect.size;
#else
Expand All @@ -71,7 +71,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vec2 f = (vi.local_pos - segment_rect.p0) / segment_rect.size;
vPos = vi.local_pos;
Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_image.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos - prim.local_rect.p0;
#endif

Expand Down
2 changes: 1 addition & 1 deletion webrender/res/ps_radial_gradient.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vPos = vi.local_pos - prim.local_rect.p0;

Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_rectangle.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

#ifdef WR_FEATURE_CLIP
Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_text_run.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
local_rect.p0);
local_rect);
vLocalPos = vi.local_pos;
vec2 f = (vi.local_pos.xy / vi.local_pos.z - local_rect.p0) / local_rect.size;
#else
Expand All @@ -27,7 +27,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
local_rect.p0);
local_rect);
vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
#endif

Expand Down
4 changes: 2 additions & 2 deletions webrender/res/ps_yuv_image.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos - prim.local_rect.p0;
#endif

Expand Down

0 comments on commit 0a6626b

Please sign in to comment.