Skip to content

Commit

Permalink
gpu: add radial-gradient material
Browse files Browse the repository at this point in the history
Signed-off-by: Egon Elbre <[email protected]>
  • Loading branch information
egonelbre committed Mar 7, 2021
1 parent 5a43a6b commit 82f63d2
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
3 changes: 3 additions & 0 deletions gpu/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,9 @@ func (g *compute) encodeOps(trans f32.Affine2D, viewport image.Point, ops []imag
case materialLinearGradient:
// TODO: implement.
g.enc.fill(f32color.NRGBAToRGBA(op.material.color1.SRGB()))
case materialRadialGradient:
// TODO: implement.
g.enc.fill(f32color.NRGBAToRGBA(op.material.color1.SRGB()))
default:
panic("not implemented")
}
Expand Down
34 changes: 34 additions & 0 deletions gpu/gpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ type blitter struct {
colUniforms *blitColUniforms
texUniforms *blitTexUniforms
linearGradientUniforms *blitLinearGradientUniforms
radialGradientUniforms *blitRadialGradientUniforms
quadVerts driver.Buffer
}

Expand Down Expand Up @@ -343,6 +344,16 @@ type blitLinearGradientUniforms struct {
}
}

type blitRadialGradientUniforms struct {
vert struct {
blitUniforms
_ [12]byte // Padding to a multiple of 16.
}
frag struct {
gradientUniforms
}
}

