mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphicsdriver/opengl: Optimization: Avoid creating slices for every frame (uniform variables)
This commit is contained in:
parent
b4f45edff8
commit
60f2c7ace6
@ -48,6 +48,8 @@ type Graphics struct {
|
|||||||
|
|
||||||
uniformVariableNameCache map[int]string
|
uniformVariableNameCache map[int]string
|
||||||
|
|
||||||
|
uniformVars []uniformVariable
|
||||||
|
|
||||||
// activatedTextures is a set of activated textures.
|
// activatedTextures is a set of activated textures.
|
||||||
// textureNative cannot be a map key unfortunately.
|
// textureNative cannot be a map key unfortunately.
|
||||||
activatedTextures []activatedTexture
|
activatedTextures []activatedTexture
|
||||||
@ -185,7 +187,6 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
g.context.blendFunc(mode)
|
g.context.blendFunc(mode)
|
||||||
|
|
||||||
var program program
|
var program program
|
||||||
var uniformVars []uniformVariable
|
|
||||||
if shaderID == driver.InvalidShaderID {
|
if shaderID == driver.InvalidShaderID {
|
||||||
program = g.state.programs[programKey{
|
program = g.state.programs[programKey{
|
||||||
useColorM: !colorM.IsIdentity(),
|
useColorM: !colorM.IsIdentity(),
|
||||||
@ -194,7 +195,7 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
dw, dh := destination.framebufferSize()
|
dw, dh := destination.framebufferSize()
|
||||||
uniformVars = append(uniformVars, uniformVariable{
|
g.uniformVars = append(g.uniformVars, uniformVariable{
|
||||||
name: "viewport_size",
|
name: "viewport_size",
|
||||||
valueSlice: []float32{float32(dw), float32(dh)},
|
valueSlice: []float32{float32(dw), float32(dh)},
|
||||||
typ: shaderir.Type{Main: shaderir.Vec2},
|
typ: shaderir.Type{Main: shaderir.Vec2},
|
||||||
@ -214,7 +215,7 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
var esBody [16]float32
|
var esBody [16]float32
|
||||||
var esTranslate [4]float32
|
var esTranslate [4]float32
|
||||||
colorM.Elements(&esBody, &esTranslate)
|
colorM.Elements(&esBody, &esTranslate)
|
||||||
uniformVars = append(uniformVars, uniformVariable{
|
g.uniformVars = append(g.uniformVars, uniformVariable{
|
||||||
name: "color_matrix_body",
|
name: "color_matrix_body",
|
||||||
valueSlice: esBody[:],
|
valueSlice: esBody[:],
|
||||||
typ: shaderir.Type{Main: shaderir.Mat4},
|
typ: shaderir.Type{Main: shaderir.Mat4},
|
||||||
@ -227,7 +228,7 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
|
|
||||||
if filter != driver.FilterNearest {
|
if filter != driver.FilterNearest {
|
||||||
sw, sh := g.images[srcIDs[0]].framebufferSize()
|
sw, sh := g.images[srcIDs[0]].framebufferSize()
|
||||||
uniformVars = append(uniformVars, uniformVariable{
|
g.uniformVars = append(g.uniformVars, uniformVariable{
|
||||||
name: "source_size",
|
name: "source_size",
|
||||||
valueSlice: []float32{float32(sw), float32(sh)},
|
valueSlice: []float32{float32(sw), float32(sh)},
|
||||||
typ: shaderir.Type{Main: shaderir.Vec2},
|
typ: shaderir.Type{Main: shaderir.Vec2},
|
||||||
@ -236,7 +237,7 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
|
|
||||||
if filter == driver.FilterScreen {
|
if filter == driver.FilterScreen {
|
||||||
scale := float32(destination.width) / float32(g.images[srcIDs[0]].width)
|
scale := float32(destination.width) / float32(g.images[srcIDs[0]].width)
|
||||||
uniformVars = append(uniformVars, uniformVariable{
|
g.uniformVars = append(g.uniformVars, uniformVariable{
|
||||||
name: "scale",
|
name: "scale",
|
||||||
value: scale,
|
value: scale,
|
||||||
typ: shaderir.Type{Main: shaderir.Float},
|
typ: shaderir.Type{Main: shaderir.Float},
|
||||||
@ -245,14 +246,20 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
} else {
|
} else {
|
||||||
shader := g.shaders[shaderID]
|
shader := g.shaders[shaderID]
|
||||||
program = shader.p
|
program = shader.p
|
||||||
uniformVars = make([]uniformVariable, graphics.PreservedUniformVariablesNum+len(uniforms))
|
|
||||||
|
ulen := graphics.PreservedUniformVariablesNum + len(uniforms)
|
||||||
|
if cap(g.uniformVars) < ulen {
|
||||||
|
g.uniformVars = make([]uniformVariable, ulen)
|
||||||
|
} else {
|
||||||
|
g.uniformVars = g.uniformVars[:ulen]
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const idx = graphics.DestinationTextureSizeUniformVariableIndex
|
const idx = graphics.DestinationTextureSizeUniformVariableIndex
|
||||||
w, h := destination.framebufferSize()
|
w, h := destination.framebufferSize()
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = []float32{float32(w), float32(h)}
|
g.uniformVars[idx].valueSlice = []float32{float32(w), float32(h)}
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
sizes := make([]float32, 2*len(srcIDs))
|
sizes := make([]float32, 2*len(srcIDs))
|
||||||
@ -265,24 +272,24 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
|
|
||||||
}
|
}
|
||||||
const idx = graphics.TextureSizesUniformVariableIndex
|
const idx = graphics.TextureSizesUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = sizes
|
g.uniformVars[idx].valueSlice = sizes
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
dw, dh := destination.framebufferSize()
|
dw, dh := destination.framebufferSize()
|
||||||
{
|
{
|
||||||
origin := []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
origin := []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
||||||
const idx = graphics.TextureDestinationRegionOriginUniformVariableIndex
|
const idx = graphics.TextureDestinationRegionOriginUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = origin
|
g.uniformVars[idx].valueSlice = origin
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
size := []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
size := []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
||||||
const idx = graphics.TextureDestinationRegionSizeUniformVariableIndex
|
const idx = graphics.TextureDestinationRegionSizeUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = size
|
g.uniformVars[idx].valueSlice = size
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
voffsets := make([]float32, 2*len(offsets))
|
voffsets := make([]float32, 2*len(offsets))
|
||||||
@ -291,37 +298,37 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
voffsets[2*i+1] = o[1]
|
voffsets[2*i+1] = o[1]
|
||||||
}
|
}
|
||||||
const idx = graphics.TextureSourceOffsetsUniformVariableIndex
|
const idx = graphics.TextureSourceOffsetsUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = voffsets
|
g.uniformVars[idx].valueSlice = voffsets
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
origin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
origin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
||||||
const idx = graphics.TextureSourceRegionOriginUniformVariableIndex
|
const idx = graphics.TextureSourceRegionOriginUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = origin
|
g.uniformVars[idx].valueSlice = origin
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
size := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
size := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
||||||
const idx = graphics.TextureSourceRegionSizeUniformVariableIndex
|
const idx = graphics.TextureSourceRegionSizeUniformVariableIndex
|
||||||
uniformVars[idx].name = g.uniformVariableName(idx)
|
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
||||||
uniformVars[idx].valueSlice = size
|
g.uniformVars[idx].valueSlice = size
|
||||||
uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
const offset = graphics.PreservedUniformVariablesNum
|
const offset = graphics.PreservedUniformVariablesNum
|
||||||
uniformVars[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
g.uniformVars[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case float32:
|
case float32:
|
||||||
uniformVars[i+offset].value = v
|
g.uniformVars[i+offset].value = v
|
||||||
case []float32:
|
case []float32:
|
||||||
uniformVars[i+offset].valueSlice = v
|
g.uniformVars[i+offset].valueSlice = v
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("opengl: unexpected uniform value: %v (type: %T)", v, v)
|
return fmt.Errorf("opengl: unexpected uniform value: %v (type: %T)", v, v)
|
||||||
}
|
}
|
||||||
uniformVars[i+offset].typ = shader.ir.Uniforms[i+offset]
|
g.uniformVars[i+offset].typ = shader.ir.Uniforms[i+offset]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,10 +341,15 @@ func (g *Graphics) DrawTriangles(dstID driver.ImageID, srcIDs [graphics.ShaderIm
|
|||||||
imgs[i].native = g.images[srcID].texture
|
imgs[i].native = g.images[srcID].texture
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.useProgram(program, uniformVars, imgs); err != nil {
|
if err := g.useProgram(program, g.uniformVars, imgs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range g.uniformVars {
|
||||||
|
g.uniformVars[i] = uniformVariable{}
|
||||||
|
}
|
||||||
|
g.uniformVars = g.uniformVars[:0]
|
||||||
|
|
||||||
if evenOdd {
|
if evenOdd {
|
||||||
if err := destination.ensureStencilBuffer(); err != nil {
|
if err := destination.ensureStencilBuffer(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user