opengl: Reduce glBindFramebuffer calls

This commit is contained in:
Hajime Hoshi 2016-06-01 02:33:31 +09:00
parent 3dfbb4a2ea
commit 91491e58f4
4 changed files with 29 additions and 17 deletions

View File

@ -32,6 +32,14 @@ type Context struct {
oneMinusSrcAlpha operation oneMinusSrcAlpha operation
oneMinusDstAlpha operation oneMinusDstAlpha operation
locationCache *locationCache locationCache *locationCache
lastFramebuffer Framebuffer
lastCompositeMode CompositeMode lastCompositeMode CompositeMode
context context
} }
func (c *Context) bindFramebuffer(f Framebuffer) {
if c.lastFramebuffer != f {
c.bindFramebufferImpl(f)
c.lastFramebuffer = f
}
}

View File

@ -147,11 +147,15 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return texture, nil return texture, nil
} }
func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
var pixels []uint8 var pixels []uint8
if err := c.RunOnContextThread(func() error { if err := c.RunOnContextThread(func() error {
gl.Flush() gl.Flush()
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f)) c.bindFramebuffer(f)
pixels = make([]uint8, 4*width*height) pixels = make([]uint8, 4*width*height)
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels)) gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
if e := gl.GetError(); e != gl.NO_ERROR { if e := gl.GetError(); e != gl.NO_ERROR {
@ -189,7 +193,7 @@ func (c *Context) TexSubImage2D(p []uint8, width, height int) {
func (c *Context) BindZeroFramebuffer() { func (c *Context) BindZeroFramebuffer() {
c.RunOnContextThread(func() error { c.RunOnContextThread(func() error {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(ZeroFramebuffer)) c.bindFramebuffer(ZeroFramebuffer)
return nil return nil
}) })
} }
@ -203,7 +207,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
if f <= 0 { if f <= 0 {
return errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false") return errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false")
} }
gl.BindFramebuffer(gl.FRAMEBUFFER, f) c.bindFramebuffer(Framebuffer(f))
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, uint32(texture), 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, uint32(texture), 0)
s := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) s := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
@ -226,7 +230,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
func (c *Context) SetViewport(f Framebuffer, width, height int) error { func (c *Context) SetViewport(f Framebuffer, width, height int) error {
return c.RunOnContextThread(func() error { return c.RunOnContextThread(func() error {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f)) c.bindFramebuffer(f)
if st := gl.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE { if st := gl.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
if e := gl.GetError(); e != 0 { if e := gl.GetError(); e != 0 {
return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e) return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e)

View File

@ -59,7 +59,6 @@ func (p Program) id() programID {
type context struct { type context struct {
gl *webgl.Context gl *webgl.Context
lastFramebuffer Framebuffer
lastProgramID programID lastProgramID programID
} }
@ -157,12 +156,9 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture{t}, nil return Texture{t}, nil
} }
func (c *Context) bindFramebuffer(f Framebuffer) { func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl := c.gl gl := c.gl
if c.lastFramebuffer != f {
gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object) gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object)
c.lastFramebuffer = f
}
} }
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {

View File

@ -122,11 +122,16 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture(t), nil return Texture(t), nil
} }
func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl := c.gl
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
gl := c.gl gl := c.gl
gl.Flush() gl.Flush()
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f)) c.bindFramebuffer(f)
pixels := make([]uint8, 4*width*height) pixels := make([]uint8, 4*width*height)
gl.ReadPixels(pixels, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE) gl.ReadPixels(pixels, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE)
@ -152,8 +157,7 @@ func (c *Context) TexSubImage2D(p []uint8, width, height int) {
} }
func (c *Context) BindZeroFramebuffer() { func (c *Context) BindZeroFramebuffer() {
gl := c.gl c.bindFramebuffer(ZeroFramebuffer)
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(ZeroFramebuffer))
} }
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) { func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
@ -162,7 +166,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
if f.Value <= 0 { if f.Value <= 0 {
return Framebuffer{}, errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false") return Framebuffer{}, errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false")
} }
gl.BindFramebuffer(mgl.FRAMEBUFFER, f) c.bindFramebuffer(Framebuffer(f))
gl.FramebufferTexture2D(mgl.FRAMEBUFFER, mgl.COLOR_ATTACHMENT0, mgl.TEXTURE_2D, mgl.Texture(texture), 0) gl.FramebufferTexture2D(mgl.FRAMEBUFFER, mgl.COLOR_ATTACHMENT0, mgl.TEXTURE_2D, mgl.Texture(texture), 0)
s := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER) s := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER)
@ -181,7 +185,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
func (c *Context) SetViewport(f Framebuffer, width, height int) error { func (c *Context) SetViewport(f Framebuffer, width, height int) error {
gl := c.gl gl := c.gl
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f)) c.bindFramebuffer(f)
if err := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER); err != mgl.FRAMEBUFFER_COMPLETE { if err := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER); err != mgl.FRAMEBUFFER_COMPLETE {
if e := gl.GetError(); e != 0 { if e := gl.GetError(); e != 0 {
return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e) return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e)