gpu/internal/opengl,internal: move sRGB emulation to OpenGL driver

There is only one driver but several backends (EGL, WebGL).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-05-15 15:25:02 +02:00
parent e90c99a66c
commit 21c319ace5
14 changed files with 104 additions and 102 deletions
+1 -32
View File
@@ -11,7 +11,6 @@ import (
"strings"
"gioui.org/gpu"
"gioui.org/internal/srgb"
)
type Context struct {
@@ -20,8 +19,6 @@ type Context struct {
eglSurf _EGLSurface
width, height int
refreshFBO bool
// For sRGB emulation.
srgbFBO *srgb.FBO
}
type eglContext struct {
@@ -60,10 +57,6 @@ const (
)
func (c *Context) Release() {
if c.srgbFBO != nil {
c.srgbFBO.Release()
c.srgbFBO = nil
}
c.ReleaseSurface()
if c.eglCtx != nil {
eglDestroyContext(c.disp, c.eglCtx.ctx)
@@ -73,15 +66,9 @@ func (c *Context) Release() {
}
func (c *Context) Present() error {
if c.srgbFBO != nil {
c.srgbFBO.Blit()
}
if !eglSwapBuffers(c.disp, c.eglSurf) {
return fmt.Errorf("eglSwapBuffers failed (%x)", eglGetError())
}
if c.srgbFBO != nil {
c.srgbFBO.AfterPresent()
}
return nil
}
@@ -151,24 +138,6 @@ func (c *Context) MakeCurrent() error {
if !eglMakeCurrent(c.disp, c.eglSurf, c.eglSurf, c.eglCtx.ctx) {
return fmt.Errorf("eglMakeCurrent error 0x%x", eglGetError())
}
if c.eglCtx.srgb || c.eglSurf == nilEGLSurface {
return nil
}
if c.srgbFBO == nil {
var err error
c.srgbFBO, err = srgb.New(nil)
if err != nil {
c.ReleaseCurrent()
return err
}
}
if c.refreshFBO {
c.refreshFBO = false
if err := c.srgbFBO.Refresh(c.width, c.height); err != nil {
c.ReleaseCurrent()
return err
}
}
return nil
}
@@ -268,7 +237,7 @@ func createSurface(disp _EGLDisplay, eglCtx *eglContext, win NativeWindowType) (
surfAttribs = append(surfAttribs, _EGL_NONE)
eglSurf := eglCreateWindowSurface(disp, eglCtx.config, win, surfAttribs)
if eglSurf == nilEGLSurface && eglCtx.srgb {
// Try again without sRGB
// Try again without sRGB.
eglCtx.srgb = false
surfAttribs = []_EGLint{_EGL_NONE}
eglSurf = eglCreateWindowSurface(disp, eglCtx.config, win, surfAttribs)
+1
View File
@@ -10,6 +10,7 @@ type (
const (
ALL_BARRIER_BITS = 0xffffffff
ARRAY_BUFFER = 0x8892
BACK = 0x0405
BLEND = 0xbe2
CLAMP_TO_EDGE = 0x812f
COLOR_ATTACHMENT0 = 0x8ce0
+9
View File
@@ -436,6 +436,15 @@ func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname
return int(f.ints[0])
}
func (f *Functions) GetInteger4(pname Enum) [4]int {
C.glGetIntegerv(C.GLenum(pname), &f.ints[0])
var r [4]int
for i := range r {
r[i] = int(f.ints[i])
}
return r
}
func (f *Functions) GetInteger(pname Enum) int {
C.glGetIntegerv(C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
+8
View File
@@ -292,6 +292,14 @@ func (c *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname
p, _, _ := syscall.Syscall(_glGetFramebufferAttachmentParameteri.Addr(), 3, uintptr(target), uintptr(attachment), uintptr(pname))
return int(p)
}
func (c *Functions) GetInteger4(pname Enum) [4]int {
syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0)
var r [4]int
for i := range r {
r[i] = int(c.int32s[i])
}
return r
}
func (c *Functions) GetInteger(pname Enum) int {
syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0)
return int(c.int32s[0])
+4
View File
@@ -14,6 +14,10 @@ type (
Object struct{ V uint }
)
func (u Framebuffer) Valid() bool {
return u.V != 0
}
func (u Uniform) Valid() bool {
return u.V != -1
}
+4
View File
@@ -16,6 +16,10 @@ type (
Object js.Value
)
func (f Framebuffer) Valid() bool {
return !js.Value(f).IsUndefined() && !js.Value(f).IsNull()
}
func (p Program) Valid() bool {
return !js.Value(p).IsUndefined() && !js.Value(p).IsNull()
}
+30 -33
View File
@@ -3,7 +3,9 @@
package srgb
import (
"errors"
"fmt"
"image"
"runtime"
"strings"
@@ -15,22 +17,18 @@ import (
// for gamma-correct rendering on platforms without
// sRGB enabled native framebuffers.
type FBO struct {
c *gl.Functions
width, height int
frameBuffer gl.Framebuffer
depthBuffer gl.Renderbuffer
colorTex gl.Texture
blitted bool
quad gl.Buffer
prog gl.Program
gl3 bool
c *gl.Functions
viewport image.Point
srgbBuffer gl.Framebuffer
depthBuffer gl.Renderbuffer
colorTex gl.Texture
blitted bool
quad gl.Buffer
prog gl.Program
gl3 bool
}
func New(ctx gl.Context) (*FBO, error) {
f, err := gl.NewFunctions(ctx)
if err != nil {
return nil, err
}
func New(f *gl.Functions) (*FBO, error) {
var gl3 bool
glVer := f.GetString(gl.VERSION)
ver, _, err := gl.ParseGLVersion(glVer)
@@ -48,7 +46,7 @@ func New(ctx gl.Context) (*FBO, error) {
s := &FBO{
c: f,
gl3: gl3,
frameBuffer: f.CreateFramebuffer(),
srgbBuffer: f.CreateFramebuffer(),
colorTex: f.CreateTexture(),
depthBuffer: f.CreateRenderbuffer(),
}
@@ -81,7 +79,6 @@ func (s *FBO) Blit() {
s.c.BufferSubData(gl.ARRAY_BUFFER, 0, coords)
s.blitted = true
}
s.c.BindFramebuffer(gl.FRAMEBUFFER, gl.Framebuffer{})
s.c.UseProgram(s.prog)
s.c.BindTexture(gl.TEXTURE_2D, s.colorTex)
s.c.BindBuffer(gl.ARRAY_BUFFER, s.quad)
@@ -93,38 +90,38 @@ func (s *FBO) Blit() {
s.c.BindTexture(gl.TEXTURE_2D, gl.Texture{})
s.c.DisableVertexAttribArray(0)
s.c.DisableVertexAttribArray(1)
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.frameBuffer)
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.srgbBuffer)
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT)
// The Android emulator requires framebuffer 0 bound at eglSwapBuffer time.
// Bind the sRGB framebuffer again in afterPresent.
s.c.BindFramebuffer(gl.FRAMEBUFFER, gl.Framebuffer{})
}
func (s *FBO) AfterPresent() {
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.frameBuffer)
func (s *FBO) Framebuffer() gl.Framebuffer {
return s.srgbBuffer
}
func (s *FBO) Refresh(w, h int) error {
s.width, s.height = w, h
if w == 0 || h == 0 {
func (s *FBO) Refresh(viewport image.Point) error {
if viewport.X == 0 || viewport.Y == 0 {
return errors.New("srgb: zero-sized framebuffer")
}
if s.viewport == viewport {
return nil
}
s.viewport = viewport
s.c.BindTexture(gl.TEXTURE_2D, s.colorTex)
if s.gl3 {
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, w, h, gl.RGBA, gl.UNSIGNED_BYTE)
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, viewport.X, viewport.Y, gl.RGBA, gl.UNSIGNED_BYTE)
} else /* EXT_sRGB */ {
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB_ALPHA_EXT, w, h, gl.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE)
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB_ALPHA_EXT, viewport.X, viewport.Y, gl.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE)
}
currentRB := gl.Renderbuffer(s.c.GetBinding(gl.RENDERBUFFER_BINDING))
s.c.BindRenderbuffer(gl.RENDERBUFFER, s.depthBuffer)
s.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h)
s.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, viewport.X, viewport.Y)
s.c.BindRenderbuffer(gl.RENDERBUFFER, currentRB)
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.frameBuffer)
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.srgbBuffer)
s.c.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, s.colorTex, 0)
s.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, s.depthBuffer)
if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", s.width, s.height, st, s.c.GetError())
return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError())
}
if runtime.GOOS == "js" {
@@ -136,9 +133,9 @@ func (s *FBO) Refresh(w, h int) error {
var pixel [4]byte
s.c.ReadPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel[:])
if pixel[0] == 128 { // Correct sRGB color value is ~188
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, gl.RGBA, gl.UNSIGNED_BYTE)
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.X, viewport.Y, gl.RGBA, gl.UNSIGNED_BYTE)
if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
return fmt.Errorf("fallback RGBA framebuffer incomplete (%dx%d), status: %#x error: %x", s.width, s.height, st, s.c.GetError())
return fmt.Errorf("fallback RGBA framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError())
}
}
}
@@ -147,7 +144,7 @@ func (s *FBO) Refresh(w, h int) error {
}
func (s *FBO) Release() {
s.c.DeleteFramebuffer(s.frameBuffer)
s.c.DeleteFramebuffer(s.srgbBuffer)
s.c.DeleteTexture(s.colorTex)
s.c.DeleteRenderbuffer(s.depthBuffer)
if s.blitted {