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:
Elias Naur 2021-03-17 12:02:41 +01:00
parent e9ff509ab9
commit df055563bd
12 changed files with 70 additions and 131 deletions

View file

@ -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),

View file

@ -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) {

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.