diff --git a/piet-gpu-types/src/ptcl.rs b/piet-gpu-types/src/ptcl.rs index b35b9bf..41cebc7 100644 --- a/piet-gpu-types/src/ptcl.rs +++ b/piet-gpu-types/src/ptcl.rs @@ -8,54 +8,35 @@ piet_gpu! { // references. tile_ref: u32, half_width: f32, - rgba_color: u32, } struct CmdFill { // As above, really Ref tile_ref: u32, backdrop: i32, + } + struct CmdColor { rgba_color: u32, } - struct CmdFillImage { - // As above, really Ref - tile_ref: u32, - backdrop: i32, + struct CmdImage { index: u32, offset: [i16; 2], } - struct CmdBeginClip { - 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 { + struct CmdAlpha { alpha: f32, } - struct CmdEndClip { - // This will be 1.0 for clips, but we can imagine blend groups. - alpha: f32, - } - struct CmdSolid { - rgba_color: u32, - } - struct CmdSolidImage { - index: u32, - offset: [i16; 2], - } struct CmdJump { new_ref: u32, } enum Cmd { End, Fill(CmdFill), - FillImage(CmdFillImage), - BeginClip(CmdBeginClip), - BeginSolidClip(CmdBeginSolidClip), - EndClip(CmdEndClip), Stroke(CmdStroke), - Solid(CmdSolid), - SolidImage(CmdSolidImage), + Solid, + Alpha(CmdAlpha), + Color(CmdColor), + Image(CmdImage), + BeginClip, + EndClip, Jump(CmdJump), } } diff --git a/piet-gpu/shader/coarse.comp b/piet-gpu/shader/coarse.comp index fb7f448..0e37985 100644 --- a/piet-gpu/shader/coarse.comp +++ b/piet-gpu/shader/coarse.comp @@ -70,6 +70,9 @@ Alloc read_tile_alloc(uint el_ix) { } #endif +// The maximum number of commands per annotated element. +#define ANNO_COMMANDS 2 + // Perhaps cmd_alloc should be a global? This is a style question. bool alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit) { if (cmd_ref.offset < cmd_limit) { @@ -83,7 +86,8 @@ bool alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit Cmd_Jump_write(cmd_alloc, cmd_ref, jump); cmd_alloc = new_cmd.alloc; cmd_ref = CmdRef(cmd_alloc.offset); - cmd_limit = cmd_alloc.offset + PTCL_INITIAL_ALLOC - 2 * Cmd_size; + // Reserve space for the maximum number of commands and a potential jump. + cmd_limit = cmd_alloc.offset + PTCL_INITIAL_ALLOC - (ANNO_COMMANDS + 1) * Cmd_size; return true; } @@ -110,7 +114,8 @@ void main() { uint this_tile_ix = (bin_tile_y + tile_y) * conf.width_in_tiles + bin_tile_x + tile_x; Alloc cmd_alloc = slice_mem(conf.ptcl_alloc, this_tile_ix * PTCL_INITIAL_ALLOC, PTCL_INITIAL_ALLOC); CmdRef cmd_ref = CmdRef(cmd_alloc.offset); - uint cmd_limit = cmd_ref.offset + PTCL_INITIAL_ALLOC - 2 * Cmd_size; + // Reserve space for the maximum number of commands and a potential jump. + uint cmd_limit = cmd_ref.offset + PTCL_INITIAL_ALLOC - (ANNO_COMMANDS + 1) * Cmd_size; // The nesting depth of the clip stack uint clip_depth = 0; // State for the "clip zero" optimization. If it's nonzero, then we are @@ -320,19 +325,19 @@ void main() { 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)); + Cmd_Solid_write(cmd_alloc, cmd_ref); } } else { 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; + Cmd_Color_write(cmd_alloc, cmd_ref, CmdColor(fill.rgba_color)); + cmd_ref.offset += Cmd_size; break; case Annotated_FillImage: tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix] @@ -342,19 +347,16 @@ void main() { break; } if (tile.tile.offset != 0) { - CmdFillImage cmd_fill_img; - cmd_fill_img.tile_ref = tile.tile.offset; - cmd_fill_img.backdrop = tile.backdrop; - cmd_fill_img.index = fill_img.index; - cmd_fill_img.offset = fill_img.offset; - Cmd_FillImage_write(cmd_alloc, cmd_ref, cmd_fill_img); + CmdFill cmd_fill; + cmd_fill.tile_ref = tile.tile.offset; + cmd_fill.backdrop = tile.backdrop; + Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill); } else { - CmdSolidImage cmd_solid_img; - cmd_solid_img.index = fill_img.index; - cmd_solid_img.offset = fill_img.offset; - Cmd_SolidImage_write(cmd_alloc, cmd_ref, cmd_solid_img); + Cmd_Solid_write(cmd_alloc, cmd_ref); } cmd_ref.offset += Cmd_size; + Cmd_Image_write(cmd_alloc, cmd_ref, CmdImage(fill_img.index, fill_img.offset)); + cmd_ref.offset += Cmd_size; break; case Annotated_BeginClip: tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix] @@ -368,16 +370,18 @@ void main() { break; } if (tile.tile.offset != 0) { - CmdBeginClip cmd_begin_clip; - cmd_begin_clip.tile_ref = tile.tile.offset; - cmd_begin_clip.backdrop = tile.backdrop; - Cmd_BeginClip_write(cmd_alloc, cmd_ref, cmd_begin_clip); + CmdFill cmd_fill; + cmd_fill.tile_ref = tile.tile.offset; + cmd_fill.backdrop = tile.backdrop; + Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill); } else { // TODO: here is where a bunch of optimization magic should happen float alpha = tile.backdrop == 0 ? 0.0 : 1.0; - Cmd_BeginSolidClip_write(cmd_alloc, cmd_ref, CmdBeginSolidClip(alpha)); + Cmd_Alpha_write(cmd_alloc, cmd_ref, CmdAlpha(alpha)); } cmd_ref.offset += Cmd_size; + Cmd_BeginClip_write(cmd_alloc, cmd_ref); + cmd_ref.offset += Cmd_size; if (clip_depth < 32) { clip_one_mask &= ~(1 << clip_depth); } @@ -390,7 +394,9 @@ void main() { if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) { break; } - Cmd_EndClip_write(cmd_alloc, cmd_ref, CmdEndClip(1.0)); + Cmd_Solid_write(cmd_alloc, cmd_ref); + cmd_ref.offset += Cmd_size; + Cmd_EndClip_write(cmd_alloc, cmd_ref); cmd_ref.offset += Cmd_size; } break; diff --git a/piet-gpu/shader/coarse.spv b/piet-gpu/shader/coarse.spv index 09bad96..9cc6cc6 100644 Binary files a/piet-gpu/shader/coarse.spv and b/piet-gpu/shader/coarse.spv differ diff --git a/piet-gpu/shader/kernel4.comp b/piet-gpu/shader/kernel4.comp index 82eb89b..8e26e1b 100644 --- a/piet-gpu/shader/kernel4.comp +++ b/piet-gpu/shader/kernel4.comp @@ -56,40 +56,6 @@ MallocResult alloc_clip_buf(uint link) { return sh_clip_alloc; } -// Calculate coverage based on backdrop + coverage of each line segment -float[CHUNK] computeArea(vec2 xy, int backdrop, uint tile_ref) { - // Probably better to store as float, but conversion is no doubt cheap. - float area[CHUNK]; - for (uint k = 0; k < CHUNK; k++) area[k] = float(backdrop); - TileSegRef tile_seg_ref = TileSegRef(tile_ref); - do { - TileSeg seg = TileSeg_read(new_alloc(tile_seg_ref.offset, TileSeg_size), tile_seg_ref); - for (uint k = 0; k < CHUNK; k++) { - vec2 my_xy = vec2(xy.x, xy.y + float(k * CHUNK_DY)); - vec2 start = seg.origin - my_xy; - vec2 end = start + seg.vector; - vec2 window = clamp(vec2(start.y, end.y), 0.0, 1.0); - if (window.x != window.y) { - vec2 t = (window - start.y) / seg.vector.y; - vec2 xs = vec2(mix(start.x, end.x, t.x), mix(start.x, end.x, t.y)); - float xmin = min(min(xs.x, xs.y), 1.0) - 1e-6; - float xmax = max(xs.x, xs.y); - float b = min(xmax, 1.0); - float c = max(b, 0.0); - float d = max(xmin, 0.0); - float a = (b + 0.5 * (d * d - c * c) - xmin) / (xmax - xmin); - area[k] += a * (window.x - window.y); - } - area[k] += sign(seg.vector.x) * clamp(my_xy.y - seg.y_edge + 1.0, 0.0, 1.0); - } - tile_seg_ref = seg.next; - } while (tile_seg_ref.offset != 0); - for (uint k = 0; k < CHUNK; k++) { - area[k] = min(abs(area[k]), 1.0); - } - return area; -} - vec3 tosRGB(vec3 rgb) { bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308)); vec3 below = vec3(12.92)*rgb; @@ -118,7 +84,7 @@ uint packsRGB(vec4 rgba) { return packUnorm4x8(rgba.wzyx); } -vec4[CHUNK] fillImage(uvec2 xy, CmdSolidImage cmd_img) { +vec4[CHUNK] fillImage(uvec2 xy, CmdImage cmd_img) { vec4 rgba[CHUNK]; for (uint i = 0; i < CHUNK; i++) { ivec2 uv = ivec2(xy.x, xy.y + i * CHUNK_DY) + cmd_img.offset; @@ -160,6 +126,7 @@ void main() { mask[i] = 1.0; } + float area[CHUNK]; while (true) { uint tag = Cmd_tag(cmd_alloc, cmd_ref).tag; if (tag == Cmd_End) { @@ -183,31 +150,67 @@ void main() { } tile_seg_ref = seg.next; } while (tile_seg_ref.offset != 0); - vec4 fg_rgba = unpacksRGB(stroke.rgba_color); for (uint k = 0; k < CHUNK; k++) { - float alpha = clamp(stroke.half_width + 0.5 - df[k], 0.0, 1.0); - rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * alpha * fg_rgba.a); + area[k] = clamp(stroke.half_width + 0.5 - df[k], 0.0, 1.0); } break; case Cmd_Fill: CmdFill fill = Cmd_Fill_read(cmd_alloc, cmd_ref); - float area[CHUNK]; - area = computeArea(xy, fill.backdrop, fill.tile_ref); - fg_rgba = unpacksRGB(fill.rgba_color); + for (uint k = 0; k < CHUNK; k++) area[k] = float(fill.backdrop); + tile_seg_ref = TileSegRef(fill.tile_ref); + // Calculate coverage based on backdrop + coverage of each line segment + do { + TileSeg seg = TileSeg_read(new_alloc(tile_seg_ref.offset, TileSeg_size), tile_seg_ref); + for (uint k = 0; k < CHUNK; k++) { + vec2 my_xy = vec2(xy.x, xy.y + float(k * CHUNK_DY)); + vec2 start = seg.origin - my_xy; + vec2 end = start + seg.vector; + vec2 window = clamp(vec2(start.y, end.y), 0.0, 1.0); + if (window.x != window.y) { + vec2 t = (window - start.y) / seg.vector.y; + vec2 xs = vec2(mix(start.x, end.x, t.x), mix(start.x, end.x, t.y)); + float xmin = min(min(xs.x, xs.y), 1.0) - 1e-6; + float xmax = max(xs.x, xs.y); + float b = min(xmax, 1.0); + float c = max(b, 0.0); + float d = max(xmin, 0.0); + float a = (b + 0.5 * (d * d - c * c) - xmin) / (xmax - xmin); + area[k] += a * (window.x - window.y); + } + area[k] += sign(seg.vector.x) * clamp(my_xy.y - seg.y_edge + 1.0, 0.0, 1.0); + } + tile_seg_ref = seg.next; + } while (tile_seg_ref.offset != 0); + for (uint k = 0; k < CHUNK; k++) { + area[k] = min(abs(area[k]), 1.0); + } + break; + case Cmd_Solid: + for (uint k = 0; k < CHUNK; k++) { + area[k] = 1.0; + } + break; + case Cmd_Alpha: + CmdAlpha alpha = Cmd_Alpha_read(cmd_alloc, cmd_ref); + for (uint k = 0; k < CHUNK; k++) { + area[k] = alpha.alpha; + } + break; + case Cmd_Color: + CmdColor color = Cmd_Color_read(cmd_alloc, cmd_ref); + vec4 fg_rgba = unpacksRGB(color.rgba_color); for (uint k = 0; k < CHUNK; k++) { rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * area[k] * fg_rgba.a); } break; - case Cmd_FillImage: - CmdFillImage fill_img = Cmd_FillImage_read(cmd_alloc, cmd_ref); - area = computeArea(xy, fill_img.backdrop, fill_img.tile_ref); - vec4 rgba[CHUNK] = fillImage(xy_uint, CmdSolidImage(fill_img.index, fill_img.offset)); + case Cmd_Image: + CmdImage fill_img = Cmd_Image_read(cmd_alloc, cmd_ref); + vec4 rgba[CHUNK] = fillImage(xy_uint, fill_img); for (uint k = 0; k < CHUNK; k++) { rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * area[k] * rgba[k].a); } break; case Cmd_BeginClip: - case Cmd_BeginSolidClip: uint blend_slot = blend_sp % BLEND_STACK_SIZE; if (blend_sp == blend_spill + BLEND_STACK_SIZE) { // spill to scratch buffer @@ -222,23 +225,12 @@ void main() { } blend_spill++; } - if (tag == Cmd_BeginClip) { - CmdBeginClip begin_clip = Cmd_BeginClip_read(cmd_alloc, cmd_ref); - area = computeArea(xy, begin_clip.backdrop, begin_clip.tile_ref); - for (uint k = 0; k < CHUNK; k++) { - blend_stack[blend_slot][k] = packsRGB(vec4(rgb[k], clamp(abs(area[k]), 0.0, 1.0))); - } - } else { - CmdBeginSolidClip begin_solid_clip = Cmd_BeginSolidClip_read(cmd_alloc, cmd_ref); - float solid_alpha = begin_solid_clip.alpha; - for (uint k = 0; k < CHUNK; k++) { - blend_stack[blend_slot][k] = packsRGB(vec4(rgb[k], solid_alpha)); - } + for (uint k = 0; k < CHUNK; k++) { + blend_stack[blend_slot][k] = packsRGB(vec4(rgb[k], clamp(abs(area[k]), 0.0, 1.0))); } blend_sp++; break; case Cmd_EndClip: - CmdEndClip end_clip = Cmd_EndClip_read(cmd_alloc, cmd_ref); blend_slot = (blend_sp - 1) % BLEND_STACK_SIZE; if (blend_sp == blend_spill) { uint base_ix = (clip_tos.offset >> 2) + gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_LocalInvocationID.y; @@ -251,21 +243,7 @@ void main() { blend_sp--; for (uint k = 0; k < CHUNK; k++) { vec4 rgba = unpacksRGB(blend_stack[blend_slot][k]); - rgb[k] = mix(rgba.rgb, rgb[k], end_clip.alpha * rgba.a); - } - break; - case Cmd_Solid: - CmdSolid solid = Cmd_Solid_read(cmd_alloc, cmd_ref); - fg_rgba = unpacksRGB(solid.rgba_color); - for (uint k = 0; k < CHUNK; k++) { - rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * fg_rgba.a); - } - break; - case Cmd_SolidImage: - CmdSolidImage solid_img = Cmd_SolidImage_read(cmd_alloc, cmd_ref); - rgba = fillImage(xy_uint, solid_img); - for (uint k = 0; k < CHUNK; k++) { - rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * rgba[k].a); + rgb[k] = mix(rgba.rgb, rgb[k], area[k] * rgba.a); } break; case Cmd_Jump: diff --git a/piet-gpu/shader/kernel4.spv b/piet-gpu/shader/kernel4.spv index ebd4811..91e54dd 100644 Binary files a/piet-gpu/shader/kernel4.spv and b/piet-gpu/shader/kernel4.spv differ diff --git a/piet-gpu/shader/ptcl.h b/piet-gpu/shader/ptcl.h index 0480ad9..6267fc5 100644 --- a/piet-gpu/shader/ptcl.h +++ b/piet-gpu/shader/ptcl.h @@ -10,27 +10,15 @@ struct CmdFillRef { uint offset; }; -struct CmdFillImageRef { +struct CmdColorRef { uint offset; }; -struct CmdBeginClipRef { +struct CmdImageRef { uint offset; }; -struct CmdBeginSolidClipRef { - uint offset; -}; - -struct CmdEndClipRef { - uint offset; -}; - -struct CmdSolidRef { - uint offset; -}; - -struct CmdSolidImageRef { +struct CmdAlphaRef { uint offset; }; @@ -45,10 +33,9 @@ struct CmdRef { struct CmdStroke { uint tile_ref; float half_width; - uint rgba_color; }; -#define CmdStroke_size 12 +#define CmdStroke_size 8 CmdStrokeRef CmdStroke_index(CmdStrokeRef ref, uint index) { return CmdStrokeRef(ref.offset + index * CmdStroke_size); @@ -57,78 +44,43 @@ CmdStrokeRef CmdStroke_index(CmdStrokeRef ref, uint index) { struct CmdFill { uint tile_ref; int backdrop; - uint rgba_color; }; -#define CmdFill_size 12 +#define CmdFill_size 8 CmdFillRef CmdFill_index(CmdFillRef ref, uint index) { return CmdFillRef(ref.offset + index * CmdFill_size); } -struct CmdFillImage { - uint tile_ref; - int backdrop; - uint index; - ivec2 offset; -}; - -#define CmdFillImage_size 16 - -CmdFillImageRef CmdFillImage_index(CmdFillImageRef ref, uint index) { - return CmdFillImageRef(ref.offset + index * CmdFillImage_size); -} - -struct CmdBeginClip { - uint tile_ref; - int backdrop; -}; - -#define CmdBeginClip_size 8 - -CmdBeginClipRef CmdBeginClip_index(CmdBeginClipRef ref, uint index) { - return CmdBeginClipRef(ref.offset + index * CmdBeginClip_size); -} - -struct CmdBeginSolidClip { - float alpha; -}; - -#define CmdBeginSolidClip_size 4 - -CmdBeginSolidClipRef CmdBeginSolidClip_index(CmdBeginSolidClipRef ref, uint index) { - return CmdBeginSolidClipRef(ref.offset + index * CmdBeginSolidClip_size); -} - -struct CmdEndClip { - float alpha; -}; - -#define CmdEndClip_size 4 - -CmdEndClipRef CmdEndClip_index(CmdEndClipRef ref, uint index) { - return CmdEndClipRef(ref.offset + index * CmdEndClip_size); -} - -struct CmdSolid { +struct CmdColor { uint rgba_color; }; -#define CmdSolid_size 4 +#define CmdColor_size 4 -CmdSolidRef CmdSolid_index(CmdSolidRef ref, uint index) { - return CmdSolidRef(ref.offset + index * CmdSolid_size); +CmdColorRef CmdColor_index(CmdColorRef ref, uint index) { + return CmdColorRef(ref.offset + index * CmdColor_size); } -struct CmdSolidImage { +struct CmdImage { uint index; ivec2 offset; }; -#define CmdSolidImage_size 8 +#define CmdImage_size 8 -CmdSolidImageRef CmdSolidImage_index(CmdSolidImageRef ref, uint index) { - return CmdSolidImageRef(ref.offset + index * CmdSolidImage_size); +CmdImageRef CmdImage_index(CmdImageRef ref, uint index) { + return CmdImageRef(ref.offset + index * CmdImage_size); +} + +struct CmdAlpha { + float alpha; +}; + +#define CmdAlpha_size 4 + +CmdAlphaRef CmdAlpha_index(CmdAlphaRef ref, uint index) { + return CmdAlphaRef(ref.offset + index * CmdAlpha_size); } struct CmdJump { @@ -143,15 +95,15 @@ CmdJumpRef CmdJump_index(CmdJumpRef ref, uint index) { #define Cmd_End 0 #define Cmd_Fill 1 -#define Cmd_FillImage 2 -#define Cmd_BeginClip 3 -#define Cmd_BeginSolidClip 4 -#define Cmd_EndClip 5 -#define Cmd_Stroke 6 -#define Cmd_Solid 7 -#define Cmd_SolidImage 8 +#define Cmd_Stroke 2 +#define Cmd_Solid 3 +#define Cmd_Alpha 4 +#define Cmd_Color 5 +#define Cmd_Image 6 +#define Cmd_BeginClip 7 +#define Cmd_EndClip 8 #define Cmd_Jump 9 -#define Cmd_size 20 +#define Cmd_size 12 CmdRef Cmd_index(CmdRef ref, uint index) { return CmdRef(ref.offset + index * Cmd_size); @@ -166,11 +118,9 @@ CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef 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); CmdStroke s; s.tile_ref = raw0; s.half_width = uintBitsToFloat(raw1); - s.rgba_color = raw2; return s; } @@ -178,18 +128,15 @@ void CmdStroke_write(Alloc a, CmdStrokeRef ref, CmdStroke s) { uint ix = ref.offset >> 2; write_mem(a, ix + 0, s.tile_ref); write_mem(a, ix + 1, floatBitsToUint(s.half_width)); - write_mem(a, ix + 2, s.rgba_color); } CmdFill CmdFill_read(Alloc a, CmdFillRef 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); CmdFill s; s.tile_ref = raw0; s.backdrop = int(raw1); - s.rgba_color = raw2; return s; } @@ -197,102 +144,50 @@ void CmdFill_write(Alloc a, CmdFillRef ref, CmdFill s) { uint ix = ref.offset >> 2; write_mem(a, ix + 0, s.tile_ref); write_mem(a, ix + 1, uint(s.backdrop)); - write_mem(a, ix + 2, s.rgba_color); } -CmdFillImage CmdFillImage_read(Alloc a, CmdFillImageRef ref) { +CmdColor CmdColor_read(Alloc a, CmdColorRef 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); - CmdFillImage s; - s.tile_ref = raw0; - s.backdrop = int(raw1); - s.index = raw2; - s.offset = ivec2(int(raw3 << 16) >> 16, int(raw3) >> 16); - return s; -} - -void CmdFillImage_write(Alloc a, CmdFillImageRef ref, CmdFillImage s) { - uint ix = ref.offset >> 2; - write_mem(a, ix + 0, s.tile_ref); - write_mem(a, ix + 1, uint(s.backdrop)); - write_mem(a, ix + 2, s.index); - write_mem(a, ix + 3, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16)); -} - -CmdBeginClip CmdBeginClip_read(Alloc a, CmdBeginClipRef ref) { - uint ix = ref.offset >> 2; - uint raw0 = read_mem(a, ix + 0); - uint raw1 = read_mem(a, ix + 1); - CmdBeginClip s; - s.tile_ref = raw0; - s.backdrop = int(raw1); - return s; -} - -void CmdBeginClip_write(Alloc a, CmdBeginClipRef ref, CmdBeginClip s) { - uint ix = ref.offset >> 2; - write_mem(a, ix + 0, s.tile_ref); - write_mem(a, ix + 1, uint(s.backdrop)); -} - -CmdBeginSolidClip CmdBeginSolidClip_read(Alloc a, CmdBeginSolidClipRef ref) { - uint ix = ref.offset >> 2; - uint raw0 = read_mem(a, ix + 0); - CmdBeginSolidClip s; - s.alpha = uintBitsToFloat(raw0); - return s; -} - -void CmdBeginSolidClip_write(Alloc a, CmdBeginSolidClipRef ref, CmdBeginSolidClip s) { - uint ix = ref.offset >> 2; - write_mem(a, ix + 0, floatBitsToUint(s.alpha)); -} - -CmdEndClip CmdEndClip_read(Alloc a, CmdEndClipRef ref) { - uint ix = ref.offset >> 2; - uint raw0 = read_mem(a, ix + 0); - CmdEndClip s; - s.alpha = uintBitsToFloat(raw0); - return s; -} - -void CmdEndClip_write(Alloc a, CmdEndClipRef ref, CmdEndClip s) { - uint ix = ref.offset >> 2; - write_mem(a, ix + 0, floatBitsToUint(s.alpha)); -} - -CmdSolid CmdSolid_read(Alloc a, CmdSolidRef ref) { - uint ix = ref.offset >> 2; - uint raw0 = read_mem(a, ix + 0); - CmdSolid s; + CmdColor s; s.rgba_color = raw0; return s; } -void CmdSolid_write(Alloc a, CmdSolidRef ref, CmdSolid s) { +void CmdColor_write(Alloc a, CmdColorRef ref, CmdColor s) { uint ix = ref.offset >> 2; write_mem(a, ix + 0, s.rgba_color); } -CmdSolidImage CmdSolidImage_read(Alloc a, CmdSolidImageRef ref) { +CmdImage CmdImage_read(Alloc a, CmdImageRef ref) { uint ix = ref.offset >> 2; uint raw0 = read_mem(a, ix + 0); uint raw1 = read_mem(a, ix + 1); - CmdSolidImage s; + CmdImage s; s.index = raw0; s.offset = ivec2(int(raw1 << 16) >> 16, int(raw1) >> 16); return s; } -void CmdSolidImage_write(Alloc a, CmdSolidImageRef ref, CmdSolidImage s) { +void CmdImage_write(Alloc a, CmdImageRef ref, CmdImage s) { uint ix = ref.offset >> 2; write_mem(a, ix + 0, s.index); write_mem(a, ix + 1, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16)); } +CmdAlpha CmdAlpha_read(Alloc a, CmdAlphaRef ref) { + uint ix = ref.offset >> 2; + uint raw0 = read_mem(a, ix + 0); + CmdAlpha s; + s.alpha = uintBitsToFloat(raw0); + return s; +} + +void CmdAlpha_write(Alloc a, CmdAlphaRef ref, CmdAlpha s) { + uint ix = ref.offset >> 2; + write_mem(a, ix + 0, floatBitsToUint(s.alpha)); +} + CmdJump CmdJump_read(Alloc a, CmdJumpRef ref) { uint ix = ref.offset >> 2; uint raw0 = read_mem(a, ix + 0); @@ -315,32 +210,20 @@ CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) { return CmdFill_read(a, CmdFillRef(ref.offset + 4)); } -CmdFillImage Cmd_FillImage_read(Alloc a, CmdRef ref) { - return CmdFillImage_read(a, CmdFillImageRef(ref.offset + 4)); -} - -CmdBeginClip Cmd_BeginClip_read(Alloc a, CmdRef ref) { - return CmdBeginClip_read(a, CmdBeginClipRef(ref.offset + 4)); -} - -CmdBeginSolidClip Cmd_BeginSolidClip_read(Alloc a, CmdRef ref) { - return CmdBeginSolidClip_read(a, CmdBeginSolidClipRef(ref.offset + 4)); -} - -CmdEndClip Cmd_EndClip_read(Alloc a, CmdRef ref) { - return CmdEndClip_read(a, CmdEndClipRef(ref.offset + 4)); -} - CmdStroke Cmd_Stroke_read(Alloc a, CmdRef ref) { return CmdStroke_read(a, CmdStrokeRef(ref.offset + 4)); } -CmdSolid Cmd_Solid_read(Alloc a, CmdRef ref) { - return CmdSolid_read(a, CmdSolidRef(ref.offset + 4)); +CmdAlpha Cmd_Alpha_read(Alloc a, CmdRef ref) { + return CmdAlpha_read(a, CmdAlphaRef(ref.offset + 4)); } -CmdSolidImage Cmd_SolidImage_read(Alloc a, CmdRef ref) { - return CmdSolidImage_read(a, CmdSolidImageRef(ref.offset + 4)); +CmdColor Cmd_Color_read(Alloc a, CmdRef ref) { + return CmdColor_read(a, CmdColorRef(ref.offset + 4)); +} + +CmdImage Cmd_Image_read(Alloc a, CmdRef ref) { + return CmdImage_read(a, CmdImageRef(ref.offset + 4)); } CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) { @@ -356,39 +239,36 @@ void Cmd_Fill_write(Alloc a, CmdRef ref, CmdFill s) { CmdFill_write(a, CmdFillRef(ref.offset + 4), s); } -void Cmd_FillImage_write(Alloc a, CmdRef ref, CmdFillImage s) { - write_mem(a, ref.offset >> 2, Cmd_FillImage); - CmdFillImage_write(a, CmdFillImageRef(ref.offset + 4), s); -} - -void Cmd_BeginClip_write(Alloc a, CmdRef ref, CmdBeginClip s) { - write_mem(a, ref.offset >> 2, Cmd_BeginClip); - CmdBeginClip_write(a, CmdBeginClipRef(ref.offset + 4), s); -} - -void Cmd_BeginSolidClip_write(Alloc a, CmdRef ref, CmdBeginSolidClip s) { - write_mem(a, ref.offset >> 2, Cmd_BeginSolidClip); - CmdBeginSolidClip_write(a, CmdBeginSolidClipRef(ref.offset + 4), s); -} - -void Cmd_EndClip_write(Alloc a, CmdRef ref, CmdEndClip s) { - write_mem(a, ref.offset >> 2, Cmd_EndClip); - CmdEndClip_write(a, CmdEndClipRef(ref.offset + 4), s); -} - void Cmd_Stroke_write(Alloc a, CmdRef ref, CmdStroke s) { write_mem(a, ref.offset >> 2, Cmd_Stroke); CmdStroke_write(a, CmdStrokeRef(ref.offset + 4), s); } -void Cmd_Solid_write(Alloc a, CmdRef ref, CmdSolid s) { +void Cmd_Solid_write(Alloc a, CmdRef ref) { write_mem(a, ref.offset >> 2, Cmd_Solid); - CmdSolid_write(a, CmdSolidRef(ref.offset + 4), s); } -void Cmd_SolidImage_write(Alloc a, CmdRef ref, CmdSolidImage s) { - write_mem(a, ref.offset >> 2, Cmd_SolidImage); - CmdSolidImage_write(a, CmdSolidImageRef(ref.offset + 4), s); +void Cmd_Alpha_write(Alloc a, CmdRef ref, CmdAlpha s) { + write_mem(a, ref.offset >> 2, Cmd_Alpha); + CmdAlpha_write(a, CmdAlphaRef(ref.offset + 4), s); +} + +void Cmd_Color_write(Alloc a, CmdRef ref, CmdColor s) { + write_mem(a, ref.offset >> 2, Cmd_Color); + CmdColor_write(a, CmdColorRef(ref.offset + 4), s); +} + +void Cmd_Image_write(Alloc a, CmdRef ref, CmdImage s) { + write_mem(a, ref.offset >> 2, Cmd_Image); + CmdImage_write(a, CmdImageRef(ref.offset + 4), s); +} + +void Cmd_BeginClip_write(Alloc a, CmdRef ref) { + write_mem(a, ref.offset >> 2, Cmd_BeginClip); +} + +void Cmd_EndClip_write(Alloc a, CmdRef ref) { + write_mem(a, ref.offset >> 2, Cmd_EndClip); } void Cmd_Jump_write(Alloc a, CmdRef ref, CmdJump s) {