mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 02:15:34 +00:00
gpu,op/clip: [compute] get rid of stroke vs fill flags
The fill mode is now controlled by a SetFillMode command, not by flags on each path segment and fill command. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+21
-22
@@ -176,7 +176,7 @@ const (
|
|||||||
pathSize = 12
|
pathSize = 12
|
||||||
binSize = 8
|
binSize = 8
|
||||||
pathsegSize = 52
|
pathsegSize = 52
|
||||||
annoSize = 28
|
annoSize = 32
|
||||||
transSize = 24
|
transSize = 24
|
||||||
stateSize = 60
|
stateSize = 60
|
||||||
stateStride = 4 + 2*stateSize
|
stateStride = 4 + 2*stateSize
|
||||||
@@ -346,8 +346,8 @@ func (g *compute) encode(viewport image.Point) error {
|
|||||||
g.enc.transform(flipY)
|
g.enc.transform(flipY)
|
||||||
if g.drawOps.clear {
|
if g.drawOps.clear {
|
||||||
g.drawOps.clear = false
|
g.drawOps.clear = false
|
||||||
g.enc.rect(f32.Rectangle{Max: layout.FPt(viewport)}, false)
|
g.enc.rect(f32.Rectangle{Max: layout.FPt(viewport)})
|
||||||
g.enc.fill(f32color.NRGBAToRGBA(g.drawOps.clearColor.SRGB()))
|
g.enc.fillColor(f32color.NRGBAToRGBA(g.drawOps.clearColor.SRGB()))
|
||||||
}
|
}
|
||||||
return g.encodeOps(flipY, viewport, g.drawOps.allImageOps)
|
return g.encodeOps(flipY, viewport, g.drawOps.allImageOps)
|
||||||
}
|
}
|
||||||
@@ -639,10 +639,10 @@ func (g *compute) encodeOps(trans f32.Affine2D, viewport image.Point, ops []imag
|
|||||||
// Add fill command, its offset is resolved and filled in renderMaterials.
|
// Add fill command, its offset is resolved and filled in renderMaterials.
|
||||||
g.enc.fillImage(0)
|
g.enc.fillImage(0)
|
||||||
case materialColor:
|
case materialColor:
|
||||||
g.enc.fill(f32color.NRGBAToRGBA(op.material.color.SRGB()))
|
g.enc.fillColor(f32color.NRGBAToRGBA(op.material.color.SRGB()))
|
||||||
case materialLinearGradient:
|
case materialLinearGradient:
|
||||||
// TODO: implement.
|
// TODO: implement.
|
||||||
g.enc.fill(f32color.NRGBAToRGBA(op.material.color1.SRGB()))
|
g.enc.fillColor(f32color.NRGBAToRGBA(op.material.color1.SRGB()))
|
||||||
default:
|
default:
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
@@ -668,7 +668,7 @@ func (g *compute) encodeClipStack(clip, bounds f32.Rectangle, p *pathOp) int {
|
|||||||
g.enc.append(pathData.computePath)
|
g.enc.append(pathData.computePath)
|
||||||
g.enc.transform(p.trans.Invert())
|
g.enc.transform(p.trans.Invert())
|
||||||
} else {
|
} else {
|
||||||
g.enc.rect(bounds, false)
|
g.enc.rect(bounds)
|
||||||
}
|
}
|
||||||
return nclips
|
return nclips
|
||||||
}
|
}
|
||||||
@@ -680,7 +680,7 @@ func encodePath(pathData []byte, stroke clip.StrokeStyle, dashes dashOp) encoder
|
|||||||
quads = quads.stroke(stroke, dashes)
|
quads = quads.stroke(stroke, dashes)
|
||||||
for _, quad := range quads {
|
for _, quad := range quads {
|
||||||
q := quad.quad
|
q := quad.quad
|
||||||
enc.quad(q.From, q.Ctrl, q.To, false)
|
enc.quad(q.From, q.Ctrl, q.To)
|
||||||
}
|
}
|
||||||
return enc
|
return enc
|
||||||
}
|
}
|
||||||
@@ -999,12 +999,11 @@ func (e *encoder) transform(m f32.Affine2D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) lineWidth(width float32) {
|
func (e *encoder) lineWidth(width float32) {
|
||||||
e.scene = append(e.scene, scene.LineWidth(width))
|
e.scene = append(e.scene, scene.SetLineWidth(width))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) stroke(col color.RGBA) {
|
func (e *encoder) fillMode(mode scene.FillMode) {
|
||||||
e.scene = append(e.scene, scene.Stroke(col))
|
e.scene = append(e.scene, scene.SetFillMode(mode))
|
||||||
e.npath++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) beginClip(bbox f32.Rectangle) {
|
func (e *encoder) beginClip(bbox f32.Rectangle) {
|
||||||
@@ -1017,17 +1016,17 @@ func (e *encoder) endClip(bbox f32.Rectangle) {
|
|||||||
e.npath++
|
e.npath++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) rect(r f32.Rectangle, stroke bool) {
|
func (e *encoder) rect(r f32.Rectangle) {
|
||||||
// Rectangle corners, clock-wise.
|
// Rectangle corners, clock-wise.
|
||||||
c0, c1, c2, c3 := r.Min, f32.Pt(r.Min.X, r.Max.Y), r.Max, f32.Pt(r.Max.X, r.Min.Y)
|
c0, c1, c2, c3 := r.Min, f32.Pt(r.Min.X, r.Max.Y), r.Max, f32.Pt(r.Max.X, r.Min.Y)
|
||||||
e.line(c0, c1, stroke)
|
e.line(c0, c1)
|
||||||
e.line(c1, c2, stroke)
|
e.line(c1, c2)
|
||||||
e.line(c2, c3, stroke)
|
e.line(c2, c3)
|
||||||
e.line(c3, c0, stroke)
|
e.line(c3, c0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) fill(col color.RGBA) {
|
func (e *encoder) fillColor(col color.RGBA) {
|
||||||
e.scene = append(e.scene, scene.Fill(col))
|
e.scene = append(e.scene, scene.FillColor(col))
|
||||||
e.npath++
|
e.npath++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1042,12 +1041,12 @@ func (e *encoder) fillImage(index int) {
|
|||||||
e.npath++
|
e.npath++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) line(start, end f32.Point, stroke bool) {
|
func (e *encoder) line(start, end f32.Point) {
|
||||||
e.scene = append(e.scene, scene.Line(start, end, stroke))
|
e.scene = append(e.scene, scene.Line(start, end))
|
||||||
e.npathseg++
|
e.npathseg++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) quad(start, ctrl, end f32.Point, stroke bool) {
|
func (e *encoder) quad(start, ctrl, end f32.Point) {
|
||||||
e.scene = append(e.scene, scene.Quad(start, ctrl, end, stroke))
|
e.scene = append(e.scene, scene.Quad(start, ctrl, end))
|
||||||
e.npathseg++
|
e.npathseg++
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1393,18 +1393,18 @@ func decodeToOutlineQuads(qs *quadSplitter, tr f32.Affine2D, pathData []byte) {
|
|||||||
qs.contour = bo.Uint32(pathData)
|
qs.contour = bo.Uint32(pathData)
|
||||||
cmd := ops.DecodeCommand(pathData[4:])
|
cmd := ops.DecodeCommand(pathData[4:])
|
||||||
switch cmd.Op() {
|
switch cmd.Op() {
|
||||||
case scene.OpFillLine:
|
case scene.OpLine:
|
||||||
var q quadSegment
|
var q quadSegment
|
||||||
q.From, q.To = scene.DecodeLine(cmd)
|
q.From, q.To = scene.DecodeLine(cmd)
|
||||||
q.Ctrl = q.From.Add(q.To).Mul(.5)
|
q.Ctrl = q.From.Add(q.To).Mul(.5)
|
||||||
q = q.Transform(tr)
|
q = q.Transform(tr)
|
||||||
qs.splitAndEncode(q)
|
qs.splitAndEncode(q)
|
||||||
case scene.OpFillQuad:
|
case scene.OpQuad:
|
||||||
var q quadSegment
|
var q quadSegment
|
||||||
q.From, q.Ctrl, q.To = scene.DecodeQuad(cmd)
|
q.From, q.Ctrl, q.To = scene.DecodeQuad(cmd)
|
||||||
q = q.Transform(tr)
|
q = q.Transform(tr)
|
||||||
qs.splitAndEncode(q)
|
qs.splitAndEncode(q)
|
||||||
case scene.OpFillCubic:
|
case scene.OpCubic:
|
||||||
for _, q := range splitCubic(scene.DecodeCubic(cmd)) {
|
for _, q := range splitCubic(scene.DecodeCubic(cmd)) {
|
||||||
q = q.Transform(tr)
|
q = q.Transform(tr)
|
||||||
qs.splitAndEncode(q)
|
qs.splitAndEncode(q)
|
||||||
@@ -1424,7 +1424,7 @@ func decodeToStrokeQuads(pathData []byte) strokeQuads {
|
|||||||
contour := bo.Uint32(pathData)
|
contour := bo.Uint32(pathData)
|
||||||
cmd := ops.DecodeCommand(pathData[4:])
|
cmd := ops.DecodeCommand(pathData[4:])
|
||||||
switch cmd.Op() {
|
switch cmd.Op() {
|
||||||
case scene.OpFillLine:
|
case scene.OpLine:
|
||||||
var q quadSegment
|
var q quadSegment
|
||||||
q.From, q.To = scene.DecodeLine(cmd)
|
q.From, q.To = scene.DecodeLine(cmd)
|
||||||
q.Ctrl = q.From.Add(q.To).Mul(.5)
|
q.Ctrl = q.From.Add(q.To).Mul(.5)
|
||||||
@@ -1433,7 +1433,7 @@ func decodeToStrokeQuads(pathData []byte) strokeQuads {
|
|||||||
quad: q,
|
quad: q,
|
||||||
}
|
}
|
||||||
quads = append(quads, quad)
|
quads = append(quads, quad)
|
||||||
case scene.OpFillQuad:
|
case scene.OpQuad:
|
||||||
var q quadSegment
|
var q quadSegment
|
||||||
q.From, q.Ctrl, q.To = scene.DecodeQuad(cmd)
|
q.From, q.Ctrl, q.To = scene.DecodeQuad(cmd)
|
||||||
quad := strokeQuad{
|
quad := strokeQuad{
|
||||||
@@ -1441,7 +1441,7 @@ func decodeToStrokeQuads(pathData []byte) strokeQuads {
|
|||||||
quad: q,
|
quad: q,
|
||||||
}
|
}
|
||||||
quads = append(quads, quad)
|
quads = append(quads, quad)
|
||||||
case scene.OpFillCubic:
|
case scene.OpCubic:
|
||||||
for _, q := range splitCubic(scene.DecodeCubic(cmd)) {
|
for _, q := range splitCubic(scene.DecodeCubic(cmd)) {
|
||||||
quad := strokeQuad{
|
quad := strokeQuad{
|
||||||
contour: contour,
|
contour: contour,
|
||||||
@@ -1506,16 +1506,16 @@ func (d *drawOps) boundsForTransformedRect(r f32.Rectangle, tr f32.Affine2D) (au
|
|||||||
buf := aux
|
buf := aux
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(buf, 0) // Contour
|
bo.PutUint32(buf, 0) // Contour
|
||||||
ops.EncodeCommand(buf[4:], scene.Line(r.Min, f32.Pt(r.Max.X, r.Min.Y), false))
|
ops.EncodeCommand(buf[4:], scene.Line(r.Min, f32.Pt(r.Max.X, r.Min.Y)))
|
||||||
buf = buf[4+scene.CommandSize:]
|
buf = buf[4+scene.CommandSize:]
|
||||||
bo.PutUint32(buf, 0)
|
bo.PutUint32(buf, 0)
|
||||||
ops.EncodeCommand(buf[4:], scene.Line(f32.Pt(r.Max.X, r.Min.Y), r.Max, false))
|
ops.EncodeCommand(buf[4:], scene.Line(f32.Pt(r.Max.X, r.Min.Y), r.Max))
|
||||||
buf = buf[4+scene.CommandSize:]
|
buf = buf[4+scene.CommandSize:]
|
||||||
bo.PutUint32(buf, 0)
|
bo.PutUint32(buf, 0)
|
||||||
ops.EncodeCommand(buf[4:], scene.Line(r.Max, f32.Pt(r.Min.X, r.Max.Y), false))
|
ops.EncodeCommand(buf[4:], scene.Line(r.Max, f32.Pt(r.Min.X, r.Max.Y)))
|
||||||
buf = buf[4+scene.CommandSize:]
|
buf = buf[4+scene.CommandSize:]
|
||||||
bo.PutUint32(buf, 0)
|
bo.PutUint32(buf, 0)
|
||||||
ops.EncodeCommand(buf[4:], scene.Line(f32.Pt(r.Min.X, r.Max.Y), r.Min, false))
|
ops.EncodeCommand(buf[4:], scene.Line(f32.Pt(r.Min.X, r.Max.Y), r.Min))
|
||||||
}
|
}
|
||||||
|
|
||||||
// establish the transform mapping from bounds rectangle to transformed corners
|
// establish the transform mapping from bounds rectangle to transformed corners
|
||||||
|
|||||||
+7
-7
File diff suppressed because one or more lines are too long
+101
-101
@@ -2,19 +2,19 @@
|
|||||||
|
|
||||||
// Code auto-generated by piet-gpu-derive
|
// Code auto-generated by piet-gpu-derive
|
||||||
|
|
||||||
struct AnnoFillRef {
|
struct AnnoImageRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnnoFillImageRef {
|
struct AnnoColorRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnnoStrokeRef {
|
struct AnnoBeginClipRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnnoClipRef {
|
struct AnnoEndClipRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,86 +22,69 @@ struct AnnotatedRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnnoFill {
|
struct AnnoImage {
|
||||||
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;
|
vec4 bbox;
|
||||||
|
float linewidth;
|
||||||
uint index;
|
uint index;
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AnnoFillImage_size 24
|
#define AnnoImage_size 28
|
||||||
|
|
||||||
AnnoFillImageRef AnnoFillImage_index(AnnoFillImageRef ref, uint index) {
|
AnnoImageRef AnnoImage_index(AnnoImageRef ref, uint index) {
|
||||||
return AnnoFillImageRef(ref.offset + index * AnnoFillImage_size);
|
return AnnoImageRef(ref.offset + index * AnnoImage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnnoStroke {
|
struct AnnoColor {
|
||||||
vec4 bbox;
|
vec4 bbox;
|
||||||
|
float linewidth;
|
||||||
uint rgba_color;
|
uint rgba_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AnnoColor_size 24
|
||||||
|
|
||||||
|
AnnoColorRef AnnoColor_index(AnnoColorRef ref, uint index) {
|
||||||
|
return AnnoColorRef(ref.offset + index * AnnoColor_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AnnoBeginClip {
|
||||||
|
vec4 bbox;
|
||||||
float linewidth;
|
float linewidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AnnoStroke_size 24
|
#define AnnoBeginClip_size 20
|
||||||
|
|
||||||
AnnoStrokeRef AnnoStroke_index(AnnoStrokeRef ref, uint index) {
|
AnnoBeginClipRef AnnoBeginClip_index(AnnoBeginClipRef ref, uint index) {
|
||||||
return AnnoStrokeRef(ref.offset + index * AnnoStroke_size);
|
return AnnoBeginClipRef(ref.offset + index * AnnoBeginClip_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnnoClip {
|
struct AnnoEndClip {
|
||||||
vec4 bbox;
|
vec4 bbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AnnoClip_size 16
|
#define AnnoEndClip_size 16
|
||||||
|
|
||||||
AnnoClipRef AnnoClip_index(AnnoClipRef ref, uint index) {
|
AnnoEndClipRef AnnoEndClip_index(AnnoEndClipRef ref, uint index) {
|
||||||
return AnnoClipRef(ref.offset + index * AnnoClip_size);
|
return AnnoEndClipRef(ref.offset + index * AnnoEndClip_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Annotated_Nop 0
|
#define Annotated_Nop 0
|
||||||
#define Annotated_Stroke 1
|
#define Annotated_Color 1
|
||||||
#define Annotated_Fill 2
|
#define Annotated_Image 2
|
||||||
#define Annotated_FillImage 3
|
#define Annotated_BeginClip 3
|
||||||
#define Annotated_BeginClip 4
|
#define Annotated_EndClip 4
|
||||||
#define Annotated_EndClip 5
|
#define Annotated_size 32
|
||||||
#define Annotated_size 28
|
|
||||||
|
|
||||||
AnnotatedRef Annotated_index(AnnotatedRef ref, uint index) {
|
AnnotatedRef Annotated_index(AnnotatedRef ref, uint index) {
|
||||||
return AnnotatedRef(ref.offset + index * Annotated_size);
|
return AnnotatedRef(ref.offset + index * Annotated_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoFill AnnoFill_read(Alloc a, AnnoFillRef ref) {
|
struct AnnotatedTag {
|
||||||
uint ix = ref.offset >> 2;
|
uint tag;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint flags;
|
||||||
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) {
|
AnnoImage AnnoImage_read(Alloc a, AnnoImageRef ref) {
|
||||||
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 ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
@@ -109,24 +92,27 @@ AnnoFillImage AnnoFillImage_read(Alloc a, AnnoFillImageRef ref) {
|
|||||||
uint raw3 = read_mem(a, ix + 3);
|
uint raw3 = read_mem(a, ix + 3);
|
||||||
uint raw4 = read_mem(a, ix + 4);
|
uint raw4 = read_mem(a, ix + 4);
|
||||||
uint raw5 = read_mem(a, ix + 5);
|
uint raw5 = read_mem(a, ix + 5);
|
||||||
AnnoFillImage s;
|
uint raw6 = read_mem(a, ix + 6);
|
||||||
|
AnnoImage s;
|
||||||
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
s.index = raw4;
|
s.linewidth = uintBitsToFloat(raw4);
|
||||||
s.offset = ivec2(int(raw5 << 16) >> 16, int(raw5) >> 16);
|
s.index = raw5;
|
||||||
|
s.offset = ivec2(int(raw6 << 16) >> 16, int(raw6) >> 16);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnoFillImage_write(Alloc a, AnnoFillImageRef ref, AnnoFillImage s) {
|
void AnnoImage_write(Alloc a, AnnoImageRef ref, AnnoImage s) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
||||||
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
||||||
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||||
write_mem(a, ix + 4, s.index);
|
write_mem(a, ix + 4, floatBitsToUint(s.linewidth));
|
||||||
write_mem(a, ix + 5, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16));
|
write_mem(a, ix + 5, s.index);
|
||||||
|
write_mem(a, ix + 6, (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 ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
@@ -134,35 +120,57 @@ AnnoStroke AnnoStroke_read(Alloc a, AnnoStrokeRef ref) {
|
|||||||
uint raw3 = read_mem(a, ix + 3);
|
uint raw3 = read_mem(a, ix + 3);
|
||||||
uint raw4 = read_mem(a, ix + 4);
|
uint raw4 = read_mem(a, ix + 4);
|
||||||
uint raw5 = read_mem(a, ix + 5);
|
uint raw5 = read_mem(a, ix + 5);
|
||||||
AnnoStroke s;
|
AnnoColor s;
|
||||||
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
s.rgba_color = raw4;
|
s.linewidth = uintBitsToFloat(raw4);
|
||||||
s.linewidth = uintBitsToFloat(raw5);
|
s.rgba_color = raw5;
|
||||||
return s;
|
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;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
||||||
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
write_mem(a, ix + 2, floatBitsToUint(s.bbox.z));
|
||||||
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||||
write_mem(a, ix + 4, s.rgba_color);
|
write_mem(a, ix + 4, floatBitsToUint(s.linewidth));
|
||||||
write_mem(a, ix + 5, floatBitsToUint(s.linewidth));
|
write_mem(a, ix + 5, s.rgba_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoClip AnnoClip_read(Alloc a, AnnoClipRef ref) {
|
AnnoBeginClip AnnoBeginClip_read(Alloc a, AnnoBeginClipRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
uint raw2 = read_mem(a, ix + 2);
|
uint raw2 = read_mem(a, ix + 2);
|
||||||
uint raw3 = read_mem(a, ix + 3);
|
uint raw3 = read_mem(a, ix + 3);
|
||||||
AnnoClip s;
|
uint raw4 = read_mem(a, ix + 4);
|
||||||
|
AnnoBeginClip s;
|
||||||
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
|
s.linewidth = uintBitsToFloat(raw4);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnnoBeginClip_write(Alloc a, AnnoBeginClipRef ref, AnnoBeginClip 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, floatBitsToUint(s.linewidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
AnnoEndClip AnnoEndClip_read(Alloc a, AnnoEndClipRef 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);
|
||||||
|
AnnoEndClip s;
|
||||||
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
s.bbox = vec4(uintBitsToFloat(raw0), uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnoClip_write(Alloc a, AnnoClipRef ref, AnnoClip s) {
|
void AnnoEndClip_write(Alloc a, AnnoEndClipRef ref, AnnoEndClip s) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
write_mem(a, ix + 0, floatBitsToUint(s.bbox.x));
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
write_mem(a, ix + 1, floatBitsToUint(s.bbox.y));
|
||||||
@@ -170,56 +178,48 @@ void AnnoClip_write(Alloc a, AnnoClipRef ref, AnnoClip s) {
|
|||||||
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Annotated_tag(Alloc a, AnnotatedRef ref) {
|
AnnotatedTag Annotated_tag(Alloc a, AnnotatedRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||||
|
return AnnotatedTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoStroke Annotated_Stroke_read(Alloc a, AnnotatedRef ref) {
|
AnnoColor Annotated_Color_read(Alloc a, AnnotatedRef ref) {
|
||||||
return AnnoStroke_read(a, AnnoStrokeRef(ref.offset + 4));
|
return AnnoColor_read(a, AnnoColorRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoFill Annotated_Fill_read(Alloc a, AnnotatedRef ref) {
|
AnnoImage Annotated_Image_read(Alloc a, AnnotatedRef ref) {
|
||||||
return AnnoFill_read(a, AnnoFillRef(ref.offset + 4));
|
return AnnoImage_read(a, AnnoImageRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoFillImage Annotated_FillImage_read(Alloc a, AnnotatedRef ref) {
|
AnnoBeginClip Annotated_BeginClip_read(Alloc a, AnnotatedRef ref) {
|
||||||
return AnnoFillImage_read(a, AnnoFillImageRef(ref.offset + 4));
|
return AnnoBeginClip_read(a, AnnoBeginClipRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnoClip Annotated_BeginClip_read(Alloc a, AnnotatedRef ref) {
|
AnnoEndClip Annotated_EndClip_read(Alloc a, AnnotatedRef ref) {
|
||||||
return AnnoClip_read(a, AnnoClipRef(ref.offset + 4));
|
return AnnoEndClip_read(a, AnnoEndClipRef(ref.offset + 4));
|
||||||
}
|
|
||||||
|
|
||||||
AnnoClip Annotated_EndClip_read(Alloc a, AnnotatedRef ref) {
|
|
||||||
return AnnoClip_read(a, AnnoClipRef(ref.offset + 4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Annotated_Nop_write(Alloc a, AnnotatedRef ref) {
|
void Annotated_Nop_write(Alloc a, AnnotatedRef ref) {
|
||||||
write_mem(a, ref.offset >> 2, Annotated_Nop);
|
write_mem(a, ref.offset >> 2, Annotated_Nop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Annotated_Stroke_write(Alloc a, AnnotatedRef ref, AnnoStroke s) {
|
void Annotated_Color_write(Alloc a, AnnotatedRef ref, uint flags, AnnoColor s) {
|
||||||
write_mem(a, ref.offset >> 2, Annotated_Stroke);
|
write_mem(a, ref.offset >> 2, (flags << 16) | Annotated_Color);
|
||||||
AnnoStroke_write(a, AnnoStrokeRef(ref.offset + 4), s);
|
AnnoColor_write(a, AnnoColorRef(ref.offset + 4), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Annotated_Fill_write(Alloc a, AnnotatedRef ref, AnnoFill s) {
|
void Annotated_Image_write(Alloc a, AnnotatedRef ref, uint flags, AnnoImage s) {
|
||||||
write_mem(a, ref.offset >> 2, Annotated_Fill);
|
write_mem(a, ref.offset >> 2, (flags << 16) | Annotated_Image);
|
||||||
AnnoFill_write(a, AnnoFillRef(ref.offset + 4), s);
|
AnnoImage_write(a, AnnoImageRef(ref.offset + 4), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Annotated_FillImage_write(Alloc a, AnnotatedRef ref, AnnoFillImage s) {
|
void Annotated_BeginClip_write(Alloc a, AnnotatedRef ref, uint flags, AnnoBeginClip s) {
|
||||||
write_mem(a, ref.offset >> 2, Annotated_FillImage);
|
write_mem(a, ref.offset >> 2, (flags << 16) | Annotated_BeginClip);
|
||||||
AnnoFillImage_write(a, AnnoFillImageRef(ref.offset + 4), s);
|
AnnoBeginClip_write(a, AnnoBeginClipRef(ref.offset + 4), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Annotated_BeginClip_write(Alloc a, AnnotatedRef ref, AnnoClip s) {
|
void Annotated_EndClip_write(Alloc a, AnnotatedRef ref, AnnoEndClip s) {
|
||||||
write_mem(a, ref.offset >> 2, Annotated_BeginClip);
|
|
||||||
AnnoClip_write(a, AnnoClipRef(ref.offset + 4), s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Annotated_EndClip_write(Alloc a, AnnotatedRef ref, AnnoClip s) {
|
|
||||||
write_mem(a, ref.offset >> 2, Annotated_EndClip);
|
write_mem(a, ref.offset >> 2, Annotated_EndClip);
|
||||||
AnnoClip_write(a, AnnoClipRef(ref.offset + 4), s);
|
AnnoEndClip_write(a, AnnoEndClipRef(ref.offset + 4), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,10 +46,14 @@ void main() {
|
|||||||
// Work assignment: 1 thread : 1 path element
|
// Work assignment: 1 thread : 1 path element
|
||||||
uint row_count = 0;
|
uint row_count = 0;
|
||||||
if (element_ix < conf.n_elements) {
|
if (element_ix < conf.n_elements) {
|
||||||
uint tag = Annotated_tag(conf.anno_alloc, ref);
|
AnnotatedTag tag = Annotated_tag(conf.anno_alloc, ref);
|
||||||
switch (tag) {
|
switch (tag.tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Color:
|
||||||
case Annotated_FillImage:
|
if (fill_mode_from_flags(tag.flags) != MODE_NONZERO) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fall through.
|
||||||
|
case Annotated_Image:
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
PathRef path_ref = PathRef(conf.tile_alloc.offset + element_ix * Path_size);
|
PathRef path_ref = PathRef(conf.tile_alloc.offset + element_ix * Path_size);
|
||||||
Path path = Path_read(conf.tile_alloc, path_ref);
|
Path path = Path_read(conf.tile_alloc, path_ref);
|
||||||
|
|||||||
@@ -56,22 +56,21 @@ void main() {
|
|||||||
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||||
uint tag = Annotated_Nop;
|
uint tag = Annotated_Nop;
|
||||||
if (element_ix < my_n_elements) {
|
if (element_ix < my_n_elements) {
|
||||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||||
}
|
}
|
||||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Color:
|
||||||
case Annotated_FillImage:
|
case Annotated_Image:
|
||||||
case Annotated_Stroke:
|
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
case Annotated_EndClip:
|
case Annotated_EndClip:
|
||||||
// Note: we take advantage of the fact that these drawing elements
|
// Note: we take advantage of the fact that these drawing elements
|
||||||
// have the bbox at the same place in their layout.
|
// have the bbox at the same place in their layout.
|
||||||
AnnoFill fill = Annotated_Fill_read(conf.anno_alloc, ref);
|
AnnoEndClip clip = Annotated_EndClip_read(conf.anno_alloc, ref);
|
||||||
x0 = int(floor(fill.bbox.x * SX));
|
x0 = int(floor(clip.bbox.x * SX));
|
||||||
y0 = int(floor(fill.bbox.y * SY));
|
y0 = int(floor(clip.bbox.y * SY));
|
||||||
x1 = int(ceil(fill.bbox.z * SX));
|
x1 = int(ceil(clip.bbox.z * SX));
|
||||||
y1 = int(ceil(fill.bbox.w * SY));
|
y1 = int(ceil(clip.bbox.w * SY));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+67
-59
@@ -70,6 +70,9 @@ Alloc read_tile_alloc(uint el_ix) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
// 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) {
|
bool alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit) {
|
||||||
if (cmd_ref.offset < 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_Jump_write(cmd_alloc, cmd_ref, jump);
|
||||||
cmd_alloc = new_cmd.alloc;
|
cmd_alloc = new_cmd.alloc;
|
||||||
cmd_ref = CmdRef(cmd_alloc.offset);
|
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;
|
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;
|
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);
|
Alloc cmd_alloc = slice_mem(conf.ptcl_alloc, this_tile_ix * PTCL_INITIAL_ALLOC, PTCL_INITIAL_ALLOC);
|
||||||
CmdRef cmd_ref = CmdRef(cmd_alloc.offset);
|
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
|
// The nesting depth of the clip stack
|
||||||
uint clip_depth = 0;
|
uint clip_depth = 0;
|
||||||
// State for the "clip zero" optimization. If it's nonzero, then we are
|
// State for the "clip zero" optimization. If it's nonzero, then we are
|
||||||
@@ -196,15 +201,14 @@ void main() {
|
|||||||
if (th_ix + rd_ix < wr_ix) {
|
if (th_ix + rd_ix < wr_ix) {
|
||||||
element_ix = sh_elements[th_ix];
|
element_ix = sh_elements[th_ix];
|
||||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bounding box of element in pixel coordinates.
|
// Bounding box of element in pixel coordinates.
|
||||||
uint tile_count;
|
uint tile_count;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Color:
|
||||||
case Annotated_FillImage:
|
case Annotated_Image:
|
||||||
case Annotated_Stroke:
|
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
case Annotated_EndClip:
|
case Annotated_EndClip:
|
||||||
// We have one "path" for each element, even if the element isn't
|
// We have one "path" for each element, even if the element isn't
|
||||||
@@ -256,7 +260,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + sh_elements[el_ix] * Annotated_size);
|
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + sh_elements[el_ix] * Annotated_size);
|
||||||
uint tag = Annotated_tag(conf.anno_alloc, ref);
|
uint tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||||
uint seq_ix = ix - (el_ix > 0 ? sh_tile_count[el_ix - 1] : 0);
|
uint seq_ix = ix - (el_ix > 0 ? sh_tile_count[el_ix - 1] : 0);
|
||||||
uint width = sh_tile_width[el_ix];
|
uint width = sh_tile_width[el_ix];
|
||||||
uint x = sh_tile_x0[el_ix] + seq_ix % width;
|
uint x = sh_tile_x0[el_ix] + seq_ix % width;
|
||||||
@@ -305,49 +309,57 @@ void main() {
|
|||||||
// If that turns out to be expensive, maybe we can pack it into
|
// If that turns out to be expensive, maybe we can pack it into
|
||||||
// shared memory (or perhaps just the tag).
|
// shared memory (or perhaps just the tag).
|
||||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
AnnotatedTag tag = Annotated_tag(conf.anno_alloc, ref);
|
||||||
|
|
||||||
if (clip_zero_depth == 0) {
|
if (clip_zero_depth == 0) {
|
||||||
switch (tag) {
|
switch (tag.tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Color:
|
||||||
Tile tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
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));
|
+ (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)) {
|
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tile.tile.offset != 0) {
|
if (fill_mode_from_flags(tag.flags) == MODE_NONZERO) {
|
||||||
CmdFill cmd_fill;
|
if (tile.tile.offset != 0) {
|
||||||
cmd_fill.tile_ref = tile.tile.offset;
|
CmdFill cmd_fill = CmdFill(tile.tile.offset, tile.backdrop);
|
||||||
cmd_fill.backdrop = tile.backdrop;
|
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
||||||
cmd_fill.rgba_color = fill.rgba_color;
|
cmd_ref.offset += 4 + CmdFill_size;
|
||||||
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
} else {
|
||||||
|
Cmd_Solid_write(cmd_alloc, cmd_ref);
|
||||||
|
cmd_ref.offset += 4;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Cmd_Solid_write(cmd_alloc, cmd_ref, CmdSolid(fill.rgba_color));
|
CmdStroke cmd_stroke = CmdStroke(tile.tile.offset, 0.5 * fill.linewidth);
|
||||||
|
Cmd_Stroke_write(cmd_alloc, cmd_ref, cmd_stroke);
|
||||||
|
cmd_ref.offset += 4 + CmdStroke_size;
|
||||||
}
|
}
|
||||||
cmd_ref.offset += Cmd_size;
|
Cmd_Color_write(cmd_alloc, cmd_ref, CmdColor(fill.rgba_color));
|
||||||
|
cmd_ref.offset += 4 + CmdColor_size;
|
||||||
break;
|
break;
|
||||||
case Annotated_FillImage:
|
case Annotated_Image:
|
||||||
tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
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));
|
+ (sh_tile_stride[element_ref_ix] * tile_y + tile_x) * Tile_size));
|
||||||
AnnoFillImage fill_img = Annotated_FillImage_read(conf.anno_alloc, ref);
|
AnnoImage fill_img = Annotated_Image_read(conf.anno_alloc, ref);
|
||||||
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tile.tile.offset != 0) {
|
if (fill_mode_from_flags(tag.flags) == MODE_NONZERO) {
|
||||||
CmdFillImage cmd_fill_img;
|
if (tile.tile.offset != 0) {
|
||||||
cmd_fill_img.tile_ref = tile.tile.offset;
|
CmdFill cmd_fill = CmdFill(tile.tile.offset, tile.backdrop);
|
||||||
cmd_fill_img.backdrop = tile.backdrop;
|
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
||||||
cmd_fill_img.index = fill_img.index;
|
cmd_ref.offset += 4 + CmdFill_size;
|
||||||
cmd_fill_img.offset = fill_img.offset;
|
} else {
|
||||||
Cmd_FillImage_write(cmd_alloc, cmd_ref, cmd_fill_img);
|
Cmd_Solid_write(cmd_alloc, cmd_ref);
|
||||||
|
cmd_ref.offset += 4;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
CmdSolidImage cmd_solid_img;
|
CmdStroke cmd_stroke = CmdStroke(tile.tile.offset, 0.5 * fill_img.linewidth);
|
||||||
cmd_solid_img.index = fill_img.index;
|
Cmd_Stroke_write(cmd_alloc, cmd_ref, cmd_stroke);
|
||||||
cmd_solid_img.offset = fill_img.offset;
|
cmd_ref.offset += 4 + CmdStroke_size;
|
||||||
Cmd_SolidImage_write(cmd_alloc, cmd_ref, cmd_solid_img);
|
|
||||||
}
|
}
|
||||||
cmd_ref.offset += Cmd_size;
|
Cmd_Image_write(cmd_alloc, cmd_ref, CmdImage(fill_img.index, fill_img.offset));
|
||||||
|
cmd_ref.offset += 4 + CmdImage_size;
|
||||||
break;
|
break;
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
tile = Tile_read(read_tile_alloc(element_ref_ix), TileRef(sh_tile_base[element_ref_ix]
|
||||||
@@ -357,20 +369,28 @@ void main() {
|
|||||||
} else if (tile.tile.offset == 0 && clip_depth < 32) {
|
} else if (tile.tile.offset == 0 && clip_depth < 32) {
|
||||||
clip_one_mask |= (1 << clip_depth);
|
clip_one_mask |= (1 << clip_depth);
|
||||||
} else {
|
} else {
|
||||||
|
AnnoBeginClip begin_clip = Annotated_BeginClip_read(conf.anno_alloc, ref);
|
||||||
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tile.tile.offset != 0) {
|
if (fill_mode_from_flags(tag.flags) == MODE_NONZERO) {
|
||||||
CmdBeginClip cmd_begin_clip;
|
if (tile.tile.offset != 0) {
|
||||||
cmd_begin_clip.tile_ref = tile.tile.offset;
|
CmdFill cmd_fill = CmdFill(tile.tile.offset, tile.backdrop);
|
||||||
cmd_begin_clip.backdrop = tile.backdrop;
|
Cmd_Fill_write(cmd_alloc, cmd_ref, cmd_fill);
|
||||||
Cmd_BeginClip_write(cmd_alloc, cmd_ref, cmd_begin_clip);
|
cmd_ref.offset += 4 + CmdFill_size;
|
||||||
|
} else {
|
||||||
|
// TODO: here is where a bunch of optimization magic should happen
|
||||||
|
float alpha = tile.backdrop == 0 ? 0.0 : 1.0;
|
||||||
|
Cmd_Alpha_write(cmd_alloc, cmd_ref, CmdAlpha(alpha));
|
||||||
|
cmd_ref.offset += 4 + CmdAlpha_size;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: here is where a bunch of optimization magic should happen
|
CmdStroke cmd_stroke = CmdStroke(tile.tile.offset, 0.5 * begin_clip.linewidth);
|
||||||
float alpha = tile.backdrop == 0 ? 0.0 : 1.0;
|
Cmd_Stroke_write(cmd_alloc, cmd_ref, cmd_stroke);
|
||||||
Cmd_BeginSolidClip_write(cmd_alloc, cmd_ref, CmdBeginSolidClip(alpha));
|
cmd_ref.offset += 4 + CmdStroke_size;
|
||||||
}
|
}
|
||||||
cmd_ref.offset += Cmd_size;
|
Cmd_BeginClip_write(cmd_alloc, cmd_ref);
|
||||||
|
cmd_ref.offset += 4;
|
||||||
if (clip_depth < 32) {
|
if (clip_depth < 32) {
|
||||||
clip_one_mask &= ~(1 << clip_depth);
|
clip_one_mask &= ~(1 << clip_depth);
|
||||||
}
|
}
|
||||||
@@ -383,28 +403,16 @@ void main() {
|
|||||||
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Cmd_EndClip_write(cmd_alloc, cmd_ref, CmdEndClip(1.0));
|
Cmd_Solid_write(cmd_alloc, cmd_ref);
|
||||||
cmd_ref.offset += Cmd_size;
|
cmd_ref.offset += 4;
|
||||||
|
Cmd_EndClip_write(cmd_alloc, cmd_ref);
|
||||||
|
cmd_ref.offset += 4;
|
||||||
}
|
}
|
||||||
break;
|
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 {
|
} else {
|
||||||
// In "clip zero" state, suppress all drawing
|
// In "clip zero" state, suppress all drawing
|
||||||
switch (tag) {
|
switch (tag.tag) {
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
clip_depth++;
|
clip_depth++;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+75
-69
@@ -63,6 +63,11 @@ uint state_flag_index(uint partition_ix) {
|
|||||||
#define FLAG_SET_LINEWIDTH 1
|
#define FLAG_SET_LINEWIDTH 1
|
||||||
#define FLAG_SET_BBOX 2
|
#define FLAG_SET_BBOX 2
|
||||||
#define FLAG_RESET_BBOX 4
|
#define FLAG_RESET_BBOX 4
|
||||||
|
#define FLAG_SET_FILL_MODE 8
|
||||||
|
// Fill modes take up the next bit. Non-zero fill is 0, stroke is 1.
|
||||||
|
#define LG_FILL_MODE 4
|
||||||
|
#define FILL_MODE_BITS 1
|
||||||
|
#define FILL_MODE_MASK (FILL_MODE_BITS << LG_FILL_MODE)
|
||||||
|
|
||||||
// This is almost like a monoid (the interaction between transformation and
|
// This is almost like a monoid (the interaction between transformation and
|
||||||
// bounding boxes is approximate)
|
// bounding boxes is approximate)
|
||||||
@@ -88,8 +93,11 @@ State combine_state(State a, State b) {
|
|||||||
c.translate.x = a.mat.x * b.translate.x + a.mat.z * b.translate.y + a.translate.x;
|
c.translate.x = a.mat.x * b.translate.x + a.mat.z * b.translate.y + a.translate.x;
|
||||||
c.translate.y = a.mat.y * b.translate.x + a.mat.w * b.translate.y + a.translate.y;
|
c.translate.y = a.mat.y * b.translate.x + a.mat.w * b.translate.y + a.translate.y;
|
||||||
c.linewidth = (b.flags & FLAG_SET_LINEWIDTH) == 0 ? a.linewidth : b.linewidth;
|
c.linewidth = (b.flags & FLAG_SET_LINEWIDTH) == 0 ? a.linewidth : b.linewidth;
|
||||||
c.flags = (a.flags & (FLAG_SET_LINEWIDTH | FLAG_SET_BBOX)) | b.flags;
|
c.flags = (a.flags & (FLAG_SET_LINEWIDTH | FLAG_SET_BBOX | FLAG_SET_FILL_MODE)) | b.flags;
|
||||||
c.flags |= (a.flags & FLAG_RESET_BBOX) >> 1;
|
c.flags |= (a.flags & FLAG_RESET_BBOX) >> 1;
|
||||||
|
uint fill_mode = (b.flags & FLAG_SET_FILL_MODE) == 0 ? a.flags : b.flags;
|
||||||
|
fill_mode &= FILL_MODE_MASK;
|
||||||
|
c.flags = (c.flags & ~FILL_MODE_MASK) | fill_mode;
|
||||||
c.path_count = a.path_count + b.path_count;
|
c.path_count = a.path_count + b.path_count;
|
||||||
c.pathseg_count = a.pathseg_count + b.pathseg_count;
|
c.pathseg_count = a.pathseg_count + b.pathseg_count;
|
||||||
c.trans_count = a.trans_count + b.trans_count;
|
c.trans_count = a.trans_count + b.trans_count;
|
||||||
@@ -99,7 +107,7 @@ State combine_state(State a, State b) {
|
|||||||
State map_element(ElementRef ref) {
|
State map_element(ElementRef ref) {
|
||||||
// TODO: it would *probably* be more efficient to make the memory read patterns less
|
// TODO: it would *probably* be more efficient to make the memory read patterns less
|
||||||
// divergent, though it would be more wasted memory.
|
// divergent, though it would be more wasted memory.
|
||||||
uint tag = Element_tag(ref);
|
uint tag = Element_tag(ref).tag;
|
||||||
State c;
|
State c;
|
||||||
c.bbox = vec4(0.0, 0.0, 0.0, 0.0);
|
c.bbox = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
c.mat = vec4(1.0, 0.0, 0.0, 1.0);
|
c.mat = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
@@ -110,30 +118,26 @@ State map_element(ElementRef ref) {
|
|||||||
c.pathseg_count = 0;
|
c.pathseg_count = 0;
|
||||||
c.trans_count = 0;
|
c.trans_count = 0;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case Element_FillLine:
|
case Element_Line:
|
||||||
case Element_StrokeLine:
|
LineSeg line = Element_Line_read(ref);
|
||||||
LineSeg line = Element_FillLine_read(ref);
|
|
||||||
c.bbox.xy = min(line.p0, line.p1);
|
c.bbox.xy = min(line.p0, line.p1);
|
||||||
c.bbox.zw = max(line.p0, line.p1);
|
c.bbox.zw = max(line.p0, line.p1);
|
||||||
c.pathseg_count = 1;
|
c.pathseg_count = 1;
|
||||||
break;
|
break;
|
||||||
case Element_FillQuad:
|
case Element_Quad:
|
||||||
case Element_StrokeQuad:
|
QuadSeg quad = Element_Quad_read(ref);
|
||||||
QuadSeg quad = Element_FillQuad_read(ref);
|
|
||||||
c.bbox.xy = min(min(quad.p0, quad.p1), quad.p2);
|
c.bbox.xy = min(min(quad.p0, quad.p1), quad.p2);
|
||||||
c.bbox.zw = max(max(quad.p0, quad.p1), quad.p2);
|
c.bbox.zw = max(max(quad.p0, quad.p1), quad.p2);
|
||||||
c.pathseg_count = 1;
|
c.pathseg_count = 1;
|
||||||
break;
|
break;
|
||||||
case Element_FillCubic:
|
case Element_Cubic:
|
||||||
case Element_StrokeCubic:
|
CubicSeg cubic = Element_Cubic_read(ref);
|
||||||
CubicSeg cubic = Element_FillCubic_read(ref);
|
|
||||||
c.bbox.xy = min(min(cubic.p0, cubic.p1), min(cubic.p2, cubic.p3));
|
c.bbox.xy = min(min(cubic.p0, cubic.p1), min(cubic.p2, cubic.p3));
|
||||||
c.bbox.zw = max(max(cubic.p0, cubic.p1), max(cubic.p2, cubic.p3));
|
c.bbox.zw = max(max(cubic.p0, cubic.p1), max(cubic.p2, cubic.p3));
|
||||||
c.pathseg_count = 1;
|
c.pathseg_count = 1;
|
||||||
break;
|
break;
|
||||||
case Element_Fill:
|
case Element_FillColor:
|
||||||
case Element_FillImage:
|
case Element_FillImage:
|
||||||
case Element_Stroke:
|
|
||||||
case Element_BeginClip:
|
case Element_BeginClip:
|
||||||
c.flags = FLAG_RESET_BBOX;
|
c.flags = FLAG_RESET_BBOX;
|
||||||
c.path_count = 1;
|
c.path_count = 1;
|
||||||
@@ -152,6 +156,10 @@ State map_element(ElementRef ref) {
|
|||||||
c.translate = t.translate;
|
c.translate = t.translate;
|
||||||
c.trans_count = 1;
|
c.trans_count = 1;
|
||||||
break;
|
break;
|
||||||
|
case Element_SetFillMode:
|
||||||
|
SetFillMode fm = Element_SetFillMode_read(ref);
|
||||||
|
c.flags = FLAG_SET_FILL_MODE | (fm.fill_mode << LG_FILL_MODE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -291,111 +299,109 @@ void main() {
|
|||||||
// gains to be had from stashing in shared memory or possibly
|
// gains to be had from stashing in shared memory or possibly
|
||||||
// registers (though register pressure is an issue).
|
// registers (though register pressure is an issue).
|
||||||
ElementRef this_ref = Element_index(ref, i);
|
ElementRef this_ref = Element_index(ref, i);
|
||||||
uint tag = Element_tag(this_ref);
|
ElementTag tag = Element_tag(this_ref);
|
||||||
switch (tag) {
|
uint fill_mode = fill_mode_from_flags(st.flags >> LG_FILL_MODE);
|
||||||
case Element_FillLine:
|
bool is_stroke = fill_mode == MODE_STROKE;
|
||||||
case Element_StrokeLine:
|
switch (tag.tag) {
|
||||||
LineSeg line = Element_StrokeLine_read(this_ref);
|
case Element_Line:
|
||||||
PathStrokeCubic path_cubic;
|
LineSeg line = Element_Line_read(this_ref);
|
||||||
|
PathCubic path_cubic;
|
||||||
path_cubic.p0 = line.p0;
|
path_cubic.p0 = line.p0;
|
||||||
path_cubic.p1 = mix(line.p0, line.p1, 1.0 / 3.0);
|
path_cubic.p1 = mix(line.p0, line.p1, 1.0 / 3.0);
|
||||||
path_cubic.p2 = mix(line.p1, line.p0, 1.0 / 3.0);
|
path_cubic.p2 = mix(line.p1, line.p0, 1.0 / 3.0);
|
||||||
path_cubic.p3 = line.p1;
|
path_cubic.p3 = line.p1;
|
||||||
path_cubic.path_ix = st.path_count;
|
path_cubic.path_ix = st.path_count;
|
||||||
path_cubic.trans_ix = st.trans_count;
|
path_cubic.trans_ix = st.trans_count;
|
||||||
if (tag == Element_StrokeLine) {
|
if (is_stroke) {
|
||||||
path_cubic.stroke = get_linewidth(st);
|
path_cubic.stroke = get_linewidth(st);
|
||||||
} else {
|
} else {
|
||||||
path_cubic.stroke = vec2(0.0);
|
path_cubic.stroke = vec2(0.0);
|
||||||
}
|
}
|
||||||
// We do encoding a bit by hand to minimize divergence. Another approach
|
|
||||||
// would be to have a fill/stroke bool.
|
|
||||||
PathSegRef path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
PathSegRef path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
||||||
uint out_tag = tag == Element_FillLine ? PathSeg_FillCubic : PathSeg_StrokeCubic;
|
PathSeg_Cubic_write(conf.pathseg_alloc, path_out_ref, fill_mode, path_cubic);
|
||||||
write_mem(conf.pathseg_alloc, path_out_ref.offset >> 2, out_tag);
|
|
||||||
PathStrokeCubic_write(conf.pathseg_alloc, PathStrokeCubicRef(path_out_ref.offset + 4), path_cubic);
|
|
||||||
break;
|
break;
|
||||||
case Element_FillQuad:
|
case Element_Quad:
|
||||||
case Element_StrokeQuad:
|
QuadSeg quad = Element_Quad_read(this_ref);
|
||||||
QuadSeg quad = Element_StrokeQuad_read(this_ref);
|
|
||||||
path_cubic.p0 = quad.p0;
|
path_cubic.p0 = quad.p0;
|
||||||
path_cubic.p1 = mix(quad.p1, quad.p0, 1.0 / 3.0);
|
path_cubic.p1 = mix(quad.p1, quad.p0, 1.0 / 3.0);
|
||||||
path_cubic.p2 = mix(quad.p1, quad.p2, 1.0 / 3.0);
|
path_cubic.p2 = mix(quad.p1, quad.p2, 1.0 / 3.0);
|
||||||
path_cubic.p3 = quad.p2;
|
path_cubic.p3 = quad.p2;
|
||||||
path_cubic.path_ix = st.path_count;
|
path_cubic.path_ix = st.path_count;
|
||||||
path_cubic.trans_ix = st.trans_count;
|
path_cubic.trans_ix = st.trans_count;
|
||||||
if (tag == Element_StrokeQuad) {
|
if (is_stroke) {
|
||||||
path_cubic.stroke = get_linewidth(st);
|
path_cubic.stroke = get_linewidth(st);
|
||||||
} else {
|
} else {
|
||||||
path_cubic.stroke = vec2(0.0);
|
path_cubic.stroke = vec2(0.0);
|
||||||
}
|
}
|
||||||
// We do encoding a bit by hand to minimize divergence. Another approach
|
|
||||||
// would be to have a fill/stroke bool.
|
|
||||||
path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
||||||
out_tag = tag == Element_FillQuad ? PathSeg_FillCubic : PathSeg_StrokeCubic;
|
PathSeg_Cubic_write(conf.pathseg_alloc, path_out_ref, fill_mode, path_cubic);
|
||||||
write_mem(conf.pathseg_alloc, path_out_ref.offset >> 2, out_tag);
|
|
||||||
PathStrokeCubic_write(conf.pathseg_alloc, PathStrokeCubicRef(path_out_ref.offset + 4), path_cubic);
|
|
||||||
break;
|
break;
|
||||||
case Element_FillCubic:
|
case Element_Cubic:
|
||||||
case Element_StrokeCubic:
|
CubicSeg cubic = Element_Cubic_read(this_ref);
|
||||||
CubicSeg cubic = Element_StrokeCubic_read(this_ref);
|
|
||||||
path_cubic.p0 = cubic.p0;
|
path_cubic.p0 = cubic.p0;
|
||||||
path_cubic.p1 = cubic.p1;
|
path_cubic.p1 = cubic.p1;
|
||||||
path_cubic.p2 = cubic.p2;
|
path_cubic.p2 = cubic.p2;
|
||||||
path_cubic.p3 = cubic.p3;
|
path_cubic.p3 = cubic.p3;
|
||||||
path_cubic.path_ix = st.path_count;
|
path_cubic.path_ix = st.path_count;
|
||||||
path_cubic.trans_ix = st.trans_count;
|
path_cubic.trans_ix = st.trans_count;
|
||||||
if (tag == Element_StrokeCubic) {
|
if (is_stroke) {
|
||||||
path_cubic.stroke = get_linewidth(st);
|
path_cubic.stroke = get_linewidth(st);
|
||||||
} else {
|
} else {
|
||||||
path_cubic.stroke = vec2(0.0);
|
path_cubic.stroke = vec2(0.0);
|
||||||
}
|
}
|
||||||
// We do encoding a bit by hand to minimize divergence. Another approach
|
|
||||||
// would be to have a fill/stroke bool.
|
|
||||||
path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
path_out_ref = PathSegRef(conf.pathseg_alloc.offset + (st.pathseg_count - 1) * PathSeg_size);
|
||||||
out_tag = tag == Element_FillCubic ? PathSeg_FillCubic : PathSeg_StrokeCubic;
|
PathSeg_Cubic_write(conf.pathseg_alloc, path_out_ref, fill_mode, path_cubic);
|
||||||
write_mem(conf.pathseg_alloc, path_out_ref.offset >> 2, out_tag);
|
|
||||||
PathStrokeCubic_write(conf.pathseg_alloc, PathStrokeCubicRef(path_out_ref.offset + 4), path_cubic);
|
|
||||||
break;
|
break;
|
||||||
case Element_Stroke:
|
case Element_FillColor:
|
||||||
Stroke stroke = Element_Stroke_read(this_ref);
|
FillColor fill = Element_FillColor_read(this_ref);
|
||||||
AnnoStroke anno_stroke;
|
AnnoColor anno_fill;
|
||||||
anno_stroke.rgba_color = stroke.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);
|
|
||||||
break;
|
|
||||||
case Element_Fill:
|
|
||||||
Fill fill = Element_Fill_read(this_ref);
|
|
||||||
AnnoFill anno_fill;
|
|
||||||
anno_fill.rgba_color = fill.rgba_color;
|
anno_fill.rgba_color = fill.rgba_color;
|
||||||
anno_fill.bbox = st.bbox;
|
if (is_stroke) {
|
||||||
out_ref = AnnotatedRef(conf.anno_alloc.offset + (st.path_count - 1) * Annotated_size);
|
vec2 lw = get_linewidth(st);
|
||||||
Annotated_Fill_write(conf.anno_alloc, out_ref, anno_fill);
|
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 {
|
||||||
|
anno_fill.bbox = st.bbox;
|
||||||
|
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;
|
break;
|
||||||
case Element_FillImage:
|
case Element_FillImage:
|
||||||
FillImage fill_img = Element_FillImage_read(this_ref);
|
FillImage fill_img = Element_FillImage_read(this_ref);
|
||||||
AnnoFillImage anno_fill_img;
|
AnnoImage anno_img;
|
||||||
anno_fill_img.index = fill_img.index;
|
anno_img.index = fill_img.index;
|
||||||
anno_fill_img.offset = fill_img.offset;
|
anno_img.offset = fill_img.offset;
|
||||||
anno_fill_img.bbox = st.bbox;
|
if (is_stroke) {
|
||||||
|
vec2 lw = get_linewidth(st);
|
||||||
|
anno_img.bbox = st.bbox + vec4(-lw, lw);
|
||||||
|
anno_img.linewidth = st.linewidth * sqrt(abs(st.mat.x * st.mat.w - st.mat.y * st.mat.z));
|
||||||
|
} else {
|
||||||
|
anno_img.bbox = st.bbox;
|
||||||
|
anno_img.linewidth = 0.0;
|
||||||
|
}
|
||||||
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);
|
Annotated_Image_write(conf.anno_alloc, out_ref, fill_mode, anno_img);
|
||||||
break;
|
break;
|
||||||
case Element_BeginClip:
|
case Element_BeginClip:
|
||||||
Clip begin_clip = Element_BeginClip_read(this_ref);
|
Clip begin_clip = Element_BeginClip_read(this_ref);
|
||||||
AnnoClip anno_begin_clip = AnnoClip(begin_clip.bbox);
|
AnnoBeginClip anno_begin_clip;
|
||||||
// This is the absolute bbox, it's been transformed during encoding.
|
if (is_stroke) {
|
||||||
anno_begin_clip.bbox = begin_clip.bbox;
|
vec2 lw = get_linewidth(st);
|
||||||
|
// This is the absolute bbox, it's been transformed during encoding.
|
||||||
|
anno_begin_clip.bbox = begin_clip.bbox + vec4(-lw, lw);
|
||||||
|
anno_begin_clip.linewidth = st.linewidth * sqrt(abs(st.mat.x * st.mat.w - st.mat.y * st.mat.z));
|
||||||
|
} else {
|
||||||
|
anno_begin_clip.bbox = begin_clip.bbox;
|
||||||
|
anno_fill.linewidth = 0.0;
|
||||||
|
}
|
||||||
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_BeginClip_write(conf.anno_alloc, out_ref, anno_begin_clip);
|
Annotated_BeginClip_write(conf.anno_alloc, out_ref, fill_mode, anno_begin_clip);
|
||||||
break;
|
break;
|
||||||
case Element_EndClip:
|
case Element_EndClip:
|
||||||
Clip end_clip = Element_EndClip_read(this_ref);
|
Clip end_clip = Element_EndClip_read(this_ref);
|
||||||
// This bbox is expected to be the same as the begin one.
|
// This bbox is expected to be the same as the begin one.
|
||||||
AnnoClip anno_end_clip = AnnoClip(end_clip.bbox);
|
AnnoEndClip anno_end_clip = AnnoEndClip(end_clip.bbox);
|
||||||
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_EndClip_write(conf.anno_alloc, out_ref, anno_end_clip);
|
Annotated_EndClip_write(conf.anno_alloc, out_ref, anno_end_clip);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+61
-76
@@ -56,40 +56,6 @@ MallocResult alloc_clip_buf(uint link) {
|
|||||||
return sh_clip_alloc;
|
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) {
|
vec3 tosRGB(vec3 rgb) {
|
||||||
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308));
|
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308));
|
||||||
vec3 below = vec3(12.92)*rgb;
|
vec3 below = vec3(12.92)*rgb;
|
||||||
@@ -118,7 +84,7 @@ uint packsRGB(vec4 rgba) {
|
|||||||
return packUnorm4x8(rgba.wzyx);
|
return packUnorm4x8(rgba.wzyx);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4[CHUNK] fillImage(uvec2 xy, CmdSolidImage cmd_img) {
|
vec4[CHUNK] fillImage(uvec2 xy, CmdImage cmd_img) {
|
||||||
vec4 rgba[CHUNK];
|
vec4 rgba[CHUNK];
|
||||||
for (uint i = 0; i < CHUNK; i++) {
|
for (uint i = 0; i < CHUNK; i++) {
|
||||||
ivec2 uv = ivec2(xy.x, xy.y + i * CHUNK_DY) + cmd_img.offset;
|
ivec2 uv = ivec2(xy.x, xy.y + i * CHUNK_DY) + cmd_img.offset;
|
||||||
@@ -160,8 +126,9 @@ void main() {
|
|||||||
mask[i] = 1.0;
|
mask[i] = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float area[CHUNK];
|
||||||
while (true) {
|
while (true) {
|
||||||
uint tag = Cmd_tag(cmd_alloc, cmd_ref);
|
uint tag = Cmd_tag(cmd_alloc, cmd_ref).tag;
|
||||||
if (tag == Cmd_End) {
|
if (tag == Cmd_End) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -183,31 +150,73 @@ void main() {
|
|||||||
}
|
}
|
||||||
tile_seg_ref = seg.next;
|
tile_seg_ref = seg.next;
|
||||||
} while (tile_seg_ref.offset != 0);
|
} while (tile_seg_ref.offset != 0);
|
||||||
vec4 fg_rgba = unpacksRGB(stroke.rgba_color);
|
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
float alpha = clamp(stroke.half_width + 0.5 - df[k], 0.0, 1.0);
|
area[k] = 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);
|
|
||||||
}
|
}
|
||||||
|
cmd_ref.offset += 4 + CmdStroke_size;
|
||||||
break;
|
break;
|
||||||
case Cmd_Fill:
|
case Cmd_Fill:
|
||||||
CmdFill fill = Cmd_Fill_read(cmd_alloc, cmd_ref);
|
CmdFill fill = Cmd_Fill_read(cmd_alloc, cmd_ref);
|
||||||
float area[CHUNK];
|
for (uint k = 0; k < CHUNK; k++) area[k] = float(fill.backdrop);
|
||||||
area = computeArea(xy, fill.backdrop, fill.tile_ref);
|
tile_seg_ref = TileSegRef(fill.tile_ref);
|
||||||
fg_rgba = unpacksRGB(fill.rgba_color);
|
// 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);
|
||||||
|
}
|
||||||
|
cmd_ref.offset += 4 + CmdFill_size;
|
||||||
|
break;
|
||||||
|
case Cmd_Solid:
|
||||||
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
|
area[k] = 1.0;
|
||||||
|
}
|
||||||
|
cmd_ref.offset += 4;
|
||||||
|
break;
|
||||||
|
case Cmd_Alpha:
|
||||||
|
CmdAlpha alpha = Cmd_Alpha_read(cmd_alloc, cmd_ref);
|
||||||
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
|
area[k] = alpha.alpha;
|
||||||
|
}
|
||||||
|
cmd_ref.offset += 4 + CmdAlpha_size;
|
||||||
|
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++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * area[k] * fg_rgba.a);
|
rgb[k] = mix(rgb[k], fg_rgba.rgb, mask[k] * area[k] * fg_rgba.a);
|
||||||
}
|
}
|
||||||
|
cmd_ref.offset += 4 + CmdColor_size;
|
||||||
break;
|
break;
|
||||||
case Cmd_FillImage:
|
case Cmd_Image:
|
||||||
CmdFillImage fill_img = Cmd_FillImage_read(cmd_alloc, cmd_ref);
|
CmdImage fill_img = Cmd_Image_read(cmd_alloc, cmd_ref);
|
||||||
area = computeArea(xy, fill_img.backdrop, fill_img.tile_ref);
|
vec4 rgba[CHUNK] = fillImage(xy_uint, fill_img);
|
||||||
vec4 rgba[CHUNK] = fillImage(xy_uint, CmdSolidImage(fill_img.index, fill_img.offset));
|
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * area[k] * rgba[k].a);
|
rgb[k] = mix(rgb[k], rgba[k].rgb, mask[k] * area[k] * rgba[k].a);
|
||||||
}
|
}
|
||||||
|
cmd_ref.offset += 4 + CmdImage_size;
|
||||||
break;
|
break;
|
||||||
case Cmd_BeginClip:
|
case Cmd_BeginClip:
|
||||||
case Cmd_BeginSolidClip:
|
|
||||||
uint blend_slot = blend_sp % BLEND_STACK_SIZE;
|
uint blend_slot = blend_sp % BLEND_STACK_SIZE;
|
||||||
if (blend_sp == blend_spill + BLEND_STACK_SIZE) {
|
if (blend_sp == blend_spill + BLEND_STACK_SIZE) {
|
||||||
// spill to scratch buffer
|
// spill to scratch buffer
|
||||||
@@ -222,23 +231,13 @@ void main() {
|
|||||||
}
|
}
|
||||||
blend_spill++;
|
blend_spill++;
|
||||||
}
|
}
|
||||||
if (tag == Cmd_BeginClip) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
CmdBeginClip begin_clip = Cmd_BeginClip_read(cmd_alloc, cmd_ref);
|
blend_stack[blend_slot][k] = packsRGB(vec4(rgb[k], clamp(abs(area[k]), 0.0, 1.0)));
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
blend_sp++;
|
blend_sp++;
|
||||||
|
cmd_ref.offset += 4;
|
||||||
break;
|
break;
|
||||||
case Cmd_EndClip:
|
case Cmd_EndClip:
|
||||||
CmdEndClip end_clip = Cmd_EndClip_read(cmd_alloc, cmd_ref);
|
|
||||||
blend_slot = (blend_sp - 1) % BLEND_STACK_SIZE;
|
blend_slot = (blend_sp - 1) % BLEND_STACK_SIZE;
|
||||||
if (blend_sp == blend_spill) {
|
if (blend_sp == blend_spill) {
|
||||||
uint base_ix = (clip_tos.offset >> 2) + gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_LocalInvocationID.y;
|
uint base_ix = (clip_tos.offset >> 2) + gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_LocalInvocationID.y;
|
||||||
@@ -251,29 +250,15 @@ void main() {
|
|||||||
blend_sp--;
|
blend_sp--;
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
vec4 rgba = unpacksRGB(blend_stack[blend_slot][k]);
|
vec4 rgba = unpacksRGB(blend_stack[blend_slot][k]);
|
||||||
rgb[k] = mix(rgba.rgb, rgb[k], end_clip.alpha * rgba.a);
|
rgb[k] = mix(rgba.rgb, rgb[k], area[k] * 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);
|
|
||||||
}
|
}
|
||||||
|
cmd_ref.offset += 4;
|
||||||
break;
|
break;
|
||||||
case Cmd_Jump:
|
case Cmd_Jump:
|
||||||
cmd_ref = CmdRef(Cmd_Jump_read(cmd_alloc, cmd_ref).new_ref);
|
cmd_ref = CmdRef(Cmd_Jump_read(cmd_alloc, cmd_ref).new_ref);
|
||||||
cmd_alloc.offset = cmd_ref.offset;
|
cmd_alloc.offset = cmd_ref.offset;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cmd_ref.offset += Cmd_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < CHUNK; i++) {
|
for (uint i = 0; i < CHUNK; i++) {
|
||||||
|
|||||||
@@ -94,14 +94,13 @@ void main() {
|
|||||||
uint element_ix = gl_GlobalInvocationID.x;
|
uint element_ix = gl_GlobalInvocationID.x;
|
||||||
PathSegRef ref = PathSegRef(conf.pathseg_alloc.offset + element_ix * PathSeg_size);
|
PathSegRef ref = PathSegRef(conf.pathseg_alloc.offset + element_ix * PathSeg_size);
|
||||||
|
|
||||||
uint tag = PathSeg_Nop;
|
PathSegTag tag = PathSegTag(PathSeg_Nop, 0);
|
||||||
if (element_ix < conf.n_pathseg) {
|
if (element_ix < conf.n_pathseg) {
|
||||||
tag = PathSeg_tag(conf.pathseg_alloc, ref);
|
tag = PathSeg_tag(conf.pathseg_alloc, ref);
|
||||||
}
|
}
|
||||||
switch (tag) {
|
switch (tag.tag) {
|
||||||
case PathSeg_FillCubic:
|
case PathSeg_Cubic:
|
||||||
case PathSeg_StrokeCubic:
|
PathCubic cubic = PathSeg_Cubic_read(conf.pathseg_alloc, ref);
|
||||||
PathStrokeCubic cubic = PathSeg_StrokeCubic_read(conf.pathseg_alloc, ref);
|
|
||||||
|
|
||||||
uint trans_ix = cubic.trans_ix;
|
uint trans_ix = cubic.trans_ix;
|
||||||
if (trans_ix > 0) {
|
if (trans_ix > 0) {
|
||||||
@@ -133,6 +132,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
uint n = max(uint(ceil(val * 0.5 / sqrt(REM_ACCURACY))), 1);
|
uint n = max(uint(ceil(val * 0.5 / sqrt(REM_ACCURACY))), 1);
|
||||||
|
|
||||||
|
bool is_stroke = fill_mode_from_flags(tag.flags) == MODE_STROKE;
|
||||||
uint path_ix = cubic.path_ix;
|
uint path_ix = cubic.path_ix;
|
||||||
Path path = Path_read(conf.tile_alloc, PathRef(conf.tile_alloc.offset + path_ix * Path_size));
|
Path path = Path_read(conf.tile_alloc, PathRef(conf.tile_alloc.offset + path_ix * Path_size));
|
||||||
Alloc path_alloc = new_alloc(path.tiles.offset, (path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y) * Tile_size);
|
Alloc path_alloc = new_alloc(path.tiles.offset, (path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y) * Tile_size);
|
||||||
@@ -212,7 +212,7 @@ void main() {
|
|||||||
for (int y = y0; y < y1; y++) {
|
for (int y = y0; y < y1; y++) {
|
||||||
float tile_y0 = float(y * TILE_HEIGHT_PX);
|
float tile_y0 = float(y * TILE_HEIGHT_PX);
|
||||||
int xbackdrop = max(xray + 1, bbox.x);
|
int xbackdrop = max(xray + 1, bbox.x);
|
||||||
if (tag == PathSeg_FillCubic && min(p0.y, p1.y) < tile_y0 && xbackdrop < bbox.z) {
|
if (!is_stroke && min(p0.y, p1.y) < tile_y0 && xbackdrop < bbox.z) {
|
||||||
int backdrop = p1.y < p0.y ? 1 : -1;
|
int backdrop = p1.y < p0.y ? 1 : -1;
|
||||||
TileRef tile_ref = Tile_index(path.tiles, uint(base + xbackdrop));
|
TileRef tile_ref = Tile_index(path.tiles, uint(base + xbackdrop));
|
||||||
uint tile_el = tile_ref.offset >> 2;
|
uint tile_el = tile_ref.offset >> 2;
|
||||||
@@ -248,7 +248,7 @@ void main() {
|
|||||||
tile_seg.origin = p0;
|
tile_seg.origin = p0;
|
||||||
tile_seg.vector = p1 - p0;
|
tile_seg.vector = p1 - p0;
|
||||||
float y_edge = 0.0;
|
float y_edge = 0.0;
|
||||||
if (tag == PathSeg_FillCubic) {
|
if (!is_stroke) {
|
||||||
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) {
|
if (min(p0.x, p1.x) < tile_x0) {
|
||||||
vec2 p = vec2(tile_x0, y_edge);
|
vec2 p = vec2(tile_x0, y_edge);
|
||||||
|
|||||||
+21
-80
@@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
// Code auto-generated by piet-gpu-derive
|
// Code auto-generated by piet-gpu-derive
|
||||||
|
|
||||||
struct PathFillCubicRef {
|
struct PathCubicRef {
|
||||||
uint offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PathStrokeCubicRef {
|
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -14,22 +10,7 @@ struct PathSegRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PathFillCubic {
|
struct PathCubic {
|
||||||
vec2 p0;
|
|
||||||
vec2 p1;
|
|
||||||
vec2 p2;
|
|
||||||
vec2 p3;
|
|
||||||
uint path_ix;
|
|
||||||
uint trans_ix;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PathFillCubic_size 40
|
|
||||||
|
|
||||||
PathFillCubicRef PathFillCubic_index(PathFillCubicRef ref, uint index) {
|
|
||||||
return PathFillCubicRef(ref.offset + index * PathFillCubic_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PathStrokeCubic {
|
|
||||||
vec2 p0;
|
vec2 p0;
|
||||||
vec2 p1;
|
vec2 p1;
|
||||||
vec2 p2;
|
vec2 p2;
|
||||||
@@ -39,58 +20,26 @@ struct PathStrokeCubic {
|
|||||||
vec2 stroke;
|
vec2 stroke;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PathStrokeCubic_size 48
|
#define PathCubic_size 48
|
||||||
|
|
||||||
PathStrokeCubicRef PathStrokeCubic_index(PathStrokeCubicRef ref, uint index) {
|
PathCubicRef PathCubic_index(PathCubicRef ref, uint index) {
|
||||||
return PathStrokeCubicRef(ref.offset + index * PathStrokeCubic_size);
|
return PathCubicRef(ref.offset + index * PathCubic_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PathSeg_Nop 0
|
#define PathSeg_Nop 0
|
||||||
#define PathSeg_FillCubic 1
|
#define PathSeg_Cubic 1
|
||||||
#define PathSeg_StrokeCubic 2
|
|
||||||
#define PathSeg_size 52
|
#define PathSeg_size 52
|
||||||
|
|
||||||
PathSegRef PathSeg_index(PathSegRef ref, uint index) {
|
PathSegRef PathSeg_index(PathSegRef ref, uint index) {
|
||||||
return PathSegRef(ref.offset + index * PathSeg_size);
|
return PathSegRef(ref.offset + index * PathSeg_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFillCubic PathFillCubic_read(Alloc a, PathFillCubicRef ref) {
|
struct PathSegTag {
|
||||||
uint ix = ref.offset >> 2;
|
uint tag;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint flags;
|
||||||
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);
|
|
||||||
uint raw5 = read_mem(a, ix + 5);
|
|
||||||
uint raw6 = read_mem(a, ix + 6);
|
|
||||||
uint raw7 = read_mem(a, ix + 7);
|
|
||||||
uint raw8 = read_mem(a, ix + 8);
|
|
||||||
uint raw9 = read_mem(a, ix + 9);
|
|
||||||
PathFillCubic s;
|
|
||||||
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
|
||||||
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
|
||||||
s.p2 = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
|
||||||
s.p3 = vec2(uintBitsToFloat(raw6), uintBitsToFloat(raw7));
|
|
||||||
s.path_ix = raw8;
|
|
||||||
s.trans_ix = raw9;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PathFillCubic_write(Alloc a, PathFillCubicRef ref, PathFillCubic s) {
|
PathCubic PathCubic_read(Alloc a, PathCubicRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
|
||||||
write_mem(a, ix + 0, floatBitsToUint(s.p0.x));
|
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.p0.y));
|
|
||||||
write_mem(a, ix + 2, floatBitsToUint(s.p1.x));
|
|
||||||
write_mem(a, ix + 3, floatBitsToUint(s.p1.y));
|
|
||||||
write_mem(a, ix + 4, floatBitsToUint(s.p2.x));
|
|
||||||
write_mem(a, ix + 5, floatBitsToUint(s.p2.y));
|
|
||||||
write_mem(a, ix + 6, floatBitsToUint(s.p3.x));
|
|
||||||
write_mem(a, ix + 7, floatBitsToUint(s.p3.y));
|
|
||||||
write_mem(a, ix + 8, s.path_ix);
|
|
||||||
write_mem(a, ix + 9, s.trans_ix);
|
|
||||||
}
|
|
||||||
|
|
||||||
PathStrokeCubic PathStrokeCubic_read(Alloc a, PathStrokeCubicRef ref) {
|
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
@@ -104,7 +53,7 @@ PathStrokeCubic PathStrokeCubic_read(Alloc a, PathStrokeCubicRef ref) {
|
|||||||
uint raw9 = read_mem(a, ix + 9);
|
uint raw9 = read_mem(a, ix + 9);
|
||||||
uint raw10 = read_mem(a, ix + 10);
|
uint raw10 = read_mem(a, ix + 10);
|
||||||
uint raw11 = read_mem(a, ix + 11);
|
uint raw11 = read_mem(a, ix + 11);
|
||||||
PathStrokeCubic s;
|
PathCubic s;
|
||||||
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
s.p0 = vec2(uintBitsToFloat(raw0), uintBitsToFloat(raw1));
|
||||||
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
s.p1 = vec2(uintBitsToFloat(raw2), uintBitsToFloat(raw3));
|
||||||
s.p2 = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
s.p2 = vec2(uintBitsToFloat(raw4), uintBitsToFloat(raw5));
|
||||||
@@ -115,7 +64,7 @@ PathStrokeCubic PathStrokeCubic_read(Alloc a, PathStrokeCubicRef ref) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathStrokeCubic_write(Alloc a, PathStrokeCubicRef ref, PathStrokeCubic s) {
|
void PathCubic_write(Alloc a, PathCubicRef ref, PathCubic s) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, floatBitsToUint(s.p0.x));
|
write_mem(a, ix + 0, floatBitsToUint(s.p0.x));
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.p0.y));
|
write_mem(a, ix + 1, floatBitsToUint(s.p0.y));
|
||||||
@@ -131,29 +80,21 @@ void PathStrokeCubic_write(Alloc a, PathStrokeCubicRef ref, PathStrokeCubic s) {
|
|||||||
write_mem(a, ix + 11, floatBitsToUint(s.stroke.y));
|
write_mem(a, ix + 11, floatBitsToUint(s.stroke.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint PathSeg_tag(Alloc a, PathSegRef ref) {
|
PathSegTag PathSeg_tag(Alloc a, PathSegRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||||
|
return PathSegTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFillCubic PathSeg_FillCubic_read(Alloc a, PathSegRef ref) {
|
PathCubic PathSeg_Cubic_read(Alloc a, PathSegRef ref) {
|
||||||
return PathFillCubic_read(a, PathFillCubicRef(ref.offset + 4));
|
return PathCubic_read(a, PathCubicRef(ref.offset + 4));
|
||||||
}
|
|
||||||
|
|
||||||
PathStrokeCubic PathSeg_StrokeCubic_read(Alloc a, PathSegRef ref) {
|
|
||||||
return PathStrokeCubic_read(a, PathStrokeCubicRef(ref.offset + 4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathSeg_Nop_write(Alloc a, PathSegRef ref) {
|
void PathSeg_Nop_write(Alloc a, PathSegRef ref) {
|
||||||
write_mem(a, ref.offset >> 2, PathSeg_Nop);
|
write_mem(a, ref.offset >> 2, PathSeg_Nop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathSeg_FillCubic_write(Alloc a, PathSegRef ref, PathFillCubic s) {
|
void PathSeg_Cubic_write(Alloc a, PathSegRef ref, uint flags, PathCubic s) {
|
||||||
write_mem(a, ref.offset >> 2, PathSeg_FillCubic);
|
write_mem(a, ref.offset >> 2, (flags << 16) | PathSeg_Cubic);
|
||||||
PathFillCubic_write(a, PathFillCubicRef(ref.offset + 4), s);
|
PathCubic_write(a, PathCubicRef(ref.offset + 4), s);
|
||||||
}
|
|
||||||
|
|
||||||
void PathSeg_StrokeCubic_write(Alloc a, PathSegRef ref, PathStrokeCubic s) {
|
|
||||||
write_mem(a, ref.offset >> 2, PathSeg_StrokeCubic);
|
|
||||||
PathStrokeCubic_write(a, PathStrokeCubicRef(ref.offset + 4), s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+88
-202
@@ -10,27 +10,15 @@ struct CmdFillRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFillImageRef {
|
struct CmdColorRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdBeginClipRef {
|
struct CmdImageRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdBeginSolidClipRef {
|
struct CmdAlphaRef {
|
||||||
uint offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CmdEndClipRef {
|
|
||||||
uint offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CmdSolidRef {
|
|
||||||
uint offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CmdSolidImageRef {
|
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,10 +33,9 @@ struct CmdRef {
|
|||||||
struct CmdStroke {
|
struct CmdStroke {
|
||||||
uint tile_ref;
|
uint tile_ref;
|
||||||
float half_width;
|
float half_width;
|
||||||
uint rgba_color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CmdStroke_size 12
|
#define CmdStroke_size 8
|
||||||
|
|
||||||
CmdStrokeRef CmdStroke_index(CmdStrokeRef ref, uint index) {
|
CmdStrokeRef CmdStroke_index(CmdStrokeRef ref, uint index) {
|
||||||
return CmdStrokeRef(ref.offset + index * CmdStroke_size);
|
return CmdStrokeRef(ref.offset + index * CmdStroke_size);
|
||||||
@@ -57,78 +44,43 @@ CmdStrokeRef CmdStroke_index(CmdStrokeRef ref, uint index) {
|
|||||||
struct CmdFill {
|
struct CmdFill {
|
||||||
uint tile_ref;
|
uint tile_ref;
|
||||||
int backdrop;
|
int backdrop;
|
||||||
uint rgba_color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CmdFill_size 12
|
#define CmdFill_size 8
|
||||||
|
|
||||||
CmdFillRef CmdFill_index(CmdFillRef ref, uint index) {
|
CmdFillRef CmdFill_index(CmdFillRef ref, uint index) {
|
||||||
return CmdFillRef(ref.offset + index * CmdFill_size);
|
return CmdFillRef(ref.offset + index * CmdFill_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CmdFillImage {
|
struct CmdColor {
|
||||||
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 {
|
|
||||||
uint rgba_color;
|
uint rgba_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CmdSolid_size 4
|
#define CmdColor_size 4
|
||||||
|
|
||||||
CmdSolidRef CmdSolid_index(CmdSolidRef ref, uint index) {
|
CmdColorRef CmdColor_index(CmdColorRef ref, uint index) {
|
||||||
return CmdSolidRef(ref.offset + index * CmdSolid_size);
|
return CmdColorRef(ref.offset + index * CmdColor_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CmdSolidImage {
|
struct CmdImage {
|
||||||
uint index;
|
uint index;
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CmdSolidImage_size 8
|
#define CmdImage_size 8
|
||||||
|
|
||||||
CmdSolidImageRef CmdSolidImage_index(CmdSolidImageRef ref, uint index) {
|
CmdImageRef CmdImage_index(CmdImageRef ref, uint index) {
|
||||||
return CmdSolidImageRef(ref.offset + index * CmdSolidImage_size);
|
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 {
|
struct CmdJump {
|
||||||
@@ -143,29 +95,32 @@ CmdJumpRef CmdJump_index(CmdJumpRef ref, uint index) {
|
|||||||
|
|
||||||
#define Cmd_End 0
|
#define Cmd_End 0
|
||||||
#define Cmd_Fill 1
|
#define Cmd_Fill 1
|
||||||
#define Cmd_FillImage 2
|
#define Cmd_Stroke 2
|
||||||
#define Cmd_BeginClip 3
|
#define Cmd_Solid 3
|
||||||
#define Cmd_BeginSolidClip 4
|
#define Cmd_Alpha 4
|
||||||
#define Cmd_EndClip 5
|
#define Cmd_Color 5
|
||||||
#define Cmd_Stroke 6
|
#define Cmd_Image 6
|
||||||
#define Cmd_Solid 7
|
#define Cmd_BeginClip 7
|
||||||
#define Cmd_SolidImage 8
|
#define Cmd_EndClip 8
|
||||||
#define Cmd_Jump 9
|
#define Cmd_Jump 9
|
||||||
#define Cmd_size 20
|
#define Cmd_size 12
|
||||||
|
|
||||||
CmdRef Cmd_index(CmdRef ref, uint index) {
|
CmdRef Cmd_index(CmdRef ref, uint index) {
|
||||||
return CmdRef(ref.offset + index * Cmd_size);
|
return CmdRef(ref.offset + index * Cmd_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CmdTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) {
|
CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
uint raw2 = read_mem(a, ix + 2);
|
|
||||||
CmdStroke s;
|
CmdStroke s;
|
||||||
s.tile_ref = raw0;
|
s.tile_ref = raw0;
|
||||||
s.half_width = uintBitsToFloat(raw1);
|
s.half_width = uintBitsToFloat(raw1);
|
||||||
s.rgba_color = raw2;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,18 +128,15 @@ void CmdStroke_write(Alloc a, CmdStrokeRef ref, CmdStroke s) {
|
|||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, s.tile_ref);
|
write_mem(a, ix + 0, s.tile_ref);
|
||||||
write_mem(a, ix + 1, floatBitsToUint(s.half_width));
|
write_mem(a, ix + 1, floatBitsToUint(s.half_width));
|
||||||
write_mem(a, ix + 2, s.rgba_color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdFill CmdFill_read(Alloc a, CmdFillRef ref) {
|
CmdFill CmdFill_read(Alloc a, CmdFillRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
uint raw2 = read_mem(a, ix + 2);
|
|
||||||
CmdFill s;
|
CmdFill s;
|
||||||
s.tile_ref = raw0;
|
s.tile_ref = raw0;
|
||||||
s.backdrop = int(raw1);
|
s.backdrop = int(raw1);
|
||||||
s.rgba_color = raw2;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,102 +144,50 @@ void CmdFill_write(Alloc a, CmdFillRef ref, CmdFill s) {
|
|||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, s.tile_ref);
|
write_mem(a, ix + 0, s.tile_ref);
|
||||||
write_mem(a, ix + 1, uint(s.backdrop));
|
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 ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
CmdColor s;
|
||||||
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;
|
|
||||||
s.rgba_color = raw0;
|
s.rgba_color = raw0;
|
||||||
return s;
|
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;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, s.rgba_color);
|
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 ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
uint raw1 = read_mem(a, ix + 1);
|
uint raw1 = read_mem(a, ix + 1);
|
||||||
CmdSolidImage s;
|
CmdImage s;
|
||||||
s.index = raw0;
|
s.index = raw0;
|
||||||
s.offset = ivec2(int(raw1 << 16) >> 16, int(raw1) >> 16);
|
s.offset = ivec2(int(raw1 << 16) >> 16, int(raw1) >> 16);
|
||||||
return s;
|
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;
|
uint ix = ref.offset >> 2;
|
||||||
write_mem(a, ix + 0, s.index);
|
write_mem(a, ix + 0, s.index);
|
||||||
write_mem(a, ix + 1, (uint(s.offset.x) & 0xffff) | (uint(s.offset.y) << 16));
|
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) {
|
CmdJump CmdJump_read(Alloc a, CmdJumpRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
uint raw0 = read_mem(a, ix + 0);
|
||||||
@@ -301,40 +201,29 @@ void CmdJump_write(Alloc a, CmdJumpRef ref, CmdJump s) {
|
|||||||
write_mem(a, ix + 0, s.new_ref);
|
write_mem(a, ix + 0, s.new_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Cmd_tag(Alloc a, CmdRef ref) {
|
CmdTag Cmd_tag(Alloc a, CmdRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||||
|
return CmdTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) {
|
CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) {
|
||||||
return CmdFill_read(a, CmdFillRef(ref.offset + 4));
|
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) {
|
CmdStroke Cmd_Stroke_read(Alloc a, CmdRef ref) {
|
||||||
return CmdStroke_read(a, CmdStrokeRef(ref.offset + 4));
|
return CmdStroke_read(a, CmdStrokeRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdSolid Cmd_Solid_read(Alloc a, CmdRef ref) {
|
CmdAlpha Cmd_Alpha_read(Alloc a, CmdRef ref) {
|
||||||
return CmdSolid_read(a, CmdSolidRef(ref.offset + 4));
|
return CmdAlpha_read(a, CmdAlphaRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdSolidImage Cmd_SolidImage_read(Alloc a, CmdRef ref) {
|
CmdColor Cmd_Color_read(Alloc a, CmdRef ref) {
|
||||||
return CmdSolidImage_read(a, CmdSolidImageRef(ref.offset + 4));
|
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) {
|
CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) {
|
||||||
@@ -350,39 +239,36 @@ void Cmd_Fill_write(Alloc a, CmdRef ref, CmdFill s) {
|
|||||||
CmdFill_write(a, CmdFillRef(ref.offset + 4), 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) {
|
void Cmd_Stroke_write(Alloc a, CmdRef ref, CmdStroke s) {
|
||||||
write_mem(a, ref.offset >> 2, Cmd_Stroke);
|
write_mem(a, ref.offset >> 2, Cmd_Stroke);
|
||||||
CmdStroke_write(a, CmdStrokeRef(ref.offset + 4), s);
|
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);
|
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) {
|
void Cmd_Alpha_write(Alloc a, CmdRef ref, CmdAlpha s) {
|
||||||
write_mem(a, ref.offset >> 2, Cmd_SolidImage);
|
write_mem(a, ref.offset >> 2, Cmd_Alpha);
|
||||||
CmdSolidImage_write(a, CmdSolidImageRef(ref.offset + 4), s);
|
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) {
|
void Cmd_Jump_write(Alloc a, CmdRef ref, CmdJump s) {
|
||||||
|
|||||||
+56
-65
@@ -14,7 +14,7 @@ struct CubicSegRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FillRef {
|
struct FillColorRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,10 +22,6 @@ struct FillImageRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StrokeRef {
|
|
||||||
uint offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SetLineWidthRef {
|
struct SetLineWidthRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
@@ -38,6 +34,10 @@ struct ClipRef {
|
|||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SetFillModeRef {
|
||||||
|
uint offset;
|
||||||
|
};
|
||||||
|
|
||||||
struct ElementRef {
|
struct ElementRef {
|
||||||
uint offset;
|
uint offset;
|
||||||
};
|
};
|
||||||
@@ -78,14 +78,14 @@ CubicSegRef CubicSeg_index(CubicSegRef ref, uint index) {
|
|||||||
return CubicSegRef(ref.offset + index * CubicSeg_size);
|
return CubicSegRef(ref.offset + index * CubicSeg_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Fill {
|
struct FillColor {
|
||||||
uint rgba_color;
|
uint rgba_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Fill_size 4
|
#define FillColor_size 4
|
||||||
|
|
||||||
FillRef Fill_index(FillRef ref, uint index) {
|
FillColorRef FillColor_index(FillColorRef ref, uint index) {
|
||||||
return FillRef(ref.offset + index * Fill_size);
|
return FillColorRef(ref.offset + index * FillColor_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FillImage {
|
struct FillImage {
|
||||||
@@ -99,16 +99,6 @@ FillImageRef FillImage_index(FillImageRef ref, uint index) {
|
|||||||
return FillImageRef(ref.offset + index * FillImage_size);
|
return FillImageRef(ref.offset + index * FillImage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Stroke {
|
|
||||||
uint rgba_color;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define Stroke_size 4
|
|
||||||
|
|
||||||
StrokeRef Stroke_index(StrokeRef ref, uint index) {
|
|
||||||
return StrokeRef(ref.offset + index * Stroke_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SetLineWidth {
|
struct SetLineWidth {
|
||||||
float width;
|
float width;
|
||||||
};
|
};
|
||||||
@@ -140,26 +130,38 @@ ClipRef Clip_index(ClipRef ref, uint index) {
|
|||||||
return ClipRef(ref.offset + index * Clip_size);
|
return ClipRef(ref.offset + index * Clip_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SetFillMode {
|
||||||
|
uint fill_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SetFillMode_size 4
|
||||||
|
|
||||||
|
SetFillModeRef SetFillMode_index(SetFillModeRef ref, uint index) {
|
||||||
|
return SetFillModeRef(ref.offset + index * SetFillMode_size);
|
||||||
|
}
|
||||||
|
|
||||||
#define Element_Nop 0
|
#define Element_Nop 0
|
||||||
#define Element_StrokeLine 1
|
#define Element_Line 1
|
||||||
#define Element_FillLine 2
|
#define Element_Quad 2
|
||||||
#define Element_StrokeQuad 3
|
#define Element_Cubic 3
|
||||||
#define Element_FillQuad 4
|
#define Element_FillColor 4
|
||||||
#define Element_StrokeCubic 5
|
#define Element_SetLineWidth 5
|
||||||
#define Element_FillCubic 6
|
#define Element_Transform 6
|
||||||
#define Element_Stroke 7
|
#define Element_BeginClip 7
|
||||||
#define Element_Fill 8
|
#define Element_EndClip 8
|
||||||
#define Element_SetLineWidth 9
|
#define Element_FillImage 9
|
||||||
#define Element_Transform 10
|
#define Element_SetFillMode 10
|
||||||
#define Element_BeginClip 11
|
|
||||||
#define Element_EndClip 12
|
|
||||||
#define Element_FillImage 13
|
|
||||||
#define Element_size 36
|
#define Element_size 36
|
||||||
|
|
||||||
ElementRef Element_index(ElementRef ref, uint index) {
|
ElementRef Element_index(ElementRef ref, uint index) {
|
||||||
return ElementRef(ref.offset + index * Element_size);
|
return ElementRef(ref.offset + index * Element_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ElementTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
LineSeg LineSeg_read(LineSegRef ref) {
|
LineSeg LineSeg_read(LineSegRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = scene[ix + 0];
|
uint raw0 = scene[ix + 0];
|
||||||
@@ -205,10 +207,10 @@ CubicSeg CubicSeg_read(CubicSegRef ref) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fill Fill_read(FillRef ref) {
|
FillColor FillColor_read(FillColorRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = scene[ix + 0];
|
uint raw0 = scene[ix + 0];
|
||||||
Fill s;
|
FillColor s;
|
||||||
s.rgba_color = raw0;
|
s.rgba_color = raw0;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -223,14 +225,6 @@ FillImage FillImage_read(FillImageRef ref) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stroke Stroke_read(StrokeRef ref) {
|
|
||||||
uint ix = ref.offset >> 2;
|
|
||||||
uint raw0 = scene[ix + 0];
|
|
||||||
Stroke s;
|
|
||||||
s.rgba_color = raw0;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLineWidth SetLineWidth_read(SetLineWidthRef ref) {
|
SetLineWidth SetLineWidth_read(SetLineWidthRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = scene[ix + 0];
|
uint raw0 = scene[ix + 0];
|
||||||
@@ -264,40 +258,33 @@ Clip Clip_read(ClipRef ref) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Element_tag(ElementRef ref) {
|
SetFillMode SetFillMode_read(SetFillModeRef ref) {
|
||||||
return scene[ref.offset >> 2];
|
uint ix = ref.offset >> 2;
|
||||||
|
uint raw0 = scene[ix + 0];
|
||||||
|
SetFillMode s;
|
||||||
|
s.fill_mode = raw0;
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
LineSeg Element_StrokeLine_read(ElementRef ref) {
|
ElementTag Element_tag(ElementRef ref) {
|
||||||
|
uint tag_and_flags = scene[ref.offset >> 2];
|
||||||
|
return ElementTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeg Element_Line_read(ElementRef ref) {
|
||||||
return LineSeg_read(LineSegRef(ref.offset + 4));
|
return LineSeg_read(LineSegRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
LineSeg Element_FillLine_read(ElementRef ref) {
|
QuadSeg Element_Quad_read(ElementRef ref) {
|
||||||
return LineSeg_read(LineSegRef(ref.offset + 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
QuadSeg Element_StrokeQuad_read(ElementRef ref) {
|
|
||||||
return QuadSeg_read(QuadSegRef(ref.offset + 4));
|
return QuadSeg_read(QuadSegRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
QuadSeg Element_FillQuad_read(ElementRef ref) {
|
CubicSeg Element_Cubic_read(ElementRef ref) {
|
||||||
return QuadSeg_read(QuadSegRef(ref.offset + 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
CubicSeg Element_StrokeCubic_read(ElementRef ref) {
|
|
||||||
return CubicSeg_read(CubicSegRef(ref.offset + 4));
|
return CubicSeg_read(CubicSegRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
CubicSeg Element_FillCubic_read(ElementRef ref) {
|
FillColor Element_FillColor_read(ElementRef ref) {
|
||||||
return CubicSeg_read(CubicSegRef(ref.offset + 4));
|
return FillColor_read(FillColorRef(ref.offset + 4));
|
||||||
}
|
|
||||||
|
|
||||||
Stroke Element_Stroke_read(ElementRef ref) {
|
|
||||||
return Stroke_read(StrokeRef(ref.offset + 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
Fill Element_Fill_read(ElementRef ref) {
|
|
||||||
return Fill_read(FillRef(ref.offset + 4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLineWidth Element_SetLineWidth_read(ElementRef ref) {
|
SetLineWidth Element_SetLineWidth_read(ElementRef ref) {
|
||||||
@@ -320,3 +307,7 @@ FillImage Element_FillImage_read(ElementRef ref) {
|
|||||||
return FillImage_read(FillImageRef(ref.offset + 4));
|
return FillImage_read(FillImageRef(ref.offset + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetFillMode Element_SetFillMode_read(ElementRef ref) {
|
||||||
|
return SetFillMode_read(SetFillModeRef(ref.offset + 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,3 +37,12 @@ struct Config {
|
|||||||
Alloc anno_alloc;
|
Alloc anno_alloc;
|
||||||
Alloc trans_alloc;
|
Alloc trans_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fill modes.
|
||||||
|
#define MODE_NONZERO 0
|
||||||
|
#define MODE_STROKE 1
|
||||||
|
|
||||||
|
// fill_mode_from_flags extracts the fill mode from tag flags.
|
||||||
|
uint fill_mode_from_flags(uint flags) {
|
||||||
|
return flags & 0x1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,22 +39,21 @@ void main() {
|
|||||||
|
|
||||||
uint tag = Annotated_Nop;
|
uint tag = Annotated_Nop;
|
||||||
if (element_ix < conf.n_elements) {
|
if (element_ix < conf.n_elements) {
|
||||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||||
}
|
}
|
||||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Color:
|
||||||
case Annotated_FillImage:
|
case Annotated_Image:
|
||||||
case Annotated_Stroke:
|
|
||||||
case Annotated_BeginClip:
|
case Annotated_BeginClip:
|
||||||
case Annotated_EndClip:
|
case Annotated_EndClip:
|
||||||
// Note: we take advantage of the fact that fills, strokes, and
|
// Note: we take advantage of the fact that fills, strokes, and
|
||||||
// clips have compatible layout.
|
// clips have compatible layout.
|
||||||
AnnoFill fill = Annotated_Fill_read(conf.anno_alloc, ref);
|
AnnoEndClip clip = Annotated_EndClip_read(conf.anno_alloc, ref);
|
||||||
x0 = int(floor(fill.bbox.x * SX));
|
x0 = int(floor(clip.bbox.x * SX));
|
||||||
y0 = int(floor(fill.bbox.y * SY));
|
y0 = int(floor(clip.bbox.y * SY));
|
||||||
x1 = int(ceil(fill.bbox.z * SX));
|
x1 = int(ceil(clip.bbox.z * SX));
|
||||||
y1 = int(ceil(fill.bbox.w * SY));
|
y1 = int(ceil(clip.bbox.w * SY));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
x0 = clamp(x0, 0, int(conf.width_in_tiles));
|
x0 = clamp(x0, 0, int(conf.width_in_tiles));
|
||||||
|
|||||||
+34
-41
@@ -16,39 +16,40 @@ type Op uint32
|
|||||||
|
|
||||||
type Command [sceneElemSize / 4]uint32
|
type Command [sceneElemSize / 4]uint32
|
||||||
|
|
||||||
const sceneElemSize = 36
|
|
||||||
|
|
||||||
// GPU commands from scene.h
|
// GPU commands from scene.h
|
||||||
const (
|
const (
|
||||||
OpNop Op = iota
|
OpNop Op = iota
|
||||||
OpStrokeLine
|
OpLine
|
||||||
OpFillLine
|
OpQuad
|
||||||
OpStrokeQuad
|
OpCubic
|
||||||
OpFillQuad
|
OpFillColor
|
||||||
OpStrokeCubic
|
|
||||||
OpFillCubic
|
|
||||||
OpStroke
|
|
||||||
OpFill
|
|
||||||
OpLineWidth
|
OpLineWidth
|
||||||
OpTransform
|
OpTransform
|
||||||
OpBeginClip
|
OpBeginClip
|
||||||
OpEndClip
|
OpEndClip
|
||||||
OpFillImage
|
OpFillImage
|
||||||
|
OpSetFillMode
|
||||||
|
)
|
||||||
|
|
||||||
|
// FillModes, from setup.h.
|
||||||
|
type FillMode uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
FillModeNonzero = 0
|
||||||
|
FillModeStroke = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
const CommandSize = int(unsafe.Sizeof(Command{}))
|
const CommandSize = int(unsafe.Sizeof(Command{}))
|
||||||
|
|
||||||
|
const sceneElemSize = 36
|
||||||
|
|
||||||
func (c Command) Op() Op {
|
func (c Command) Op() Op {
|
||||||
return Op(c[0])
|
return Op(c[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Line(start, end f32.Point, stroke bool) Command {
|
func Line(start, end f32.Point) Command {
|
||||||
tag := uint32(OpFillLine)
|
|
||||||
if stroke {
|
|
||||||
tag = uint32(OpStrokeLine)
|
|
||||||
}
|
|
||||||
return Command{
|
return Command{
|
||||||
0: tag,
|
0: uint32(OpLine),
|
||||||
1: math.Float32bits(start.X),
|
1: math.Float32bits(start.X),
|
||||||
2: math.Float32bits(start.Y),
|
2: math.Float32bits(start.Y),
|
||||||
3: math.Float32bits(end.X),
|
3: math.Float32bits(end.X),
|
||||||
@@ -56,13 +57,9 @@ func Line(start, end f32.Point, stroke bool) Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Cubic(start, ctrl0, ctrl1, end f32.Point, stroke bool) Command {
|
func Cubic(start, ctrl0, ctrl1, end f32.Point) Command {
|
||||||
tag := uint32(OpFillCubic)
|
|
||||||
if stroke {
|
|
||||||
tag = uint32(OpStrokeCubic)
|
|
||||||
}
|
|
||||||
return Command{
|
return Command{
|
||||||
0: tag,
|
0: uint32(OpCubic),
|
||||||
1: math.Float32bits(start.X),
|
1: math.Float32bits(start.X),
|
||||||
2: math.Float32bits(start.Y),
|
2: math.Float32bits(start.Y),
|
||||||
3: math.Float32bits(ctrl0.X),
|
3: math.Float32bits(ctrl0.X),
|
||||||
@@ -74,13 +71,9 @@ func Cubic(start, ctrl0, ctrl1, end f32.Point, stroke bool) Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Quad(start, ctrl, end f32.Point, stroke bool) Command {
|
func Quad(start, ctrl, end f32.Point) Command {
|
||||||
tag := uint32(OpFillQuad)
|
|
||||||
if stroke {
|
|
||||||
tag = uint32(OpStrokeQuad)
|
|
||||||
}
|
|
||||||
return Command{
|
return Command{
|
||||||
0: tag,
|
0: uint32(OpQuad),
|
||||||
1: math.Float32bits(start.X),
|
1: math.Float32bits(start.X),
|
||||||
2: math.Float32bits(start.Y),
|
2: math.Float32bits(start.Y),
|
||||||
3: math.Float32bits(ctrl.X),
|
3: math.Float32bits(ctrl.X),
|
||||||
@@ -103,20 +96,13 @@ func Transform(m f32.Affine2D) Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LineWidth(width float32) Command {
|
func SetLineWidth(width float32) Command {
|
||||||
return Command{
|
return Command{
|
||||||
0: uint32(OpLineWidth),
|
0: uint32(OpLineWidth),
|
||||||
1: math.Float32bits(width),
|
1: math.Float32bits(width),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stroke(col color.RGBA) Command {
|
|
||||||
return Command{
|
|
||||||
0: uint32(OpStroke),
|
|
||||||
1: uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BeginClip(bbox f32.Rectangle) Command {
|
func BeginClip(bbox f32.Rectangle) Command {
|
||||||
return Command{
|
return Command{
|
||||||
0: uint32(OpBeginClip),
|
0: uint32(OpBeginClip),
|
||||||
@@ -137,9 +123,9 @@ func EndClip(bbox f32.Rectangle) Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fill(col color.RGBA) Command {
|
func FillColor(col color.RGBA) Command {
|
||||||
return Command{
|
return Command{
|
||||||
0: uint32(OpFill),
|
0: uint32(OpFillColor),
|
||||||
1: uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A),
|
1: uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,8 +137,15 @@ func FillImage(index int) Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetFillMode(mode FillMode) Command {
|
||||||
|
return Command{
|
||||||
|
0: uint32(OpSetFillMode),
|
||||||
|
1: uint32(mode),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func DecodeLine(cmd Command) (from, to f32.Point) {
|
func DecodeLine(cmd Command) (from, to f32.Point) {
|
||||||
if cmd[0] != uint32(OpFillLine) {
|
if cmd[0] != uint32(OpLine) {
|
||||||
panic("invalid command")
|
panic("invalid command")
|
||||||
}
|
}
|
||||||
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
||||||
@@ -161,7 +154,7 @@ func DecodeLine(cmd Command) (from, to f32.Point) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DecodeQuad(cmd Command) (from, ctrl, to f32.Point) {
|
func DecodeQuad(cmd Command) (from, ctrl, to f32.Point) {
|
||||||
if cmd[0] != uint32(OpFillQuad) {
|
if cmd[0] != uint32(OpQuad) {
|
||||||
panic("invalid command")
|
panic("invalid command")
|
||||||
}
|
}
|
||||||
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
||||||
@@ -171,7 +164,7 @@ func DecodeQuad(cmd Command) (from, ctrl, to f32.Point) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DecodeCubic(cmd Command) (from, ctrl0, ctrl1, to f32.Point) {
|
func DecodeCubic(cmd Command) (from, ctrl0, ctrl1, to f32.Point) {
|
||||||
if cmd[0] != uint32(OpFillCubic) {
|
if cmd[0] != uint32(OpCubic) {
|
||||||
panic("invalid command")
|
panic("invalid command")
|
||||||
}
|
}
|
||||||
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
from = f32.Pt(math.Float32frombits(cmd[1]), math.Float32frombits(cmd[2]))
|
||||||
|
|||||||
+3
-3
@@ -141,7 +141,7 @@ func (p *Path) LineTo(to f32.Point) {
|
|||||||
data := p.ops.Write(scene.CommandSize + 4)
|
data := p.ops.Write(scene.CommandSize + 4)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(data[0:], uint32(p.contour))
|
bo.PutUint32(data[0:], uint32(p.contour))
|
||||||
ops.EncodeCommand(data[4:], scene.Line(p.pen, to, false))
|
ops.EncodeCommand(data[4:], scene.Line(p.pen, to))
|
||||||
p.pen = to
|
p.pen = to
|
||||||
p.hasSegments = true
|
p.hasSegments = true
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ func (p *Path) QuadTo(ctrl, to f32.Point) {
|
|||||||
data := p.ops.Write(scene.CommandSize + 4)
|
data := p.ops.Write(scene.CommandSize + 4)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(data[0:], uint32(p.contour))
|
bo.PutUint32(data[0:], uint32(p.contour))
|
||||||
ops.EncodeCommand(data[4:], scene.Quad(p.pen, ctrl, to, false))
|
ops.EncodeCommand(data[4:], scene.Quad(p.pen, ctrl, to))
|
||||||
p.pen = to
|
p.pen = to
|
||||||
p.hasSegments = true
|
p.hasSegments = true
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,7 @@ func (p *Path) CubeTo(ctrl0, ctrl1, to f32.Point) {
|
|||||||
data := p.ops.Write(scene.CommandSize + 4)
|
data := p.ops.Write(scene.CommandSize + 4)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(data[0:], uint32(p.contour))
|
bo.PutUint32(data[0:], uint32(p.contour))
|
||||||
ops.EncodeCommand(data[4:], scene.Cubic(p.pen, ctrl0, ctrl1, to, false))
|
ops.EncodeCommand(data[4:], scene.Cubic(p.pen, ctrl0, ctrl1, to))
|
||||||
p.pen = to
|
p.pen = to
|
||||||
p.hasSegments = true
|
p.hasSegments = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user