mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
change tile segment representation to (origin, vector)
Eliminates the precision loss of the subtraction in the sign(end.x - start.x) expression in kernel4. That's important for the next change that avoids inconsistent line intersections in path_coarse. Updates #23 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
parent
2068171f96
commit
19f4d9fa95
|
@ -13,8 +13,8 @@ piet_gpu! {
|
||||||
}
|
}
|
||||||
// Segments within a tile are represented as a linked list.
|
// Segments within a tile are represented as a linked list.
|
||||||
struct TileSeg {
|
struct TileSeg {
|
||||||
start: [f32; 2],
|
origin: [f32; 2],
|
||||||
end: [f32; 2],
|
vector: [f32; 2],
|
||||||
y_edge: f32,
|
y_edge: f32,
|
||||||
next: Ref<TileSeg>,
|
next: Ref<TileSeg>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,8 @@ float[CHUNK] computeArea(vec2 xy, int backdrop, uint tile_ref) {
|
||||||
TileSeg seg = TileSeg_read(tile_seg_ref);
|
TileSeg seg = TileSeg_read(tile_seg_ref);
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
vec2 my_xy = vec2(xy.x, xy.y + float(k * CHUNK_DY));
|
vec2 my_xy = vec2(xy.x, xy.y + float(k * CHUNK_DY));
|
||||||
vec2 start = seg.start - my_xy;
|
vec2 start = seg.origin - my_xy;
|
||||||
vec2 end = seg.end - my_xy;
|
vec2 end = start + seg.vector;
|
||||||
vec2 window = clamp(vec2(start.y, end.y), 0.0, 1.0);
|
vec2 window = clamp(vec2(start.y, end.y), 0.0, 1.0);
|
||||||
if (window.x != window.y) {
|
if (window.x != window.y) {
|
||||||
vec2 t = (window - start.y) / (end.y - start.y);
|
vec2 t = (window - start.y) / (end.y - start.y);
|
||||||
|
@ -79,7 +79,7 @@ float[CHUNK] computeArea(vec2 xy, int backdrop, uint tile_ref) {
|
||||||
float a = (b + 0.5 * (d * d - c * c) - xmin) / (xmax - xmin);
|
float a = (b + 0.5 * (d * d - c * c) - xmin) / (xmax - xmin);
|
||||||
area[k] += a * (window.x - window.y);
|
area[k] += a * (window.x - window.y);
|
||||||
}
|
}
|
||||||
area[k] += sign(end.x - start.x) * clamp(my_xy.y - seg.y_edge + 1.0, 0.0, 1.0);
|
area[k] += sign(seg.vector.x) * clamp(my_xy.y - seg.y_edge + 1.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
tile_seg_ref = seg.next;
|
tile_seg_ref = seg.next;
|
||||||
} while (tile_seg_ref.offset != 0);
|
} while (tile_seg_ref.offset != 0);
|
||||||
|
@ -131,9 +131,9 @@ void main() {
|
||||||
TileSegRef tile_seg_ref = TileSegRef(stroke.tile_ref);
|
TileSegRef tile_seg_ref = TileSegRef(stroke.tile_ref);
|
||||||
do {
|
do {
|
||||||
TileSeg seg = TileSeg_read(tile_seg_ref);
|
TileSeg seg = TileSeg_read(tile_seg_ref);
|
||||||
vec2 line_vec = seg.end - seg.start;
|
vec2 line_vec = seg.vector;
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
vec2 dpos = xy + vec2(0.5, 0.5) - seg.start;
|
vec2 dpos = xy + vec2(0.5, 0.5) - seg.origin;
|
||||||
dpos.y += float(k * CHUNK_DY);
|
dpos.y += float(k * CHUNK_DY);
|
||||||
float t = clamp(dot(line_vec, dpos) / dot(line_vec, line_vec), 0.0, 1.0);
|
float t = clamp(dot(line_vec, dpos) / dot(line_vec, line_vec), 0.0, 1.0);
|
||||||
df[k] = min(df[k], length(line_vec * t - dpos));
|
df[k] = min(df[k], length(line_vec * t - dpos));
|
||||||
|
|
Binary file not shown.
|
@ -205,16 +205,18 @@ void main() {
|
||||||
TileRef tile_ref = Tile_index(path.tiles, uint(base + x));
|
TileRef tile_ref = Tile_index(path.tiles, uint(base + x));
|
||||||
uint tile_el = tile_ref.offset >> 2;
|
uint tile_el = tile_ref.offset >> 2;
|
||||||
uint old = atomicExchange(tile[tile_el], tile_offset);
|
uint old = atomicExchange(tile[tile_el], tile_offset);
|
||||||
tile_seg.start = p0;
|
tile_seg.origin = p0;
|
||||||
tile_seg.end = p1;
|
tile_seg.vector = p1 - p0;
|
||||||
float y_edge = 0.0;
|
float y_edge = 0.0;
|
||||||
if (tag == PathSeg_FillCubic) {
|
if (tag == PathSeg_FillCubic) {
|
||||||
y_edge = mix(p0.y, p1.y, (tile_x0 - p0.x) / dx);
|
y_edge = mix(p0.y, p1.y, (tile_x0 - p0.x) / dx);
|
||||||
if (min(p0.x, p1.x) < tile_x0 && y_edge >= tile_y0 && y_edge < tile_y0 + TILE_HEIGHT_PX) {
|
if (min(p0.x, p1.x) < tile_x0 && y_edge >= tile_y0 && y_edge < tile_y0 + TILE_HEIGHT_PX) {
|
||||||
|
vec2 p = vec2(tile_x0, y_edge);
|
||||||
if (p0.x > p1.x) {
|
if (p0.x > p1.x) {
|
||||||
tile_seg.end = vec2(tile_x0, y_edge);
|
tile_seg.vector = p - p0;
|
||||||
} else {
|
} else {
|
||||||
tile_seg.start = vec2(tile_x0, y_edge);
|
tile_seg.origin = p;
|
||||||
|
tile_seg.vector = p1 - p;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
y_edge = 1e9;
|
y_edge = 1e9;
|
||||||
|
|
Binary file not shown.
|
@ -35,8 +35,8 @@ TileRef Tile_index(TileRef ref, uint index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TileSeg {
|
struct TileSeg {
|
||||||
vec2 start;
|
vec2 origin;
|
||||||
vec2 end;
|
vec2 vector;
|
||||||
float y_edge;
|
float y_edge;
|
||||||
TileSegRef next;
|
TileSegRef next;
|
||||||
};
|
};
|
||||||
|
@ -90,8 +90,8 @@ TileSeg TileSeg_read(TileSegRef ref) {
|
||||||
uint raw4 = tile[ix + 4];
|
uint raw4 = tile[ix + 4];
|
||||||
uint raw5 = tile[ix + 5];
|
uint raw5 = tile[ix + 5];
|
||||||
TileSeg s;
|
TileSeg s;
|
||||||
s.start = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
s.origin = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
||||||
s.end = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
s.vector = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
s.y_edge = uintBitsToFloat(raw4);
|
s.y_edge = uintBitsToFloat(raw4);
|
||||||
s.next = TileSegRef(raw5);
|
s.next = TileSegRef(raw5);
|
||||||
return s;
|
return s;
|
||||||
|
@ -99,10 +99,10 @@ TileSeg TileSeg_read(TileSegRef ref) {
|
||||||
|
|
||||||
void TileSeg_write(TileSegRef ref, TileSeg s) {
|
void TileSeg_write(TileSegRef ref, TileSeg s) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
tile[ix + 0] = floatBitsToUint(s.start.x);
|
tile[ix + 0] = floatBitsToUint(s.origin.x);
|
||||||
tile[ix + 1] = floatBitsToUint(s.start.y);
|
tile[ix + 1] = floatBitsToUint(s.origin.y);
|
||||||
tile[ix + 2] = floatBitsToUint(s.end.x);
|
tile[ix + 2] = floatBitsToUint(s.vector.x);
|
||||||
tile[ix + 3] = floatBitsToUint(s.end.y);
|
tile[ix + 3] = floatBitsToUint(s.vector.y);
|
||||||
tile[ix + 4] = floatBitsToUint(s.y_edge);
|
tile[ix + 4] = floatBitsToUint(s.y_edge);
|
||||||
tile[ix + 5] = s.next.offset;
|
tile[ix + 5] = s.next.offset;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue