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
oneMinusDstAlpha operation
locationCache *locationCache
lastFramebuffer Framebuffer
lastCompositeMode CompositeMode
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
}
func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
var pixels []uint8
if err := c.RunOnContextThread(func() error {
gl.Flush()
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
c.bindFramebuffer(f)
pixels = make([]uint8, 4*width*height)
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
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() {
c.RunOnContextThread(func() error {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(ZeroFramebuffer))
c.bindFramebuffer(ZeroFramebuffer)
return nil
})
}
@ -203,7 +207,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
if f <= 0 {
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)
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 {
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 e := gl.GetError(); e != 0 {
return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e)

View File

@ -58,9 +58,8 @@ func (p Program) id() programID {
}
type context struct {
gl *webgl.Context
lastFramebuffer Framebuffer
lastProgramID programID
gl *webgl.Context
lastProgramID programID
}
func NewContext() (*Context, error) {
@ -157,12 +156,9 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture{t}, nil
}
func (c *Context) bindFramebuffer(f Framebuffer) {
func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl := c.gl
if c.lastFramebuffer != f {
gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object)
c.lastFramebuffer = f
}
gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object)
}
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
}
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) {
gl := c.gl
gl.Flush()
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
c.bindFramebuffer(f)
pixels := make([]uint8, 4*width*height)
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() {
gl := c.gl
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(ZeroFramebuffer))
c.bindFramebuffer(ZeroFramebuffer)
}
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
@ -162,7 +166,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
if f.Value <= 0 {
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)
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 {
gl := c.gl
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
c.bindFramebuffer(f)
if err := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER); err != mgl.FRAMEBUFFER_COMPLETE {
if e := gl.GetError(); e != 0 {
return fmt.Errorf("opengl: glBindFramebuffer failed: %d", e)