mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 09:25:38 +00:00
ui/app/internal/gpu: implement OpenGL ES 2 float fbo fallbacks
Also applicable to WebGL. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -35,6 +35,7 @@ const (
|
|||||||
FRAMEBUFFER_BINDING = 0x8ca6
|
FRAMEBUFFER_BINDING = 0x8ca6
|
||||||
FRAMEBUFFER_COMPLETE = 0x8cd5
|
FRAMEBUFFER_COMPLETE = 0x8cd5
|
||||||
HALF_FLOAT = 0x140b
|
HALF_FLOAT = 0x140b
|
||||||
|
HALF_FLOAT_OES = 0x8d61
|
||||||
GREATER = 0x204
|
GREATER = 0x204
|
||||||
LINEAR = 0x2601
|
LINEAR = 0x2601
|
||||||
LINK_STATUS = 0x8b82
|
LINK_STATUS = 0x8b82
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package gpu
|
package gpu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gioui.org/ui/app/internal/gl"
|
"gioui.org/ui/app/internal/gl"
|
||||||
@@ -14,6 +15,17 @@ type context struct {
|
|||||||
type caps struct {
|
type caps struct {
|
||||||
EXT_disjoint_timer_query bool
|
EXT_disjoint_timer_query bool
|
||||||
srgbMode srgbMode
|
srgbMode srgbMode
|
||||||
|
// floatTriple holds the settings for floating point
|
||||||
|
// textures.
|
||||||
|
floatTriple textureTriple
|
||||||
|
}
|
||||||
|
|
||||||
|
// textureTriple holds the type settings for
|
||||||
|
// a TexImage2D call.
|
||||||
|
type textureTriple struct {
|
||||||
|
internalFormat int
|
||||||
|
format gl.Enum
|
||||||
|
typ gl.Enum
|
||||||
}
|
}
|
||||||
|
|
||||||
type srgbMode uint8
|
type srgbMode uint8
|
||||||
@@ -33,20 +45,42 @@ func newContext(glctx gl.Context) (*context, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
srgbMode, err := srgbModeFor(ver, exts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
floatTriple, err := floatTripleFor(ver, exts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
ctx.caps = caps{
|
ctx.caps = caps{
|
||||||
EXT_disjoint_timer_query: strings.Contains(exts, "GL_EXT_disjoint_timer_query"),
|
EXT_disjoint_timer_query: strings.Contains(exts, "GL_EXT_disjoint_timer_query"),
|
||||||
srgbMode: srgbModeFor(ver, exts),
|
srgbMode: srgbMode,
|
||||||
|
floatTriple: floatTriple,
|
||||||
}
|
}
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func srgbModeFor(ver [2]int, exts string) srgbMode {
|
func floatTripleFor(ver [2]int, exts string) (textureTriple, error) {
|
||||||
switch {
|
switch {
|
||||||
case ver[0] >= 3:
|
case ver[0] >= 3:
|
||||||
return srgbES3
|
return textureTriple{gl.R16F, gl.Enum(gl.RED), gl.Enum(gl.HALF_FLOAT)}, nil
|
||||||
case strings.Contains(exts, "EXT_sRGB"):
|
case strings.Contains(exts, "GL_OES_texture_half_float"):
|
||||||
return srgbEXT
|
return textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.HALF_FLOAT_OES)}, nil
|
||||||
|
case strings.Contains(exts, "GL_OES_texture_float"):
|
||||||
|
return textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.FLOAT)}, nil
|
||||||
default:
|
default:
|
||||||
panic("neither OpenGL ES 3 nor EXT_sRGB is supported")
|
return textureTriple{}, errors.New("floating point texture not supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func srgbModeFor(ver [2]int, exts string) (srgbMode, error) {
|
||||||
|
switch {
|
||||||
|
case ver[0] >= 3:
|
||||||
|
return srgbES3, nil
|
||||||
|
case strings.Contains(exts, "EXT_sRGB"):
|
||||||
|
return srgbEXT, nil
|
||||||
|
default:
|
||||||
|
return 0, errors.New("neither OpenGL ES 3 nor EXT_sRGB is supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ func newStenciler(ctx *context) *stenciler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *fboSet) resize(ctx *context, sizes []image.Point, internalFormat int, format, ty gl.Enum) {
|
func (s *fboSet) resize(ctx *context, sizes []image.Point) {
|
||||||
// Add fbos.
|
// Add fbos.
|
||||||
for i := len(s.fbos); i < len(sizes); i++ {
|
for i := len(s.fbos); i < len(sizes); i++ {
|
||||||
tex := ctx.CreateTexture()
|
tex := ctx.CreateTexture()
|
||||||
@@ -177,7 +177,8 @@ func (s *fboSet) resize(ctx *context, sizes []image.Point, internalFormat int, f
|
|||||||
if resize {
|
if resize {
|
||||||
f.size = sz
|
f.size = sz
|
||||||
ctx.BindTexture(gl.TEXTURE_2D, f.tex)
|
ctx.BindTexture(gl.TEXTURE_2D, f.tex)
|
||||||
ctx.TexImage2D(gl.TEXTURE_2D, 0, internalFormat, sz.X, sz.Y, format, ty, nil)
|
tt := ctx.caps.floatTriple
|
||||||
|
ctx.TexImage2D(gl.TEXTURE_2D, 0, tt.internalFormat, sz.X, sz.Y, tt.format, tt.typ, nil)
|
||||||
ctx.BindFramebuffer(gl.FRAMEBUFFER, f.fbo)
|
ctx.BindFramebuffer(gl.FRAMEBUFFER, f.fbo)
|
||||||
ctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, f.tex, 0)
|
ctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, f.tex, 0)
|
||||||
}
|
}
|
||||||
@@ -254,7 +255,7 @@ func (s *stenciler) beginIntersect(sizes []image.Point) {
|
|||||||
// 8 bit coverage is enough, but OpenGL ES only supports single channel
|
// 8 bit coverage is enough, but OpenGL ES only supports single channel
|
||||||
// floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if
|
// floating point formats. Replace with GL_RGB+GL_UNSIGNED_BYTE if
|
||||||
// no floating point support is available.
|
// no floating point support is available.
|
||||||
s.intersections.resize(s.ctx, sizes, gl.R16F, gl.RED, gl.HALF_FLOAT)
|
s.intersections.resize(s.ctx, sizes)
|
||||||
s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0)
|
s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0)
|
||||||
s.ctx.UseProgram(s.iprog)
|
s.ctx.UseProgram(s.iprog)
|
||||||
}
|
}
|
||||||
@@ -278,7 +279,7 @@ func (s *stenciler) begin(sizes []image.Point) {
|
|||||||
s.ctx.BindTexture(gl.TEXTURE_2D, gl.Texture{})
|
s.ctx.BindTexture(gl.TEXTURE_2D, gl.Texture{})
|
||||||
s.ctx.ActiveTexture(gl.TEXTURE0)
|
s.ctx.ActiveTexture(gl.TEXTURE0)
|
||||||
s.ctx.BlendFunc(gl.ONE, gl.ONE)
|
s.ctx.BlendFunc(gl.ONE, gl.ONE)
|
||||||
s.fbos.resize(s.ctx, sizes, gl.R16F, gl.RED, gl.HALF_FLOAT)
|
s.fbos.resize(s.ctx, sizes)
|
||||||
s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0)
|
s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0)
|
||||||
s.ctx.BindTexture(gl.TEXTURE_2D, s.areaLUT)
|
s.ctx.BindTexture(gl.TEXTURE_2D, s.areaLUT)
|
||||||
s.ctx.UseProgram(s.prog)
|
s.ctx.UseProgram(s.prog)
|
||||||
|
|||||||
Reference in New Issue
Block a user