gpu/internal/opengl: detect sRGB triple in terms of srgbaTripleFor

Refactor in preparation for relaxing sRGB format requirements.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-07-28 13:41:47 +02:00
parent 970fadf852
commit 68fa64dfd5
2 changed files with 34 additions and 42 deletions
+33 -41
View File
@@ -17,42 +17,38 @@ import (
// for gamma-correct rendering on platforms without // for gamma-correct rendering on platforms without
// sRGB enabled native framebuffers. // sRGB enabled native framebuffers.
type SRGBFBO struct { type SRGBFBO struct {
c *gl.Functions c *gl.Functions
state *glState state *glState
viewport image.Point viewport image.Point
srgbBuffer gl.Framebuffer fbo gl.Framebuffer
depthBuffer gl.Renderbuffer tex gl.Texture
colorTex gl.Texture depth gl.Renderbuffer
blitted bool blitted bool
quad gl.Buffer quad gl.Buffer
prog gl.Program prog gl.Program
gl3 bool format textureTriple
} }
func NewSRGBFBO(f *gl.Functions, state *glState) (*SRGBFBO, error) { func NewSRGBFBO(f *gl.Functions, state *glState) (*SRGBFBO, error) {
var gl3 bool
glVer := f.GetString(gl.VERSION) glVer := f.GetString(gl.VERSION)
ver, _, err := gl.ParseGLVersion(glVer) ver, _, err := gl.ParseGLVersion(glVer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if ver[0] >= 3 { exts := strings.Split(f.GetString(gl.EXTENSIONS), " ")
gl3 = true srgbTriple, err := srgbaTripleFor(ver, exts)
} else { if err != nil {
exts := f.GetString(gl.EXTENSIONS) return nil, fmt.Errorf("srgb: missing sRGB format support")
if !strings.Contains(exts, "EXT_sRGB") {
return nil, fmt.Errorf("no support for OpenGL ES 3 nor EXT_sRGB")
}
} }
s := &SRGBFBO{ s := &SRGBFBO{
c: f, c: f,
state: state, state: state,
gl3: gl3, format: srgbTriple,
srgbBuffer: f.CreateFramebuffer(), fbo: f.CreateFramebuffer(),
colorTex: f.CreateTexture(), tex: f.CreateTexture(),
depthBuffer: f.CreateRenderbuffer(), depth: f.CreateRenderbuffer(),
} }
state.bindTexture(f, 0, s.colorTex) state.bindTexture(f, 0, s.tex)
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
@@ -82,19 +78,19 @@ func (s *SRGBFBO) Blit() {
s.blitted = true s.blitted = true
} }
s.state.useProgram(s.c, s.prog) s.state.useProgram(s.c, s.prog)
s.state.bindTexture(s.c, 0, s.colorTex) s.state.bindTexture(s.c, 0, s.tex)
s.state.vertexAttribPointer(s.c, s.quad, 0 /* pos */, 2, gl.FLOAT, false, 4*4, 0) s.state.vertexAttribPointer(s.c, s.quad, 0 /* pos */, 2, gl.FLOAT, false, 4*4, 0)
s.state.vertexAttribPointer(s.c, s.quad, 1 /* uv */, 2, gl.FLOAT, false, 4*4, 4*2) s.state.vertexAttribPointer(s.c, s.quad, 1 /* uv */, 2, gl.FLOAT, false, 4*4, 4*2)
s.state.setVertexAttribArray(s.c, 0, true) s.state.setVertexAttribArray(s.c, 0, true)
s.state.setVertexAttribArray(s.c, 1, true) s.state.setVertexAttribArray(s.c, 1, true)
s.c.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) s.c.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
s.state.bindFramebuffer(s.c, gl.FRAMEBUFFER, s.srgbBuffer) s.state.bindFramebuffer(s.c, gl.FRAMEBUFFER, s.fbo)
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0) s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT) s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT)
} }
func (s *SRGBFBO) Framebuffer() gl.Framebuffer { func (s *SRGBFBO) Framebuffer() gl.Framebuffer {
return s.srgbBuffer return s.fbo
} }
func (s *SRGBFBO) Refresh(viewport image.Point) error { func (s *SRGBFBO) Refresh(viewport image.Point) error {
@@ -105,17 +101,13 @@ func (s *SRGBFBO) Refresh(viewport image.Point) error {
return nil return nil
} }
s.viewport = viewport s.viewport = viewport
s.state.bindTexture(s.c, 0, s.colorTex) s.state.bindTexture(s.c, 0, s.tex)
if s.gl3 { s.c.TexImage2D(gl.TEXTURE_2D, 0, s.format.internalFormat, viewport.X, viewport.Y, s.format.format, s.format.typ)
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, viewport.X, viewport.Y, gl.RGBA, gl.UNSIGNED_BYTE) s.state.bindRenderbuffer(s.c, gl.RENDERBUFFER, s.depth)
} else /* EXT_sRGB */ {
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB_ALPHA_EXT, viewport.X, viewport.Y, gl.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE)
}
s.state.bindRenderbuffer(s.c, gl.RENDERBUFFER, s.depthBuffer)
s.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, viewport.X, viewport.Y) s.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, viewport.X, viewport.Y)
s.state.bindFramebuffer(s.c, gl.FRAMEBUFFER, s.srgbBuffer) s.state.bindFramebuffer(s.c, gl.FRAMEBUFFER, s.fbo)
s.c.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, s.colorTex, 0) s.c.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, s.tex, 0)
s.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, s.depthBuffer) s.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, s.depth)
if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE { if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError()) return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError())
} }
@@ -140,9 +132,9 @@ func (s *SRGBFBO) Refresh(viewport image.Point) error {
} }
func (s *SRGBFBO) Release() { func (s *SRGBFBO) Release() {
s.state.deleteFramebuffer(s.c, s.srgbBuffer) s.state.deleteFramebuffer(s.c, s.fbo)
s.state.deleteTexture(s.c, s.colorTex) s.state.deleteTexture(s.c, s.tex)
s.state.deleteRenderbuffer(s.c, s.depthBuffer) s.state.deleteRenderbuffer(s.c, s.depth)
if s.blitted { if s.blitted {
s.state.deleteBuffer(s.c, s.quad) s.state.deleteBuffer(s.c, s.quad)
s.state.deleteProgram(s.c, s.prog) s.state.deleteProgram(s.c, s.prog)
+1 -1
View File
@@ -180,7 +180,7 @@ func createContext(disp _EGLDisplay) (*eglContext, error) {
// Some Mesa drivers crash if an sRGB framebuffer is requested without alpha. // Some Mesa drivers crash if an sRGB framebuffer is requested without alpha.
// https://bugs.freedesktop.org/show_bug.cgi?id=107782. // https://bugs.freedesktop.org/show_bug.cgi?id=107782.
// //
// Also, some Android devices (Samsung S9) needs alpha for sRGB to work. // Also, some Android devices (Samsung S9) need alpha for sRGB to work.
attribs = append(attribs, _EGL_ALPHA_SIZE, 8) attribs = append(attribs, _EGL_ALPHA_SIZE, 8)
} }
// Only request a depth buffer if we're going to render directly to the framebuffer. // Only request a depth buffer if we're going to render directly to the framebuffer.