Skip to content

Commit

Permalink
gpu,op/paint: add Offset1 to RadialGradient
Browse files Browse the repository at this point in the history
  • Loading branch information
egonelbre committed Mar 8, 2021
1 parent 2ae1967 commit 118fba5
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 26 deletions.
24 changes: 19 additions & 5 deletions gpu/gpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ type drawState struct {
color1 color.NRGBA
color2 color.NRGBA
// Current paint.RadialGradientOp.
offset1 float32
radiusy float32
}

Expand Down Expand Up @@ -193,6 +194,7 @@ type material struct {
color1 f32color.RGBA
color2 f32color.RGBA
// For materialTypeRadialGradient.
offset1 float32
radiusy float32
// For materialTypeTexture.
data imageOpData
Expand Down Expand Up @@ -227,6 +229,7 @@ type radialGradientOpData struct {
stop1 f32.Point
stop2 f32.Point

offset1 float32
radiusy float32

color1 color.NRGBA
Expand Down Expand Up @@ -336,6 +339,7 @@ func decodeRadialGradientOp(data []byte) radialGradientOpData {
B: data[25+2],
A: data[25+3],
},
offset1: math.Float32frombits(bo.Uint32(data[29:])),
}
}

Expand Down Expand Up @@ -395,7 +399,8 @@ type blitRadialGradientUniforms struct {
_ [12]byte // Padding to a multiple of 16.
}
frag struct {
gradientUniforms
radialGradientUniforms
_ [12]byte // Padding to multiple of 16.
}
}

Expand Down Expand Up @@ -426,6 +431,12 @@ type gradientUniforms struct {
color2 f32color.RGBA
}

type radialGradientUniforms struct {
color1 f32color.RGBA
color2 f32color.RGBA
offset1 float32
}

type materialType uint8

const (
Expand Down Expand Up @@ -1025,6 +1036,7 @@ loop:
op := decodeRadialGradientOp(encOp.Data)
state.stop1 = op.stop1
state.stop2 = op.stop2
state.offset1 = op.offset1
state.radiusy = op.radiusy
state.color1 = op.color1
state.color2 = op.color2
Expand Down Expand Up @@ -1145,6 +1157,7 @@ func (d *drawState) materialFor(rect f32.Rectangle, off f32.Point, partTrans f32

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

m.uvTrans = partTrans.Mul(gradientSpaceTransform(clip, off, d.stop1, d.stop2, d.radiusy))
Expand Down Expand Up @@ -1188,7 +1201,7 @@ func (r *renderer) drawZOps(cache *resourceCache, ops []imageOp) {
}
drc := img.clip
scale, off := clipSpaceTransform(drc, r.blitter.viewport)
r.blitter.blit(img.z, m.material, m.color, m.color1, m.color2, scale, off, m.uvTrans)
r.blitter.blit(img.z, m.material, m.color, m.color1, m.color2, m.offset1, scale, off, m.uvTrans)
}
r.ctx.SetDepthTest(false)
}
Expand All @@ -1212,7 +1225,7 @@ func (r *renderer) drawOps(cache *resourceCache, ops []imageOp) {
var fbo stencilFBO
switch img.clipType {
case clipTypeNone:
r.blitter.blit(img.z, m.material, m.color, m.color1, m.color2, scale, off, m.uvTrans)
r.blitter.blit(img.z, m.material, m.color, m.color1, m.color2, m.offset1, scale, off, m.uvTrans)
continue
case clipTypePath:
fbo = r.pather.stenciler.cover(img.place.Idx)
Expand All @@ -1228,13 +1241,13 @@ func (r *renderer) drawOps(cache *resourceCache, ops []imageOp) {
Max: img.place.Pos.Add(drc.Size()),
}
coverScale, coverOff := texSpaceTransform(layout.FRect(uv), fbo.size)
r.pather.cover(img.z, m.material, m.color, m.color1, m.color2, scale, off, m.uvTrans, coverScale, coverOff)
r.pather.cover(img.z, m.material, m.color, m.color1, m.color2, m.offset1, scale, off, m.uvTrans, coverScale, coverOff)
}
r.ctx.DepthMask(true)
r.ctx.SetDepthTest(false)
}

