mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 04:31:30 +11:00
collapse annotated Fill and Stroke to Color with fill mode flag
No functionality changes, just different encoding. Updates #70 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
parent
e9ff509ab9
commit
df055563bd
|
@ -3,20 +3,15 @@ use piet_gpu_derive::piet_gpu;
|
|||
piet_gpu! {
|
||||
#[gpu_write]
|
||||
mod annotated {
|
||||
struct AnnoFill {
|
||||
// The bbox is always first, as we take advantage of common
|
||||
// layout when binning.
|
||||
bbox: [f32; 4],
|
||||
rgba_color: u32,
|
||||
}
|
||||
struct AnnoFillImage {
|
||||
bbox: [f32; 4],
|
||||
index: u32,
|
||||
offset: [i16; 2],
|
||||
}
|
||||
struct AnnoStroke {
|
||||
struct AnnoColor {
|
||||
bbox: [f32; 4],
|
||||
rgba_color: u32,
|
||||
// For stroked fills.
|
||||
// For the nonuniform scale case, this needs to be a 2x2 matrix.
|
||||
// That's expected to be uncommon, so we could special-case it.
|
||||
linewidth: f32,
|
||||
|
@ -26,8 +21,7 @@ piet_gpu! {
|
|||
}
|
||||
enum Annotated {
|
||||
Nop,
|
||||
Stroke(AnnoStroke),
|
||||
Fill(AnnoFill),
|
||||
Color(TagFlags, AnnoColor),
|
||||
FillImage(AnnoFillImage),
|
||||
BeginClip(AnnoClip),
|
||||
EndClip(AnnoClip),
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
// Code auto-generated by piet-gpu-derive
|
||||
|
||||
struct AnnoFillRef {
|
||||
uint offset;
|
||||
};
|
||||
|
||||
struct AnnoFillImageRef {
|
||||
uint offset;
|
||||
};
|
||||
|
||||
struct AnnoStrokeRef {
|
||||
struct AnnoColorRef {
|
||||
uint offset;
|
||||
};
|
||||
|
||||
|
@ -22,17 +18,6 @@ struct AnnotatedRef {
|
|||
uint offset;
|
||||
};
|
||||
|
||||
struct AnnoFill {
|
||||
vec4 bbox;
|
||||
uint rgba_color;
|
||||
};
|
||||
|
||||
#define AnnoFill_size 20
|
||||
|
||||
AnnoFillRef AnnoFill_index(AnnoFillRef ref, uint index) {
|
||||
return AnnoFillRef(ref.offset + index * AnnoFill_size);
|
||||
}
|
||||
|
||||
struct AnnoFillImage {
|
||||
vec4 bbox;
|
||||
uint index;
|
||||
|
@ -45,16 +30,16 @@ AnnoFillImageRef AnnoFillImage_index(AnnoFillImageRef ref, uint index) {
|
|||
return AnnoFillImageRef(ref.offset + index * AnnoFillImage_size);
|
||||
}
|
||||
|
||||
struct AnnoStroke {
|
||||
struct AnnoColor {
|
||||
vec4 bbox;
|
||||
uint rgba_color;
|
||||
float linewidth;
|
||||
};
|
||||
|
||||
#define AnnoStroke_size 24
|
||||
#define AnnoColor_size 24
|
||||
|
||||
AnnoStrokeRef AnnoStroke_index(AnnoStrokeRef ref, uint index) {
|
||||
return AnnoStrokeRef(ref.offset + index * AnnoStroke_size);
|
||||
AnnoColorRef AnnoColor_index(AnnoColorRef ref, uint index) {
|
||||
return AnnoColorRef(ref.offset + index * AnnoColor_size);
|
||||
}
|
||||
|
||||
struct AnnoClip {
|
||||
|
@ -68,11 +53,10 @@ AnnoClipRef AnnoClip_index(AnnoClipRef ref, uint index) {
|
|||
}
|
||||
|
||||
#define Annotated_Nop 0
|
||||
#define Annotated_Stroke 1
|
||||
#define Annotated_Fill 2
|
||||
#define Annotated_FillImage 3
|
||||
#define Annotated_BeginClip 4
|
||||
#define Annotated_EndClip 5
|
||||
#define Annotated_Color 1
|
||||
#define Annotated_FillImage 2
|
||||
#define Annotated_BeginClip 3
|
||||
#define Annotated_EndClip 4
|
||||
#define Annotated_size 28
|
||||
|
||||
AnnotatedRef Annotated_index(AnnotatedRef ref, uint index) {
|
||||
|
@ -84,28 +68,6 @@ struct AnnotatedTag {
|
|||
uint flags;
|
||||
};
|
||||
|
||||
AnnoFill AnnoFill_read(Alloc a, AnnoFillRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
uint raw1 = read_mem(a, ix + 1);
|
||||
uint raw2 = read_mem(a, ix + 2);
|
||||
uint raw3 = read_mem(a, ix + 3);
|
||||
uint raw4 = read_mem(a, ix + 4);
|
||||
AnnoFill s;
|
||||
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||
s.rgba_color = raw4;
|
||||
return s;
|
||||
}
|
||||
|
||||
void AnnoFill_write(Alloc a, AnnoFillRef ref, AnnoFill s) {
|
||||
uint ix = ref.offset >> 2;
|
||||
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
||||
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
||||
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
||||
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||
write_mem(a, ix + 4, s.rgba_color);
|
||||
}
|
||||
|
||||
AnnoFillImage AnnoFillImage_read(Alloc a, AnnoFillImageRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
|
@ -131,7 +93,7 @@ void AnnoFillImage_write(Alloc a, AnnoFillImageRef ref, AnnoFillImage s) {
|
|||
write_mem(a, ix + 5, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16));
|
||||
}
|
||||
|
||||
AnnoStroke AnnoStroke_read(Alloc a, AnnoStrokeRef ref) {
|
||||
AnnoColor AnnoColor_read(Alloc a, AnnoColorRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
uint raw1 = read_mem(a, ix + 1);
|
||||
|
@ -139,14 +101,14 @@ AnnoStroke AnnoStroke_read(Alloc a, AnnoStrokeRef ref) {
|
|||
uint raw3 = read_mem(a, ix + 3);
|
||||
uint raw4 = read_mem(a, ix + 4);
|
||||
uint raw5 = read_mem(a, ix + 5);
|
||||
AnnoStroke s;
|
||||
AnnoColor s;
|
||||
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||
s.rgba_color = raw4;
|
||||
s.linewidth = uintBitsToFloat(raw5);
|
||||
return s;
|
||||
}
|
||||
|
||||
void AnnoStroke_write(Alloc a, AnnoStrokeRef ref, AnnoStroke s) {
|
||||
void AnnoColor_write(Alloc a, AnnoColorRef ref, AnnoColor s) {
|
||||
uint ix = ref.offset >> 2;
|
||||
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
||||
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
||||
|
@ -180,12 +142,8 @@ AnnotatedTag Annotated_tag(Alloc a, AnnotatedRef ref) {
|
|||
return AnnotatedTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||
}
|
||||
|
||||
AnnoStroke Annotated_Stroke_read(Alloc a, AnnotatedRef ref) {
|
||||
return AnnoStroke_read(a, AnnoStrokeRef(ref.offset + 4));
|
||||
}
|
||||
|
||||
AnnoFill Annotated_Fill_read(Alloc a, AnnotatedRef ref) {
|
||||
return AnnoFill_read(a, AnnoFillRef(ref.offset + 4));
|
||||
AnnoColor Annotated_Color_read(Alloc a, AnnotatedRef ref) {
|
||||
return AnnoColor_read(a, AnnoColorRef(ref.offset + 4));
|
||||
}
|
||||
|
||||
AnnoFillImage Annotated_FillImage_read(Alloc a, AnnotatedRef ref) {
|
||||
|
@ -204,14 +162,9 @@ void Annotated_Nop_write(Alloc a, AnnotatedRef ref) {
|
|||
write_mem(a, ref.offset >> 2, Annotated_Nop);
|
||||
}
|
||||
|
||||
void Annotated_Stroke_write(Alloc a, AnnotatedRef ref, AnnoStroke s) {
|
||||
write_mem(a, ref.offset >> 2, Annotated_Stroke);
|
||||
AnnoStroke_write(a, AnnoStrokeRef(ref.offset + 4), s);
|
||||
}
|
||||
|
||||
void Annotated_Fill_write(Alloc a, AnnotatedRef ref, AnnoFill s) {
|
||||
write_mem(a, ref.offset >> 2, Annotated_Fill);
|
||||
AnnoFill_write(a, AnnoFillRef(ref.offset + 4), s);
|
||||
void Annotated_Color_write(Alloc a, AnnotatedRef ref, uint flags, AnnoColor s) {
|
||||
write_mem(a, ref.offset >> 2, (flags << 16) | Annotated_Color);
|
||||
AnnoColor_write(a, AnnoColorRef(ref.offset + 4), s);
|
||||
}
|
||||
|
||||
void Annotated_FillImage_write(Alloc a, AnnotatedRef ref, AnnoFillImage s) {
|
||||
|
|
|
@ -46,9 +46,13 @@ void main() {
|
|||
// Work assignment: 1 thread : 1 path element
|
||||
uint row_count = 0;
|
||||
if (element_ix < conf.n_elements) {
|
||||
uint tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
AnnotatedTag tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
switch (tag.tag) {
|
||||
case Annotated_Color:
|
||||
if (fill_mode_from_flags(tag.flags) != MODE_NONZERO) {
|
||||
break;
|
||||
}
|
||||
// Fall through.
|
||||
case Annotated_FillImage:
|
||||
case Annotated_BeginClip:
|
||||
PathRef path_ref = PathRef(conf.tile_alloc.offset + element_ix * Path_size);
|
||||
|
|
Binary file not shown.
|
@ -60,18 +60,17 @@ void main() {
|
|||
}
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
case Annotated_Color:
|
||||
case Annotated_FillImage:
|
||||
case Annotated_Stroke:
|
||||
case Annotated_BeginClip:
|
||||
case Annotated_EndClip:
|
||||
// Note: we take advantage of the fact that these drawing elements
|
||||
// have the bbox at the same place in their layout.
|
||||
AnnoFill fill = Annotated_Fill_read(conf.anno_alloc, ref);
|
||||
x0 = int(floor(fill.bbox.x * SX));
|
||||
y0 = int(floor(fill.bbox.y * SY));
|
||||
x1 = int(ceil(fill.bbox.z * SX));
|
||||
y1 = int(ceil(fill.bbox.w * SY));
|
||||
AnnoClip clip = Annotated_BeginClip_read(conf.anno_alloc, ref);
|
||||
x0 = int(floor(clip.bbox.x * SX));
|
||||
y0 = int(floor(clip.bbox.y * SY));
|
||||
x1 = int(ceil(clip.bbox.z * SX));
|
||||
y1 = int(ceil(clip.bbox.w * SY));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -202,9 +202,8 @@ void main() {
|
|||
// Bounding box of element in pixel coordinates.
|
||||
uint tile_count;
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
case Annotated_Color:
|
||||
case Annotated_FillImage:
|
||||
case Annotated_Stroke:
|
||||
case Annotated_BeginClip:
|
||||
case Annotated_EndClip:
|
||||
// We have one "path" for each element, even if the element isn't
|
||||
|
@ -305,25 +304,33 @@ void main() {
|
|||
// If that turns out to be expensive, maybe we can pack it into
|
||||
// shared memory (or perhaps just the tag).
|
||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
AnnotatedTag tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
|
||||
if (clip_zero_depth == 0) {
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
switch (tag.tag) {
|
||||
case Annotated_Color:
|
||||
Tile tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
||||
+ (sh_tile_stride[element_ref_ix] * tile_y + tile_x) * Tile_size));
|
||||
AnnoFill fill = Annotated_Fill_read(conf.anno_alloc, ref);
|
||||
AnnoColor fill = Annotated_Color_read(conf.anno_alloc, ref);
|
||||
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||
break;
|
||||
}
|
||||
if (tile.tile.offset != 0) {
|
||||
CmdFill cmd_fill;
|
||||
cmd_fill.tile_ref = tile.tile.offset;
|
||||
cmd_fill.backdrop = tile.backdrop;
|
||||
cmd_fill.rgba_color = fill.rgba_color;
|
||||
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
||||
if (fill_mode_from_flags(tag.flags) == MODE_NONZERO) {
|
||||
if (tile.tile.offset != 0) {
|
||||
CmdFill cmd_fill;
|
||||
cmd_fill.tile_ref = tile.tile.offset;
|
||||
cmd_fill.backdrop = tile.backdrop;
|
||||
cmd_fill.rgba_color = fill.rgba_color;
|
||||
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
||||
} else {
|
||||
Cmd_Solid_write(cmd_alloc, cmd_ref, CmdSolid(fill.rgba_color));
|
||||
}
|
||||
} else {
|
||||
Cmd_Solid_write(cmd_alloc, cmd_ref, CmdSolid(fill.rgba_color));
|
||||
CmdStroke cmd_stroke;
|
||||
cmd_stroke.tile_ref = tile.tile.offset;
|
||||
cmd_stroke.half_width = 0.5 * fill.linewidth;
|
||||
cmd_stroke.rgba_color = fill.rgba_color;
|
||||
Cmd_Stroke_write(cmd_alloc, cmd_ref, cmd_stroke);
|
||||
}
|
||||
cmd_ref.offset += Cmd_size;
|
||||
break;
|
||||
|
@ -387,24 +394,10 @@ void main() {
|
|||
cmd_ref.offset += Cmd_size;
|
||||
}
|
||||
break;
|
||||
case Annotated_Stroke:
|
||||
tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
||||
+ (sh_tile_stride[element_ref_ix] * tile_y + tile_x) * Tile_size));
|
||||
AnnoStroke stroke = Annotated_Stroke_read(conf.anno_alloc, ref);
|
||||
CmdStroke cmd_stroke;
|
||||
cmd_stroke.tile_ref = tile.tile.offset;
|
||||
cmd_stroke.half_width = 0.5 * stroke.linewidth;
|
||||
cmd_stroke.rgba_color = stroke.rgba_color;
|
||||
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||
break;
|
||||
}
|
||||
Cmd_Stroke_write(cmd_alloc, cmd_ref, cmd_stroke);
|
||||
cmd_ref.offset += Cmd_size;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// In "clip zero" state, suppress all drawing
|
||||
switch (tag) {
|
||||
switch (tag.tag) {
|
||||
case Annotated_BeginClip:
|
||||
clip_depth++;
|
||||
break;
|
||||
|
|
Binary file not shown.
|
@ -288,7 +288,8 @@ void main() {
|
|||
// registers (though register pressure is an issue).
|
||||
ElementRef this_ref = Element_index(ref, i);
|
||||
ElementTag tag = Element_tag(this_ref);
|
||||
bool is_stroke = fill_mode_from_flags(tag.flags) == MODE_STROKE;
|
||||
uint fill_mode = fill_mode_from_flags(tag.flags);
|
||||
bool is_stroke = fill_mode == MODE_STROKE;
|
||||
switch (tag.tag) {
|
||||
case Element_Line:
|
||||
LineSeg line = Element_Line_read(this_ref);
|
||||
|
@ -353,22 +354,18 @@ void main() {
|
|||
break;
|
||||
case Element_FillColor:
|
||||
FillColor fill = Element_FillColor_read(this_ref);
|
||||
// TODO: merge paths when annotations use tag flags.
|
||||
AnnoColor anno_fill;
|
||||
anno_fill.rgba_color = fill.rgba_color;
|
||||
if (is_stroke) {
|
||||
AnnoStroke anno_stroke;
|
||||
anno_stroke.rgba_color = fill.rgba_color;
|
||||
vec2 lw = get_linewidth(st);
|
||||
anno_stroke.bbox = st.bbox + vec4(-lw, lw);
|
||||
anno_stroke.linewidth = st.linewidth * sqrt(abs(st.mat.x * st.mat.w - st.mat.y * st.mat.z));
|
||||
AnnotatedRef out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
||||
Annotated_Stroke_write(conf.anno_alloc, out_ref, anno_stroke);
|
||||
anno_fill.bbox = st.bbox + vec4(-lw, lw);
|
||||
anno_fill.linewidth = st.linewidth * sqrt(abs(st.mat.x * st.mat.w - st.mat.y * st.mat.z));
|
||||
} else {
|
||||
AnnoFill anno_fill;
|
||||
anno_fill.rgba_color = fill.rgba_color;
|
||||
anno_fill.bbox = st.bbox;
|
||||
AnnotatedRef out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
||||
Annotated_Fill_write(conf.anno_alloc, out_ref, anno_fill);
|
||||
anno_fill.linewidth = 0.0;
|
||||
}
|
||||
AnnotatedRef out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
||||
Annotated_Color_write(conf.anno_alloc, out_ref, fill_mode, anno_fill);
|
||||
break;
|
||||
case Element_FillImage:
|
||||
FillImage fill_img = Element_FillImage_read(this_ref);
|
||||
|
@ -376,7 +373,7 @@ void main() {
|
|||
anno_fill_img.index = fill_img.index;
|
||||
anno_fill_img.offset = fill_img.offset;
|
||||
anno_fill_img.bbox = st.bbox;
|
||||
AnnotatedRef out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
||||
out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
||||
Annotated_FillImage_write(conf.anno_alloc, out_ref, anno_fill_img);
|
||||
break;
|
||||
case Element_BeginClip:
|
||||
|
|
Binary file not shown.
|
@ -43,18 +43,17 @@ void main() {
|
|||
}
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
case Annotated_Color:
|
||||
case Annotated_FillImage:
|
||||
case Annotated_Stroke:
|
||||
case Annotated_BeginClip:
|
||||
case Annotated_EndClip:
|
||||
// Note: we take advantage of the fact that fills, strokes, and
|
||||
// clips have compatible layout.
|
||||
AnnoFill fill = Annotated_Fill_read(conf.anno_alloc, ref);
|
||||
x0 = int(floor(fill.bbox.x * SX));
|
||||
y0 = int(floor(fill.bbox.y * SY));
|
||||
x1 = int(ceil(fill.bbox.z * SX));
|
||||
y1 = int(ceil(fill.bbox.w * SY));
|
||||
AnnoClip clip = Annotated_BeginClip_read(conf.anno_alloc, ref);
|
||||
x0 = int(floor(clip.bbox.x * SX));
|
||||
y0 = int(floor(clip.bbox.y * SY));
|
||||
x1 = int(ceil(clip.bbox.z * SX));
|
||||
y1 = int(ceil(clip.bbox.w * SY));
|
||||
break;
|
||||
}
|
||||
x0 = clamp(x0, 0, int(conf.width_in_tiles));
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue