// SPDX-License-Identifier: Unlicense OR MIT // Shader source types and GLSL constants. // Vendored from gioui.org/shader v1.0.8 - GLSL100ES only. package gio // ShaderSources holds the GLSL sources and reflection data for a shader. type ShaderSources struct { Name string GLSL100ES string GLSL150 string Uniforms ShaderUniformsReflection Inputs []ShaderInputLocation Textures []ShaderTextureBinding } type ShaderUniformsReflection struct { Locations []ShaderUniformLocation Size int } type ShaderTextureBinding struct { Name string Binding int } type ShaderUniformLocation struct { Name string Type ShaderDataType Size int Offset int } type ShaderInputLocation struct { Name string Location int Type ShaderDataType Size int } type ShaderDataType uint8 const ( ShaderDataTypeFloat ShaderDataType = iota ShaderDataTypeInt ShaderDataTypeShort ) // --- Vendored GLSL100ES shader sources for Gio stencil-and-cover pipeline --- func ShaderBlitVert() ShaderSources { return ShaderSources{ Name: "blit.vert", Inputs: []ShaderInputLocation{ {Name: "pos", Location: 0, Type: 0x0, Size: 2}, {Name: "uv", Location: 1, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_block.transform", Type: 0x0, Size: 4, Offset: 0}, {Name: "_block.uvTransformR1", Type: 0x0, Size: 4, Offset: 16}, {Name: "_block.uvTransformR2", Type: 0x0, Size: 4, Offset: 32}, {Name: "_block.opacity", Type: 0x0, Size: 1, Offset: 48}, {Name: "_block.fbo", Type: 0x0, Size: 1, Offset: 52}, }, Size: 56, }, GLSL100ES: ` #version 100 struct m3x2 { vec3 r0; vec3 r1; }; struct Block { vec4 transform; vec4 uvTransformR1; vec4 uvTransformR2; float opacity; float fbo; }; uniform Block _block; attribute vec2 pos; varying vec2 vUV; attribute vec2 uv; varying float opacity; vec3 transform3x2(m3x2 t, vec3 v) { return vec3(dot(t.r0, v), dot(t.r1, v), dot(vec3(0.0, 0.0, 1.0), v)); } void main() { vec2 p = (pos * _block.transform.xy) + _block.transform.zw; if (_block.fbo != 0.0) { m3x2 param = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0)); gl_Position = vec4(transform3x2(param, vec3(p, 0.0)), 1.0); } else { m3x2 param2 = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0)); gl_Position = vec4(transform3x2(param2, vec3(p, 0.0)), 1.0); } m3x2 param3 = m3x2(_block.uvTransformR1.xyz, _block.uvTransformR2.xyz); vUV = transform3x2(param3, vec3(uv, 1.0)).xy; opacity = _block.opacity; } `, } } func ShaderBlitFrag() [3]ShaderSources { return [3]ShaderSources{ { Name: "blit.frag", Inputs: []ShaderInputLocation{ {Name: "vUV", Location: 0, Type: 0x0, Size: 2}, {Name: "opacity", Location: 1, Type: 0x0, Size: 1}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_color.color", Type: 0x0, Size: 4, Offset: 112}, }, Size: 16, }, GLSL100ES: ` #version 100 precision mediump float; precision highp int; struct Color { vec4 color; }; uniform Color _color; varying highp float opacity; varying highp vec2 vUV; void main() { gl_FragData[0] = _color.color * opacity; } `, }, { Name: "blit.frag", Inputs: []ShaderInputLocation{ {Name: "vUV", Location: 0, Type: 0x0, Size: 2}, {Name: "opacity", Location: 1, Type: 0x0, Size: 1}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_gradient.color1", Type: 0x0, Size: 4, Offset: 96}, {Name: "_gradient.color2", Type: 0x0, Size: 4, Offset: 112}, }, Size: 32, }, GLSL100ES: ` #version 100 precision mediump float; precision highp int; struct Gradient { vec4 color1; vec4 color2; }; uniform Gradient _gradient; varying highp float opacity; varying highp vec2 vUV; void main() { gl_FragData[0] = mix(_gradient.color1, _gradient.color2, vec4(clamp(vUV.x, 0.0, 1.0))) * opacity; } `, }, { Name: "blit.frag", Inputs: []ShaderInputLocation{ {Name: "vUV", Location: 0, Type: 0x0, Size: 2}, {Name: "opacity", Location: 1, Type: 0x0, Size: 1}, }, Textures: []ShaderTextureBinding{{Name: "tex", Binding: 0}}, GLSL100ES: ` #version 100 precision mediump float; precision highp int; uniform mediump sampler2D tex; varying highp float opacity; varying highp vec2 vUV; void main() { gl_FragData[0] = texture2D(tex, vUV) * opacity; } `, }, } } func ShaderCoverVert() ShaderSources { return ShaderSources{ Name: "cover.vert", Inputs: []ShaderInputLocation{ {Name: "pos", Location: 0, Type: 0x0, Size: 2}, {Name: "uv", Location: 1, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_block.transform", Type: 0x0, Size: 4, Offset: 0}, {Name: "_block.uvCoverTransform", Type: 0x0, Size: 4, Offset: 16}, {Name: "_block.uvTransformR1", Type: 0x0, Size: 4, Offset: 32}, {Name: "_block.uvTransformR2", Type: 0x0, Size: 4, Offset: 48}, {Name: "_block.fbo", Type: 0x0, Size: 1, Offset: 64}, }, Size: 68, }, GLSL100ES: ` #version 100 struct m3x2 { vec3 r0; vec3 r1; }; struct Block { vec4 transform; vec4 uvCoverTransform; vec4 uvTransformR1; vec4 uvTransformR2; float fbo; }; uniform Block _block; attribute vec2 pos; varying vec2 vUV; attribute vec2 uv; varying vec2 vCoverUV; vec3 transform3x2(m3x2 t, vec3 v) { return vec3(dot(t.r0, v), dot(t.r1, v), dot(vec3(0.0, 0.0, 1.0), v)); } void main() { vec2 p = vec2((pos * _block.transform.xy) + _block.transform.zw); if (_block.fbo != 0.0) { m3x2 param = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0)); gl_Position = vec4(transform3x2(param, vec3(p, 0.0)), 1.0); } else { m3x2 param2 = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0)); gl_Position = vec4(transform3x2(param2, vec3(p, 0.0)), 1.0); } m3x2 param3 = m3x2(_block.uvTransformR1.xyz, _block.uvTransformR2.xyz); vUV = transform3x2(param3, vec3(uv, 1.0)).xy; vec3 uv3 = vec3(uv, 1.0); vCoverUV = ((uv3 * vec3(_block.uvCoverTransform.xy, 1.0)) + vec3(_block.uvCoverTransform.zw, 0.0)).xy; } `, } } func ShaderCoverFrag() [3]ShaderSources { return [3]ShaderSources{ { Name: "cover.frag", Inputs: []ShaderInputLocation{ {Name: "vCoverUV", Location: 0, Type: 0x0, Size: 2}, {Name: "vUV", Location: 1, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_color.color", Type: 0x0, Size: 4, Offset: 112}, }, Size: 16, }, Textures: []ShaderTextureBinding{{Name: "cover", Binding: 1}}, GLSL100ES: ` #version 100 precision mediump float; precision highp int; struct Color { vec4 color; }; uniform Color _color; uniform mediump sampler2D cover; varying highp vec2 vCoverUV; varying highp vec2 vUV; void main() { gl_FragData[0] = _color.color; float c = min(abs(texture2D(cover, vCoverUV).x), 1.0); gl_FragData[0] *= c; } `, }, { Name: "cover.frag", Inputs: []ShaderInputLocation{ {Name: "vCoverUV", Location: 0, Type: 0x0, Size: 2}, {Name: "vUV", Location: 1, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_gradient.color1", Type: 0x0, Size: 4, Offset: 96}, {Name: "_gradient.color2", Type: 0x0, Size: 4, Offset: 112}, }, Size: 32, }, Textures: []ShaderTextureBinding{{Name: "cover", Binding: 1}}, GLSL100ES: ` #version 100 precision mediump float; precision highp int; struct Gradient { vec4 color1; vec4 color2; }; uniform Gradient _gradient; uniform mediump sampler2D cover; varying highp vec2 vUV; varying highp vec2 vCoverUV; void main() { gl_FragData[0] = mix(_gradient.color1, _gradient.color2, vec4(clamp(vUV.x, 0.0, 1.0))); float c = min(abs(texture2D(cover, vCoverUV).x), 1.0); gl_FragData[0] *= c; } `, }, { Name: "cover.frag", Inputs: []ShaderInputLocation{ {Name: "vCoverUV", Location: 0, Type: 0x0, Size: 2}, {Name: "vUV", Location: 1, Type: 0x0, Size: 2}, }, Textures: []ShaderTextureBinding{ {Name: "tex", Binding: 0}, {Name: "cover", Binding: 1}, }, GLSL100ES: ` #version 100 precision mediump float; precision highp int; uniform mediump sampler2D tex; uniform mediump sampler2D cover; varying highp vec2 vUV; varying highp vec2 vCoverUV; void main() { gl_FragData[0] = texture2D(tex, vUV); float c = min(abs(texture2D(cover, vCoverUV).x), 1.0); gl_FragData[0] *= c; } `, }, } } func ShaderStencilVert() ShaderSources { return ShaderSources{ Name: "stencil.vert", Inputs: []ShaderInputLocation{ {Name: "corner", Location: 0, Type: 0x0, Size: 1}, {Name: "maxy", Location: 1, Type: 0x0, Size: 1}, {Name: "from", Location: 2, Type: 0x0, Size: 2}, {Name: "ctrl", Location: 3, Type: 0x0, Size: 2}, {Name: "to", Location: 4, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_block.transform", Type: 0x0, Size: 4, Offset: 0}, {Name: "_block.pathOffset", Type: 0x0, Size: 2, Offset: 16}, }, Size: 24, }, GLSL100ES: ` #version 100 struct m3x2 { vec3 r0; vec3 r1; }; struct Block { vec4 transform; vec2 pathOffset; }; uniform Block _block; attribute float corner; attribute float maxy; attribute vec2 from; attribute vec2 ctrl; attribute vec2 to; varying vec2 vFrom; varying vec2 vCtrl; varying vec2 vTo; vec3 transform3x2(m3x2 t, vec3 v) { return vec3(dot(t.r0, v), dot(t.r1, v), dot(vec3(0.0, 0.0, 1.0), v)); } void main() { vec2 from1 = from + _block.pathOffset; vec2 ctrl1 = ctrl + _block.pathOffset; vec2 to1 = to + _block.pathOffset; float maxy1 = maxy + _block.pathOffset.y; float c = corner; vec2 pos; if (c >= 0.375) { c -= 0.5; pos.y = maxy1 + 1.0; } else { pos.y = min(min(from1.y, ctrl1.y), to1.y) - 1.0; } if (c >= 0.125) { pos.x = max(max(from1.x, ctrl1.x), to1.x) + 1.0; } else { pos.x = min(min(from1.x, ctrl1.x), to1.x) - 1.0; } vFrom = from1 - pos; vCtrl = ctrl1 - pos; vTo = to1 - pos; pos = (pos * _block.transform.xy) + _block.transform.zw; m3x2 param = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0)); gl_Position = vec4(transform3x2(param, vec3(pos, 0.0)), 1.0); } `, } } func ShaderStencilFrag() ShaderSources { return ShaderSources{ Name: "stencil.frag", Inputs: []ShaderInputLocation{ {Name: "vFrom", Location: 0, Type: 0x0, Size: 2}, {Name: "vCtrl", Location: 1, Type: 0x0, Size: 2}, {Name: "vTo", Location: 2, Type: 0x0, Size: 2}, }, GLSL100ES: ` #version 100 precision mediump float; precision highp int; varying highp vec2 vTo; varying highp vec2 vFrom; varying highp vec2 vCtrl; void main() { float dx = vTo.x - vFrom.x; bool increasing = vTo.x >= vFrom.x; bvec2 _35 = bvec2(increasing); vec2 left = vec2(_35.x ? vFrom.x : vTo.x, _35.y ? vFrom.y : vTo.y); bvec2 _41 = bvec2(increasing); vec2 right = vec2(_41.x ? vTo.x : vFrom.x, _41.y ? vTo.y : vFrom.y); vec2 extent = clamp(vec2(vFrom.x, vTo.x), vec2(-0.5), vec2(0.5)); float midx = mix(extent.x, extent.y, 0.5); float x0 = midx - left.x; vec2 p1 = vCtrl - left; vec2 v = right - vCtrl; float t = x0 / (p1.x + sqrt((p1.x * p1.x) + ((v.x - p1.x) * x0))); float y = mix(mix(left.y, vCtrl.y, t), mix(vCtrl.y, right.y, t), t); vec2 d_half = mix(p1, v, vec2(t)); float dy = d_half.y / d_half.x; float width = extent.y - extent.x; dy = abs(dy * width); vec4 sides = vec4((dy * 0.5) + y, (dy * (-0.5)) + y, (0.5 - y) / dy, ((-0.5) - y) / dy); sides = clamp(sides + vec4(0.5), vec4(0.0), vec4(1.0)); float area = 0.5 * ((((sides.z - (sides.z * sides.y)) + 1.0) - sides.x) + (sides.x * sides.w)); area *= width; if (width == 0.0) { area = 0.0; } gl_FragData[0].x = area; } `, } } func ShaderIntersectVert() ShaderSources { return ShaderSources{ Name: "intersect.vert", Inputs: []ShaderInputLocation{ {Name: "pos", Location: 0, Type: 0x0, Size: 2}, {Name: "uv", Location: 1, Type: 0x0, Size: 2}, }, Uniforms: ShaderUniformsReflection{ Locations: []ShaderUniformLocation{ {Name: "_block.uvTransform", Type: 0x0, Size: 4, Offset: 0}, {Name: "_block.subUVTransform", Type: 0x0, Size: 4, Offset: 16}, }, Size: 32, }, GLSL100ES: ` #version 100 struct m3x2 { vec3 r0; vec3 r1; }; struct Block { vec4 uvTransform; vec4 subUVTransform; }; uniform Block _block; attribute vec2 pos; varying vec2 vUV; attribute vec2 uv; vec3 transform3x2(m3x2 t, vec3 v) { return vec3(dot(t.r0, v), dot(t.r1, v), dot(vec3(0.0, 0.0, 1.0), v)); } void main() { m3x2 param = m3x2(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0)); vec3 p = transform3x2(param, vec3(pos, 1.0)); gl_Position = vec4(p, 1.0); vUV = (uv * _block.subUVTransform.xy) + _block.subUVTransform.zw; vUV = (vUV * _block.uvTransform.xy) + _block.uvTransform.zw; } `, } } func ShaderIntersectFrag() ShaderSources { return ShaderSources{ Name: "intersect.frag", Inputs: []ShaderInputLocation{ {Name: "vUV", Location: 0, Type: 0x0, Size: 2}, }, Textures: []ShaderTextureBinding{{Name: "cover", Binding: 0}}, GLSL100ES: ` #version 100 precision mediump float; precision highp int; uniform mediump sampler2D cover; varying highp vec2 vUV; void main() { gl_FragData[0].x = abs(texture2D(cover, vUV).x); } `, } }