Use location cache

This commit is contained in:
Hajime Hoshi 2015-01-12 23:16:34 +09:00
parent 9418d4c577
commit f0519b8604
3 changed files with 87 additions and 36 deletions

View File

@ -26,8 +26,14 @@ type Texture int
type Framebuffer int type Framebuffer int
type Shader int type Shader int
type Program int type Program int
type UniformLocation int type UniformLocation gl.UniformLocation
type AttribLocation int type AttribLocation gl.AttribLocation
type ProgramID int
func GetProgramID(p Program) ProgramID {
return ProgramID(p)
}
type context struct{} type context struct{}
@ -173,13 +179,17 @@ func (c *Context) UseProgram(p Program) {
gl.Program(p).Use() gl.Program(p).Use()
} }
func (c *Context) GetUniformLocation(p Program, location string) UniformLocation {
return UniformLocation(gl.Program(p).GetUniformLocation(location))
}
func (c *Context) UniformInt(p Program, location string, v int) { func (c *Context) UniformInt(p Program, location string, v int) {
l := gl.Program(p).GetUniformLocation(location) l := gl.UniformLocation(GetUniformLocation(c, p, location))
l.Uniform1i(v) l.Uniform1i(v)
} }
func (c *Context) UniformFloats(p Program, location string, v []float32) { func (c *Context) UniformFloats(p Program, location string, v []float32) {
l := gl.Program(p).GetUniformLocation(location) l := gl.UniformLocation(GetUniformLocation(c, p, location))
switch len(v) { switch len(v) {
case 4: case 4:
l.Uniform4fv(1, v) l.Uniform4fv(1, v)
@ -192,16 +202,23 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
} }
} }
func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
return AttribLocation(gl.Program(p).GetAttribLocation(location))
}
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) { func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) {
gl.Program(p).GetAttribLocation(location).AttribPointer(2, gl.FLOAT, false, stride, v) l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.AttribPointer(2, gl.FLOAT, false, stride, v)
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl.Program(p).GetAttribLocation(location).EnableArray() l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.EnableArray()
} }
func (c *Context) DisableVertexAttribArray(p Program, location string) { func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl.Program(p).GetAttribLocation(location).DisableArray() l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.DisableArray()
} }
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageType BufferUsageType) { func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageType BufferUsageType) {

View File

@ -30,6 +30,12 @@ type Program js.Object
type UniformLocation js.Object type UniformLocation js.Object
type AttribLocation int type AttribLocation int
type ProgramID int
func GetProgramID(p Program) ProgramID {
return ProgramID(p.Get("__ebiten_programId").Int())
}
type context struct { type context struct {
gl *webgl.Context gl *webgl.Context
} }
@ -175,12 +181,16 @@ func (c *Context) DeleteShader(s Shader) {
gl.DeleteShader(s) gl.DeleteShader(s)
} }
var lastProgramID ProgramID = 0
func (c *Context) NewProgram(shaders []Shader) (Program, error) { func (c *Context) NewProgram(shaders []Shader) (Program, error) {
gl := c.gl gl := c.gl
p := gl.CreateProgram() p := gl.CreateProgram()
if p == nil { if p == nil {
return nil, errors.New("glCreateProgram failed") return nil, errors.New("glCreateProgram failed")
} }
p.Set("__ebiten_programId", lastProgramID)
lastProgramID++
for _, shader := range shaders { for _, shader := range shaders {
gl.AttachShader(p, shader) gl.AttachShader(p, shader)
@ -197,23 +207,20 @@ func (c *Context) UseProgram(p Program) {
gl.UseProgram(p) gl.UseProgram(p)
} }
func (c *Context) GetUniformLocation(p Program, location string) UniformLocation {
gl := c.gl
return gl.GetUniformLocation(p, location)
}
func (c *Context) UniformInt(p Program, location string, v int) { func (c *Context) UniformInt(p Program, location string, v int) {
gl := c.gl gl := c.gl
l, ok := uniformLocationCache[location] l := GetUniformLocation(c, p, location)
if !ok {
l = gl.GetUniformLocation(p, location)
uniformLocationCache[location] = l
}
gl.Uniform1i(l, v) gl.Uniform1i(l, v)
} }
func (c *Context) UniformFloats(p Program, location string, v []float32) { func (c *Context) UniformFloats(p Program, location string, v []float32) {
gl := c.gl gl := c.gl
l, ok := uniformLocationCache[location] l := GetUniformLocation(c, p, location)
if !ok {
l = gl.GetUniformLocation(p, location)
uniformLocationCache[location] = l
}
switch len(v) { switch len(v) {
case 4: case 4:
gl.Call("uniform4fv", l, v) gl.Call("uniform4fv", l, v)
@ -224,33 +231,26 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
} }
} }
func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
gl := c.gl
return AttribLocation(gl.GetAttribLocation(p, location))
}
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) { func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) {
gl := c.gl gl := c.gl
l, ok := attribLocationCache[location] l := GetAttribLocation(c, p, location)
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
gl.VertexAttribPointer(int(l), 2, gl.FLOAT, false, stride, int(v)) gl.VertexAttribPointer(int(l), 2, gl.FLOAT, false, stride, int(v))
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl := c.gl gl := c.gl
l, ok := attribLocationCache[location] l := GetAttribLocation(c, p, location)
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
gl.EnableVertexAttribArray(int(l)) gl.EnableVertexAttribArray(int(l))
} }
func (c *Context) DisableVertexAttribArray(p Program, location string) { func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl := c.gl gl := c.gl
l, ok := attribLocationCache[location] l := GetAttribLocation(c, p, location)
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
gl.DisableVertexAttribArray(int(l)) gl.DisableVertexAttribArray(int(l))
} }

View File

@ -14,7 +14,41 @@
package opengl package opengl
// Note: This cache is created only for one program. // Since js.Object (Program) can't be keys of a map, use integers (ProgramID) instead.
// If we use two or more programs, the key of the map should be changed.
var uniformLocationCache = map[string]UniformLocation{} var uniformLocationCache = map[ProgramID]map[string]UniformLocation{}
var attribLocationCache = map[string]AttribLocation{} var attribLocationCache = map[ProgramID]map[string]AttribLocation{}
type UniformLocationGetter interface {
GetUniformLocation(p Program, location string) UniformLocation
}
func GetUniformLocation(g UniformLocationGetter, p Program, location string) UniformLocation {
id := GetProgramID(p)
if _, ok := uniformLocationCache[id]; !ok {
uniformLocationCache[id] = map[string]UniformLocation{}
}
l, ok := uniformLocationCache[id][location]
if !ok {
l = g.GetUniformLocation(p, location)
uniformLocationCache[id][location] = l
}
return l
}
type AttribLocationGetter interface {
GetAttribLocation(p Program, location string) AttribLocation
}
func GetAttribLocation(g AttribLocationGetter, p Program, location string) AttribLocation {
id := GetProgramID(p)
if _, ok := attribLocationCache[id]; !ok {
attribLocationCache[id] = map[string]AttribLocation{}
}
l, ok := attribLocationCache[id][location]
if !ok {
l = g.GetAttribLocation(p, location)
attribLocationCache[id][location] = l
}
return l
}