internal/graphicsdriver/opengl: bug fix: needed always to set uniform variables

Before this fix, setting uniform variables could be skipped when the
values were the same. This caused some issues when a number of drawing
commands were much small than usual (e.g. SetScreenClearedEveryFrame
with false).

This change fixes this by not doing such optimization. Unfortunately
it was impossible to create a minimum reproducible unit test since
we cannot test the final screen framebuffer's states so far.

Closes #2517
This commit is contained in:
Hajime Hoshi 2023-01-03 00:39:37 +09:00
parent a049acd94e
commit 6b4c696b31

View File

@ -124,7 +124,6 @@ type openGLState struct {
elementArrayBuffer buffer
lastProgram program
lastUniforms map[string][]uint32
lastActiveTexture int
}
@ -136,9 +135,6 @@ func (s *openGLState) reset(context *context) error {
s.lastProgram = 0
context.ctx.UseProgram(0)
for key := range s.lastUniforms {
delete(s.lastUniforms, key)
}
// On browsers (at least Chrome), buffers are already detached from the context
// and must not be deleted by DeleteBuffer.
@ -161,19 +157,6 @@ func (s *openGLState) reset(context *context) error {
return nil
}
// areSameUint32Array returns a boolean indicating if a and b are deeply equal.
func areSameUint32Array(a, b []uint32) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
type uniformVariable struct {
name string
value []uint32
@ -208,9 +191,6 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
}
g.state.lastProgram = program
for k := range g.state.lastUniforms {
delete(g.state.lastUniforms, k)
}
g.state.lastActiveTexture = 0
g.context.ctx.ActiveTexture(gl.TEXTURE0)
}
@ -226,15 +206,8 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
return fmt.Errorf("opengl: length of a uniform variables %s (%s) doesn't match: expected %d but %d", u.name, typ.String(), expected, got)
}
cached, ok := g.state.lastUniforms[u.name]
if ok && areSameUint32Array(cached, u.value) {
continue
}
// Set the uniform variables, even though they are the same as the last time (#2517).
g.context.uniforms(program, u.name, u.value, u.typ)
if g.state.lastUniforms == nil {
g.state.lastUniforms = map[string][]uint32{}
}
g.state.lastUniforms[u.name] = u.value
}
var idx int