func (b *blitter) blit(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, scale, off f32.Point, uvTrans f32.Affine2D) {
func (b *blitter) blit(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, col1off float32, scale, off f32.Point, uvTrans f32.Affine2D) {
p := b.prog[mat]
b.ctx.BindProgram(p.prog)
var uniforms *blitUniforms
Expand All @@ -1261,6 +1274,7 @@ func (b *blitter) blit(z float32, mat materialType, col f32color.RGBA, col1, col
case materialRadialGradient:
b.radialGradientUniforms.frag.color1 = col1
b.radialGradientUniforms.frag.color2 = col2
b.radialGradientUniforms.frag.offset1 = col1off

t1, t2, t3, t4, t5, t6 := uvTrans.Elems()
b.radialGradientUniforms.vert.blitUniforms.uvTransformR1 = [4]float32{t1, t2, t3, 0}
Expand Down
4 changes: 2 additions & 2 deletions gpu/internal/convertshaders/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ func (conv *Converter) Shader(shaderPath string) ([]driver.ShaderSources, error)
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: `mix(_color1, _color2, clamp((length(vUV) - _offset1) / (1.0 - _offset1), 0.0, 1.0))`,
Header: `layout(binding=0) uniform Gradient { vec4 _color1; vec4 _color2; float _offset1; };`,
},
{
FetchColorExpr: `texture(tex, vUV)`,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions gpu/internal/rendertest/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,19 @@ func TestRadialGradient(t *testing.T) {
}, func(r result) {})
}

func TestRadialGradientOffset(t *testing.T) {
run(t, func(ops *op.Ops) {
paint.RadialGradientOp{
Stop1: f32.Pt(64, 64),
Color1: blue,
Stop2: f32.Pt(64, 0),
Color2: black,
Offset1: 0.5,
}.Add(ops)
paint.PaintOp{}.Add(ops)
}, func(r result) {})
}

func TestEllipseGradient(t *testing.T) {
run(t, func(ops *op.Ops) {
paint.RadialGradientOp{
Expand Down
10 changes: 6 additions & 4 deletions gpu/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ type coverRadialGradientUniforms struct {
_ [12]byte // Padding to multiple of 16.
}
frag struct {
gradientUniforms
radialGradientUniforms
_ [12]byte // Padding to multiple of 16.
}
}

Expand Down Expand Up @@ -399,11 +400,11 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima
}
}

func (p *pather) cover(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, scale, off f32.Point, uvTrans f32.Affine2D, coverScale, coverOff f32.Point) {
p.coverer.cover(z, mat, col, col1, col2, scale, off, uvTrans, coverScale, coverOff)
func (p *pather) cover(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, col1off float32, scale, off f32.Point, uvTrans f32.Affine2D, coverScale, coverOff f32.Point) {
p.coverer.cover(z, mat, col, col1, col2, col1off, scale, off, uvTrans, coverScale, coverOff)
}

func (c *coverer) cover(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, scale, off f32.Point, uvTrans f32.Affine2D, coverScale, coverOff f32.Point) {
func (c *coverer) cover(z float32, mat materialType, col f32color.RGBA, col1, col2 f32color.RGBA, col1off float32, scale, off f32.Point, uvTrans f32.Affine2D, coverScale, coverOff f32.Point) {
p := c.prog[mat]
c.ctx.BindProgram(p.prog)
var uniforms *coverUniforms
Expand All @@ -424,6 +425,7 @@ func (c *coverer) cover(z float32, mat materialType, col f32color.RGBA, col1, co
case materialRadialGradient:
c.radialGradientUniforms.frag.color1 = col1
c.radialGradientUniforms.frag.color2 = col2
c.radialGradientUniforms.frag.offset1 = col1off

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

0 comments on commit 118fba5

Please sign in to comment.