Skip to content

Commit

Permalink
Continuing work on clips
Browse files Browse the repository at this point in the history
I realized there's a problem with encoding clip bboxes relative to the
current transform (see #36 for a more detailed explanation), so this is
changing it to absolute bboxes.

This more or less gets clips working. There are optimization
opportunities (all-clear and all-opaque mask tiles), and it doesn't deal
with overflow of the blend stack, but it seems to basically work.
  • Loading branch information
raphlinus committed Nov 21, 2020
1 parent f53d00e commit d14895b
Show file tree
Hide file tree
Showing 23 changed files with 268 additions and 161 deletions.
8 changes: 5 additions & 3 deletions piet-gpu-types/src/annotated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ piet_gpu! {
#[gpu_write]
mod annotated {
struct AnnoFill {
rgba_color: u32,
// The bbox is always first, as we take advantage of common
// layout when binning.
bbox: [f32; 4],
rgba_color: u32,
}
struct AnnoFillMask {
mask: f32,
bbox: [f32; 4],
mask: f32,
}
struct AnnoStroke {
rgba_color: u32,
bbox: [f32; 4],
rgba_color: u32,
// 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,
Expand Down
3 changes: 0 additions & 3 deletions piet-gpu-types/src/bins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ piet_gpu! {
mod bins {
struct BinInstance {
element_ix: u32,
// Right edge of the bounding box of the associated fill
// element; used in backdrop computation.
right_edge: f32,
}

struct BinChunk {
Expand Down
6 changes: 6 additions & 0 deletions piet-gpu-types/src/ptcl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ piet_gpu! {
tile_ref: u32,
backdrop: i32,
}
// This is mostly here for expedience and can always be optimized
// out for pure clips, but will be useful for blend groups.
struct CmdBeginSolidClip {
alpha: f32,
}
struct CmdEndClip {
// This will be 1.0 for clips, but we can imagine blend groups.
alpha: f32,
Expand All @@ -55,6 +60,7 @@ piet_gpu! {
FillMask(CmdFillMask),
FillMaskInv(CmdFillMask),
BeginClip(CmdBeginClip),
BeginSolidClip(CmdBeginSolidClip),
EndClip(CmdEndClip),
Stroke(CmdStroke),
Solid(CmdSolid),
Expand Down
13 changes: 4 additions & 9 deletions piet-gpu-types/src/scene.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use piet_gpu_derive::piet_gpu;

pub use self::scene::{
BeginClip, CubicSeg, Element, EndClip, Fill, LineSeg, QuadSeg, SetLineWidth, Stroke, Transform,
Clip, CubicSeg, Element, Fill, LineSeg, QuadSeg, SetLineWidth, Stroke, Transform,
};

piet_gpu! {
Expand Down Expand Up @@ -38,15 +38,10 @@ piet_gpu! {
mat: [f32; 4],
translate: [f32; 2],
}
struct BeginClip {
struct Clip {
bbox: [f32; 4],
// TODO: add alpha?
}
struct EndClip {
// The delta between the BeginClip and EndClip element indices.
// It is stored as a delta to facilitate binary string concatenation.
delta: u32,
}
enum Element {
Nop,
// Another approach to encoding would be to use a single
Expand All @@ -66,8 +61,8 @@ piet_gpu! {
Transform(Transform),
FillMask(FillMask),
FillMaskInv(FillMask),
BeginClip(BeginClip),
EndClip(EndClip),
BeginClip(Clip),
EndClip(Clip),
}
}
}
36 changes: 34 additions & 2 deletions piet-gpu/bin/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,38 @@ fn trace_ptcl(buf: &[u32]) {
}
}
}
6 => {
let backdrop = buf[tile_offset / 4 + 2];
println!(" {:x}: begin_clip {}", tile_offset, backdrop);
let mut seg_chunk = buf[tile_offset / 4 + 1] as usize;
let n = buf[seg_chunk / 4] as usize;
let segs = buf[seg_chunk / 4 + 2] as usize;
println!(" chunk @{:x}: n={}, segs @{:x}", seg_chunk, n, segs);
for i in 0..n {
let x0 = f32::from_bits(buf[segs / 4 + i * 5]);
let y0 = f32::from_bits(buf[segs / 4 + i * 5 + 1]);
let x1 = f32::from_bits(buf[segs / 4 + i * 5 + 2]);
let y1 = f32::from_bits(buf[segs / 4 + i * 5 + 3]);
let y_edge = f32::from_bits(buf[segs / 4 + i * 5 + 4]);
println!(
" ({:.3}, {:.3}) - ({:.3}, {:.3}) | {:.3}",
x0, y0, x1, y1, y_edge
);
}
loop {
seg_chunk = buf[seg_chunk / 4 + 1] as usize;
if seg_chunk == 0 {
break;
}
}
}
7 => {
let backdrop = buf[tile_offset / 4 + 1];
println!("{:x}: solid_clip {:x}", tile_offset, backdrop);
}
8 => {
println!("{:x}: end_clip", tile_offset);
}
_ => {
println!("{:x}: {}", tile_offset, tag);
}
Expand Down Expand Up @@ -246,9 +278,9 @@ fn main() -> Result<(), Error> {

/*
let mut data: Vec<u32> = Default::default();
device.read_buffer(&renderer.tile_buf, &mut data).unwrap();
renderer.tile_buf.read(&mut data).unwrap();
piet_gpu::dump_k1_data(&data);
//trace_ptcl(&data);
trace_ptcl(&data);
*/

let mut img_data: Vec<u8> = Default::default();
Expand Down
48 changes: 24 additions & 24 deletions piet-gpu/shader/annotated.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ struct AnnotatedRef {
};

struct AnnoFill {
uint rgba_color;
vec4 bbox;
uint rgba_color;
};

#define AnnoFill_size 20
Expand All @@ -32,8 +32,8 @@ AnnoFillRef AnnoFill_index(AnnoFillRef ref, uint index) {
}

struct AnnoFillMask {
float mask;
vec4 bbox;
float mask;
};

#define AnnoFillMask_size 20
Expand All @@ -43,8 +43,8 @@ AnnoFillMaskRef AnnoFillMask_index(AnnoFillMaskRef ref, uint index) {
}

struct AnnoStroke {
uint rgba_color;
vec4 bbox;
uint rgba_color;
float linewidth;
};

Expand Down Expand Up @@ -85,18 +85,18 @@ AnnoFill AnnoFill_read(AnnoFillRef ref) {
uint raw3 = annotated[ix + 3];
uint raw4 = annotated[ix + 4];
AnnoFill s;
s.rgba_color = raw0;
s.bbox = vec4(uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3), uintBitsToFloat(raw4));
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
s.rgba_color = raw4;
return s;
}

void AnnoFill_write(AnnoFillRef ref, AnnoFill s) {
uint ix = ref.offset >> 2;
annotated[ix + 0] = s.rgba_color;
annotated[ix + 1] = floatBitsToUint(s.bbox.x);
annotated[ix + 2] = floatBitsToUint(s.bbox.y);
annotated[ix + 3] = floatBitsToUint(s.bbox.z);
annotated[ix + 4] = floatBitsToUint(s.bbox.w);
annotated[ix + 0] = floatBitsToUint(s.bbox.x);
annotated[ix + 1] = floatBitsToUint(s.bbox.y);
annotated[ix + 2] = floatBitsToUint(s.bbox.z);
annotated[ix + 3] = floatBitsToUint(s.bbox.w);
annotated[ix + 4] = s.rgba_color;
}

AnnoFillMask AnnoFillMask_read(AnnoFillMaskRef ref) {
Expand All @@ -107,18 +107,18 @@ AnnoFillMask AnnoFillMask_read(AnnoFillMaskRef ref) {
uint raw3 = annotated[ix + 3];
uint raw4 = annotated[ix + 4];
AnnoFillMask s;
s.mask = uintBitsToFloat(raw0);
s.bbox = vec4(uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3), uintBitsToFloat(raw4));
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
s.mask = uintBitsToFloat(raw4);
return s;
}

void AnnoFillMask_write(AnnoFillMaskRef ref, AnnoFillMask s) {
uint ix = ref.offset >> 2;
annotated[ix + 0] = floatBitsToUint(s.mask);
annotated[ix + 1] = floatBitsToUint(s.bbox.x);
annotated[ix + 2] = floatBitsToUint(s.bbox.y);
annotated[ix + 3] = floatBitsToUint(s.bbox.z);
annotated[ix + 4] = floatBitsToUint(s.bbox.w);
annotated[ix + 0] = floatBitsToUint(s.bbox.x);
annotated[ix + 1] = floatBitsToUint(s.bbox.y);
annotated[ix + 2] = floatBitsToUint(s.bbox.z);
annotated[ix + 3] = floatBitsToUint(s.bbox.w);
annotated[ix + 4] = floatBitsToUint(s.mask);
}

AnnoStroke AnnoStroke_read(AnnoStrokeRef ref) {
Expand All @@ -130,19 +130,19 @@ AnnoStroke AnnoStroke_read(AnnoStrokeRef ref) {
uint raw4 = annotated[ix + 4];
uint raw5 = annotated[ix + 5];
AnnoStroke s;
s.rgba_color = raw0;
s.bbox = vec4(uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3), uintBitsToFloat(raw4));
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
s.rgba_color = raw4;
s.linewidth = uintBitsToFloat(raw5);
return s;
}

void AnnoStroke_write(AnnoStrokeRef ref, AnnoStroke s) {
uint ix = ref.offset >> 2;
annotated[ix + 0] = s.rgba_color;
annotated[ix + 1] = floatBitsToUint(s.bbox.x);
annotated[ix + 2] = floatBitsToUint(s.bbox.y);
annotated[ix + 3] = floatBitsToUint(s.bbox.z);
annotated[ix + 4] = floatBitsToUint(s.bbox.w);
annotated[ix + 0] = floatBitsToUint(s.bbox.x);
annotated[ix + 1] = floatBitsToUint(s.bbox.y);
annotated[ix + 2] = floatBitsToUint(s.bbox.z);
annotated[ix + 3] = floatBitsToUint(s.bbox.w);
annotated[ix + 4] = s.rgba_color;
annotated[ix + 5] = floatBitsToUint(s.linewidth);
}

Expand Down
1 change: 1 addition & 0 deletions piet-gpu/shader/backdrop.comp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void main() {
case Annotated_Fill:
case Annotated_FillMask:
case Annotated_FillMaskInv:
case Annotated_BeginClip:
PathRef path_ref = PathRef(element_ix * Path_size);
Path path = Path_read(path_ref);
sh_row_width[th_ix] = path.bbox.z - path.bbox.x;
Expand Down
Binary file modified piet-gpu/shader/backdrop.spv
Binary file not shown.
12 changes: 5 additions & 7 deletions piet-gpu/shader/binning.comp
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,20 @@ void main() {
tag = Annotated_tag(ref);
}
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
float my_right_edge = INFINITY;
switch (tag) {
case Annotated_Fill:
case Annotated_FillMask:
case Annotated_FillMaskInv:
case Annotated_Stroke:
// Note: we take advantage of the fact that fills and strokes
// have compatible layout.
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(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));
// It probably makes more sense to track x1, to avoid having to redo
// the rounding to tile coords.
my_right_edge = fill.bbox.z;
break;
}

Expand Down Expand Up @@ -131,7 +129,7 @@ void main() {
idx += count[my_slice - 1][bin_ix];
}
uint out_offset = sh_chunk_start[bin_ix] + idx * BinInstance_size;
BinInstance_write(BinInstanceRef(out_offset), BinInstance(element_ix, my_right_edge));
BinInstance_write(BinInstanceRef(out_offset), BinInstance(element_ix));
}
x++;
if (x == x1) {
Expand Down
Binary file modified piet-gpu/shader/binning.spv
Binary file not shown.
6 changes: 1 addition & 5 deletions piet-gpu/shader/bins.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ struct BinChunkRef {

struct BinInstance {
uint element_ix;
float right_edge;
};

#define BinInstance_size 8
#define BinInstance_size 4

BinInstanceRef BinInstance_index(BinInstanceRef ref, uint index) {
return BinInstanceRef(ref.offset + index * BinInstance_size);
Expand All @@ -33,17 +32,14 @@ BinChunkRef BinChunk_index(BinChunkRef ref, uint index) {
BinInstance BinInstance_read(BinInstanceRef ref) {
uint ix = ref.offset >> 2;
uint raw0 = bins[ix + 0];
uint raw1 = bins[ix + 1];
BinInstance s;
s.element_ix = raw0;
s.right_edge = uintBitsToFloat(raw1);
return s;
}

void BinInstance_write(BinInstanceRef ref, BinInstance s) {
uint ix = ref.offset >> 2;
bins[ix + 0] = s.element_ix;
bins[ix + 1] = floatBitsToUint(s.right_edge);
}

BinChunk BinChunk_read(BinChunkRef ref) {
Expand Down
Loading

0 comments on commit d14895b

Please sign in to comment.