type uniformBuffer struct {
buf driver.Buffer
ptr []byte
Expand Down Expand Up @@ -381,6 +392,7 @@ const (
const (
materialColor materialType = iota
materialLinearGradient
materialRadialGradient
materialTexture
materialCount
)
Expand Down Expand Up @@ -578,16 +590,19 @@ func newBlitter(ctx driver.Device) *blitter {
b.colUniforms = new(blitColUniforms)
b.texUniforms = new(blitTexUniforms)
b.linearGradientUniforms = new(blitLinearGradientUniforms)
b.radialGradientUniforms = new(blitRadialGradientUniforms)

prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag,
[...]interface{}{
materialColor: &b.colUniforms.vert,
materialLinearGradient: &b.linearGradientUniforms.vert,
materialRadialGradient: &b.radialGradientUniforms.vert,
materialTexture: &b.texUniforms.vert,
},
[...]interface{}{
materialColor: &b.colUniforms.frag,
materialLinearGradient: &b.linearGradientUniforms.frag,
materialRadialGradient: &b.radialGradientUniforms.frag,
materialTexture: nil,
},
)
Expand Down Expand Up @@ -1071,6 +1086,14 @@ func (d *drawState) materialFor(rect f32.Rectangle, off f32.Point, partTrans f32
m.color2 = f32color.LinearFromSRGB(d.color2)
m.opaque = m.color1.A == 1.0 && m.color2.A == 1.0

m.uvTrans = partTrans.Mul(gradientSpaceTransform(clip, off, d.stop1, d.stop2))
case materialRadialGradient:
m.material = materialRadialGradient

m.color1 = f32color.LinearFromSRGB(d.color1)
m.color2 = f32color.LinearFromSRGB(d.color2)
m.opaque = m.color1.A == 1.0 && m.color2.A == 1.0

m.uvTrans = partTrans.Mul(gradientSpaceTransform(clip, off, d.stop1, d.stop2))
case materialTexture:
m.material = materialTexture
Expand Down Expand Up @@ -1166,11 +1189,13 @@ func (b *blitter) blit(z float32, mat materialType, col f32color.RGBA, col1, col
case materialColor:
b.colUniforms.frag.color = col
uniforms = &b.colUniforms.vert.blitUniforms

case materialTexture:
t1, t2, t3, t4, t5, t6 := uvTrans.Elems()
b.texUniforms.vert.blitUniforms.uvTransformR1 = [4]float32{t1, t2, t3, 0}
b.texUniforms.vert.blitUniforms.uvTransformR2 = [4]float32{t4, t5, t6, 0}
uniforms = &b.texUniforms.vert.blitUniforms

case materialLinearGradient:
b.linearGradientUniforms.frag.color1 = col1
b.linearGradientUniforms.frag.color2 = col2
Expand All @@ -1179,6 +1204,15 @@ func (b *blitter) blit(z float32, mat materialType, col f32color.RGBA, col1, col
b.linearGradientUniforms.vert.blitUniforms.uvTransformR1 = [4]float32{t1, t2, t3, 0}
b.linearGradientUniforms.vert.blitUniforms.uvTransformR2 = [4]float32{t4, t5, t6, 0}
uniforms = &b.linearGradientUniforms.vert.blitUniforms

case materialRadialGradient:
b.radialGradientUniforms.frag.color1 = col1
b.radialGradientUniforms.frag.color2 = col2

t1, t2, t3, t4, t5, t6 := uvTrans.Elems()
b.radialGradientUniforms.vert.blitUniforms.uvTransformR1 = [4]float32{t1, t2, t3, 0}
b.radialGradientUniforms.vert.blitUniforms.uvTransformR2 = [4]float32{t4, t5, t6, 0}
uniforms = &b.radialGradientUniforms.vert.blitUniforms
}
uniforms.z = z
uniforms.transform = [4]float32{scale.X, scale.Y, off.X, off.Y}
Expand Down
4 changes: 4 additions & 0 deletions gpu/internal/convertshaders/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ func (conv *Converter) Shader(shaderPath string) ([]driver.ShaderSources, error)
FetchColorExpr: `mix(_color1, _color2, clamp(vUV.x, 0.0, 1.0))`,
Header: `layout(binding=0) uniform Gradient { vec4 _color1; vec4 _color2; };`,
},
{
FetchColorExpr: `mix(_color1, _color2, clamp(length(vUV), 0.0, 1.0))`,
Header: `layout(binding=0) uniform Gradient { vec4 _color1; vec4 _color2; };`,
},
{
FetchColorExpr: `texture(tex, vUV)`,
Header: `layout(binding=0) uniform sampler2D tex;`,
Expand Down
28 changes: 28 additions & 0 deletions gpu/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type coverer struct {
texUniforms *coverTexUniforms
colUniforms *coverColUniforms
linearGradientUniforms *coverLinearGradientUniforms
radialGradientUniforms *coverRadialGradientUniforms
layout driver.InputLayout
}

Expand Down Expand Up @@ -62,6 +63,16 @@ type coverLinearGradientUniforms struct {
}
}

type coverRadialGradientUniforms struct {
vert struct {
coverUniforms
_ [12]byte // Padding to multiple of 16.
}
frag struct {
gradientUniforms
}
}

type coverUniforms struct {
transform [4]float32
uvCoverTransform [4]float32
Expand Down Expand Up @@ -158,24 +169,30 @@ func newCoverer(ctx driver.Device) *coverer {
c := &coverer{
ctx: ctx,
}

c.colUniforms = new(coverColUniforms)
c.texUniforms = new(coverTexUniforms)
c.linearGradientUniforms = new(coverLinearGradientUniforms)
c.radialGradientUniforms = new(coverRadialGradientUniforms)

prog, layout, err := createColorPrograms(ctx, shader_cover_vert, shader_cover_frag,
[materialCount]interface{}{
materialColor: &c.colUniforms.vert,
materialLinearGradient: &c.linearGradientUniforms.vert,
materialRadialGradient: &c.radialGradientUniforms.vert,
materialTexture: &c.texUniforms.vert,
},
[materialCount]interface{}{
materialColor: &c.colUniforms.frag,
materialLinearGradient: &c.linearGradientUniforms.frag,
materialRadialGradient: &c.radialGradientUniforms.frag,
materialTexture: nil,
},
)
if err != nil {
panic(err)
}

c.prog = prog
c.layout = layout
return c
Expand Down Expand Up @@ -394,6 +411,7 @@ func (c *coverer) cover(z float32, mat materialType, col f32color.RGBA, col1, co
case materialColor:
c.colUniforms.frag.color = col
uniforms = &c.colUniforms.vert.coverUniforms

case materialLinearGradient:
c.linearGradientUniforms.frag.color1 = col1
c.linearGradientUniforms.frag.color2 = col2
Expand All @@ -402,6 +420,16 @@ func (c *coverer) cover(z float32, mat materialType, col f32color.RGBA, col1, co
c.linearGradientUniforms.vert.uvTransformR1 = [4]float32{t1, t2, t3, 0}
c.linearGradientUniforms.vert.uvTransformR2 = [4]float32{t4, t5, t6, 0}
uniforms = &c.linearGradientUniforms.vert.coverUniforms

case materialRadialGradient:
c.radialGradientUniforms.frag.color1 = col1
c.radialGradientUniforms.frag.color2 = col2

t1, t2, t3, t4, t5, t6 := uvTrans.Elems()
c.radialGradientUniforms.vert.uvTransformR1 = [4]float32{t1, t2, t3, 0}
c.radialGradientUniforms.vert.uvTransformR2 = [4]float32{t4, t5, t6, 0}
uniforms = &c.radialGradientUniforms.vert.coverUniforms

case materialTexture:
t1, t2, t3, t4, t5, t6 := uvTrans.Elems()
c.texUniforms.vert.uvTransformR1 = [4]float32{t1, t2, t3, 0}
Expand Down
Loading

0 comments on commit 82f63d2

Please sign in to comment.