opengl: Introduce locationCache struct

This commit is contained in:
Hajime Hoshi 2016-02-27 03:01:55 +09:00
parent 3c4aa7ec1e
commit 93f9d9fbb0
4 changed files with 45 additions and 30 deletions

View File

@ -47,7 +47,8 @@ func (p Program) id() programID {
} }
type context struct { type context struct {
funcs chan func() locationCache *locationCache
funcs chan func()
} }
func NewContext() *Context { func NewContext() *Context {
@ -63,6 +64,7 @@ func NewContext() *Context {
Triangles: gl.TRIANGLES, Triangles: gl.TRIANGLES,
Lines: gl.LINES, Lines: gl.LINES,
} }
c.locationCache = newLocationCache()
c.funcs = make(chan func()) c.funcs = make(chan func())
return c return c
} }
@ -321,14 +323,14 @@ func (c *Context) getUniformLocation(p Program, location string) UniformLocation
func (c *Context) UniformInt(p Program, location string, v int) { func (c *Context) UniformInt(p Program, location string, v int) {
c.RunOnContextThread(func() { c.RunOnContextThread(func() {
l := int32(GetUniformLocation(c, p, location)) l := int32(c.locationCache.GetUniformLocation(c, p, location))
gl.Uniform1i(l, int32(v)) gl.Uniform1i(l, int32(v))
}) })
} }
func (c *Context) UniformFloats(p Program, location string, v []float32) { func (c *Context) UniformFloats(p Program, location string, v []float32) {
c.RunOnContextThread(func() { c.RunOnContextThread(func() {
l := int32(GetUniformLocation(c, p, location)) l := int32(c.locationCache.GetUniformLocation(c, p, location))
switch len(v) { switch len(v) {
case 4: case 4:
gl.Uniform4fv(l, 1, (*float32)(gl.Ptr(v))) gl.Uniform4fv(l, 1, (*float32)(gl.Ptr(v)))
@ -350,21 +352,21 @@ func (c *Context) getAttribLocation(p Program, location string) AttribLocation {
func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) { func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) {
c.RunOnContextThread(func() { c.RunOnContextThread(func() {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.VertexAttribPointer(uint32(l), int32(size), gl.SHORT, normalize, int32(stride), gl.PtrOffset(v)) gl.VertexAttribPointer(uint32(l), int32(size), gl.SHORT, normalize, int32(stride), gl.PtrOffset(v))
}) })
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
c.RunOnContextThread(func() { c.RunOnContextThread(func() {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.EnableVertexAttribArray(uint32(l)) gl.EnableVertexAttribArray(uint32(l))
}) })
} }
func (c *Context) DisableVertexAttribArray(p Program, location string) { func (c *Context) DisableVertexAttribArray(p Program, location string) {
c.RunOnContextThread(func() { c.RunOnContextThread(func() {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.DisableVertexAttribArray(uint32(l)) gl.DisableVertexAttribArray(uint32(l))
}) })
} }

View File

@ -65,6 +65,7 @@ func (p Program) id() programID {
type context struct { type context struct {
gl *webgl.Context gl *webgl.Context
lastFramebuffer Framebuffer lastFramebuffer Framebuffer
locationCache *locationCache
} }
func NewContext() *Context { func NewContext() *Context {
@ -105,6 +106,7 @@ func NewContext() *Context {
Lines: Mode(gl.LINES), Lines: Mode(gl.LINES),
} }
c.gl = gl c.gl = gl
c.locationCache = newLocationCache()
c.init() c.init()
return c return c
} }
@ -297,13 +299,13 @@ func (c *Context) getUniformLocation(p Program, location string) UniformLocation
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 := GetUniformLocation(c, p, location) l := c.locationCache.GetUniformLocation(c, p, location)
gl.Uniform1i(l.Object, v) gl.Uniform1i(l.Object, 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 := GetUniformLocation(c, p, location) l := c.locationCache.GetUniformLocation(c, p, location)
switch len(v) { switch len(v) {
case 4: case 4:
gl.Call("uniform4fv", l.Object, v) gl.Call("uniform4fv", l.Object, v)
@ -321,19 +323,19 @@ func (c *Context) getAttribLocation(p Program, location string) AttribLocation {
func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) { func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) {
gl := c.gl gl := c.gl
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.VertexAttribPointer(int(l), size, gl.SHORT, normalize, stride, v) gl.VertexAttribPointer(int(l), size, gl.SHORT, normalize, stride, v)
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl := c.gl gl := c.gl
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
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 := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.DisableVertexAttribArray(int(l)) gl.DisableVertexAttribArray(int(l))
} }

View File

@ -48,8 +48,9 @@ func (p Program) id() programID {
} }
type context struct { type context struct {
worker mgl.Worker locationCache *locationCache
funcs chan func() worker mgl.Worker
funcs chan func()
} }
// TODO: This variable can be in the context struct. // TODO: This variable can be in the context struct.
@ -70,6 +71,7 @@ func NewContext() *Context {
Triangles: mgl.TRIANGLES, Triangles: mgl.TRIANGLES,
Lines: mgl.LINES, Lines: mgl.LINES,
} }
c.locationCache = newLocationCache()
c.funcs = make(chan func()) c.funcs = make(chan func())
gl, c.worker = mgl.NewContext() gl, c.worker = mgl.NewContext()
return c return c
@ -259,11 +261,11 @@ func (c *Context) getUniformLocation(p Program, location string) UniformLocation
} }
func (c *Context) UniformInt(p Program, location string, v int) { func (c *Context) UniformInt(p Program, location string, v int) {
gl.Uniform1i(mgl.Uniform(GetUniformLocation(c, p, location)), v) gl.Uniform1i(mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)), v)
} }
func (c *Context) UniformFloats(p Program, location string, v []float32) { func (c *Context) UniformFloats(p Program, location string, v []float32) {
l := mgl.Uniform(GetUniformLocation(c, p, location)) l := mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location))
switch len(v) { switch len(v) {
case 4: case 4:
gl.Uniform4fv(l, v) gl.Uniform4fv(l, v)
@ -283,17 +285,17 @@ func (c *Context) getAttribLocation(p Program, location string) AttribLocation {
} }
func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) { func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.VertexAttribPointer(mgl.Attrib(l), size, mgl.SHORT, normalize, stride, v) gl.VertexAttribPointer(mgl.Attrib(l), size, mgl.SHORT, normalize, stride, v)
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.EnableVertexAttribArray(mgl.Attrib(l)) gl.EnableVertexAttribArray(mgl.Attrib(l))
} }
func (c *Context) DisableVertexAttribArray(p Program, location string) { func (c *Context) DisableVertexAttribArray(p Program, location string) {
l := GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.DisableVertexAttribArray(mgl.Attrib(l)) gl.DisableVertexAttribArray(mgl.Attrib(l))
} }

View File

@ -16,8 +16,17 @@ package opengl
// Since js.Object (Program) can't be keys of a map, use integers (programID) instead. // Since js.Object (Program) can't be keys of a map, use integers (programID) instead.
var uniformLocationCache = map[programID]map[string]UniformLocation{} type locationCache struct {
var attribLocationCache = map[programID]map[string]AttribLocation{} uniformLocationCache map[programID]map[string]UniformLocation
attribLocationCache map[programID]map[string]AttribLocation
}
func newLocationCache() *locationCache {
return &locationCache{
uniformLocationCache: map[programID]map[string]UniformLocation{},
attribLocationCache: map[programID]map[string]AttribLocation{},
}
}
type uniformLocationGetter interface { type uniformLocationGetter interface {
getUniformLocation(p Program, location string) UniformLocation getUniformLocation(p Program, location string) UniformLocation
@ -25,15 +34,15 @@ type uniformLocationGetter interface {
// TODO: Rename these functions not to be confusing // TODO: Rename these functions not to be confusing
func GetUniformLocation(g uniformLocationGetter, p Program, location string) UniformLocation { func (c *locationCache) GetUniformLocation(g uniformLocationGetter, p Program, location string) UniformLocation {
id := p.id() id := p.id()
if _, ok := uniformLocationCache[id]; !ok { if _, ok := c.uniformLocationCache[id]; !ok {
uniformLocationCache[id] = map[string]UniformLocation{} c.uniformLocationCache[id] = map[string]UniformLocation{}
} }
l, ok := uniformLocationCache[id][location] l, ok := c.uniformLocationCache[id][location]
if !ok { if !ok {
l = g.getUniformLocation(p, location) l = g.getUniformLocation(p, location)
uniformLocationCache[id][location] = l c.uniformLocationCache[id][location] = l
} }
return l return l
} }
@ -42,15 +51,15 @@ type attribLocationGetter interface {
getAttribLocation(p Program, location string) AttribLocation getAttribLocation(p Program, location string) AttribLocation
} }
func GetAttribLocation(g attribLocationGetter, p Program, location string) AttribLocation { func (c *locationCache) GetAttribLocation(g attribLocationGetter, p Program, location string) AttribLocation {
id := p.id() id := p.id()
if _, ok := attribLocationCache[id]; !ok { if _, ok := c.attribLocationCache[id]; !ok {
attribLocationCache[id] = map[string]AttribLocation{} c.attribLocationCache[id] = map[string]AttribLocation{}
} }
l, ok := attribLocationCache[id][location] l, ok := c.attribLocationCache[id][location]
if !ok { if !ok {
l = g.getAttribLocation(p, location) l = g.getAttribLocation(p, location)
attribLocationCache[id][location] = l c.attribLocationCache[id][location] = l
} }
return l return l
} }