gpu: replace Backend.DefaultFramebuffer by Backend.CurrentFramebuffer

DefaultFramebuffer was set up at Backend creation time, which is
difficult to predict. Instead, let GPU query and cache the current
FBO when created.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-22 16:25:01 +01:00
parent b4c163e437
commit dfc1503c00
4 changed files with 17 additions and 28 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ type Backend interface {
// are valid at the point of call. // are valid at the point of call.
IsTimeContinuous() bool IsTimeContinuous() bool
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error) NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
DefaultFramebuffer() Framebuffer CurrentFramebuffer() Framebuffer
NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error) NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error)
NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error) NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
NewBuffer(typ BufferBinding, size int) (Buffer, error) NewBuffer(typ BufferBinding, size int) (Buffer, error)
+9 -7
View File
@@ -15,8 +15,7 @@ import (
// Backend implements gpu.Backend. // Backend implements gpu.Backend.
type Backend struct { type Backend struct {
funcs Functions funcs Functions
defFBO *gpuFramebuffer
state glstate state glstate
@@ -59,10 +58,11 @@ type gpuTexture struct {
} }
type gpuFramebuffer struct { type gpuFramebuffer struct {
backend *Backend backend *Backend
obj Framebuffer obj Framebuffer
hasDepth bool hasDepth bool
depthBuf Renderbuffer depthBuf Renderbuffer
foreign bool
} }
type gpuBuffer struct { type gpuBuffer struct {
@@ -127,14 +127,12 @@ func NewBackend(f Functions) (*Backend, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defFBO := Framebuffer(f.GetBinding(FRAMEBUFFER_BINDING))
b := &Backend{ b := &Backend{
funcs: f, funcs: f,
floatTriple: floatTriple, floatTriple: floatTriple,
alphaTriple: alphaTripleFor(ver), alphaTriple: alphaTripleFor(ver),
srgbaTriple: srgbaTriple, srgbaTriple: srgbaTriple,
} }
b.defFBO = &gpuFramebuffer{backend: b, obj: defFBO}
if hasExtension(exts, "GL_EXT_disjoint_timer_query_webgl2") || hasExtension(exts, "GL_EXT_disjoint_timer_query") { if hasExtension(exts, "GL_EXT_disjoint_timer_query_webgl2") || hasExtension(exts, "GL_EXT_disjoint_timer_query") {
b.feats.Features |= gpu.FeatureTimers b.feats.Features |= gpu.FeatureTimers
} }
@@ -202,8 +200,9 @@ func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffe
return fbo, nil return fbo, nil
} }
func (b *Backend) DefaultFramebuffer() gpu.Framebuffer { func (b *Backend) CurrentFramebuffer() gpu.Framebuffer {
return b.defFBO fboID := Framebuffer(b.funcs.GetBinding(FRAMEBUFFER_BINDING))
return &gpuFramebuffer{backend: b, obj: fboID, foreign: true}
} }
func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) { func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) {
@@ -612,6 +611,9 @@ func (f *gpuFramebuffer) Invalidate() {
} }
func (f *gpuFramebuffer) Release() { func (f *gpuFramebuffer) Release() {
if f.foreign {
panic("cannot release framebuffer created by CurrentFramebuffer")
}
f.backend.funcs.DeleteFramebuffer(f.obj) f.backend.funcs.DeleteFramebuffer(f.obj)
if f.hasDepth { if f.hasDepth {
f.backend.funcs.DeleteRenderbuffer(f.depthBuf) f.backend.funcs.DeleteRenderbuffer(f.depthBuf)
+5 -2
View File
@@ -30,6 +30,7 @@ type GPU struct {
pathCache *opCache pathCache *opCache
cache *resourceCache cache *resourceCache
defFBO Framebuffer
profile string profile string
timers *timers timers *timers
frameStart time.Time frameStart time.Time
@@ -275,7 +276,9 @@ const (
) )
func New(ctx Backend) (*GPU, error) { func New(ctx Backend) (*GPU, error) {
defFBO := ctx.CurrentFramebuffer()
g := &GPU{ g := &GPU{
defFBO: defFBO,
pathCache: newOpCache(), pathCache: newOpCache(),
cache: newResourceCache(), cache: newResourceCache(),
} }
@@ -332,6 +335,7 @@ func (g *GPU) BeginFrame() {
if g.drawOps.profile { if g.drawOps.profile {
g.zopsTimer.begin() g.zopsTimer.begin()
} }
g.ctx.BindFramebuffer(g.defFBO)
g.ctx.DepthFunc(DepthFuncGreater) g.ctx.DepthFunc(DepthFuncGreater)
g.ctx.ClearColor(g.drawOps.clearColor[0], g.drawOps.clearColor[1], g.drawOps.clearColor[2], 1.0) g.ctx.ClearColor(g.drawOps.clearColor[0], g.drawOps.clearColor[1], g.drawOps.clearColor[2], 1.0)
g.ctx.ClearDepth(0.0) g.ctx.ClearDepth(0.0)
@@ -347,6 +351,7 @@ func (g *GPU) BeginFrame() {
g.renderer.intersect(g.drawOps.imageOps) g.renderer.intersect(g.drawOps.imageOps)
g.stencilTimer.end() g.stencilTimer.end()
g.coverTimer.begin() g.coverTimer.begin()
g.ctx.BindFramebuffer(g.defFBO)
g.ctx.Viewport(0, 0, viewport.X, viewport.Y) g.ctx.Viewport(0, 0, viewport.X, viewport.Y)
g.renderer.drawOps(g.drawOps.imageOps) g.renderer.drawOps(g.drawOps.imageOps)
g.ctx.SetBlend(false) g.ctx.SetBlend(false)
@@ -502,7 +507,6 @@ func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) {
data, _ := pathCache.get(p.pathKey) data, _ := pathCache.get(p.pathKey)
r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData)) r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData))
} }
r.pather.end()
} }
func (r *renderer) intersect(ops []imageOp) { func (r *renderer) intersect(ops []imageOp) {
@@ -526,7 +530,6 @@ func (r *renderer) intersect(ops []imageOp) {
r.ctx.Viewport(img.place.Pos.X, img.place.Pos.Y, img.clip.Dx(), img.clip.Dy()) r.ctx.Viewport(img.place.Pos.X, img.place.Pos.Y, img.clip.Dx(), img.clip.Dy())
r.intersectPath(img.path, img.clip) r.intersectPath(img.path, img.clip)
} }
r.pather.stenciler.endIntersect()
} }
func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) { func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) {
+2 -18
View File
@@ -56,9 +56,8 @@ type coverUniforms struct {
} }
type stenciler struct { type stenciler struct {
ctx Backend ctx Backend
defFBO Framebuffer prog struct {
prog struct {
prog *program prog *program
uniforms struct { uniforms struct {
vert struct { vert struct {
@@ -138,7 +137,6 @@ func newCoverer(ctx Backend) *coverer {
} }
func newStenciler(ctx Backend) *stenciler { func newStenciler(ctx Backend) *stenciler {
defFBO := ctx.DefaultFramebuffer()
// Allocate a suitably large index buffer for drawing paths. // Allocate a suitably large index buffer for drawing paths.
indices := make([]uint16, pathBatchSize*6) indices := make([]uint16, pathBatchSize*6)
for i := 0; i < pathBatchSize; i++ { for i := 0; i < pathBatchSize; i++ {
@@ -173,7 +171,6 @@ func newStenciler(ctx Backend) *stenciler {
} }
st := &stenciler{ st := &stenciler{
ctx: ctx, ctx: ctx,
defFBO: defFBO,
indexBuf: indexBuf, indexBuf: indexBuf,
} }
prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag) prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag)
@@ -281,10 +278,6 @@ func (p *pather) begin(sizes []image.Point) {
p.stenciler.begin(sizes) p.stenciler.begin(sizes)
} }
func (p *pather) end() {
p.stenciler.end()
}
func (p *pather) stencilPath(bounds image.Rectangle, offset f32.Point, uv image.Point, data *pathData) { func (p *pather) stencilPath(bounds image.Rectangle, offset f32.Point, uv image.Point, data *pathData) {
p.stenciler.stencilPath(bounds, offset, uv, data) p.stenciler.stencilPath(bounds, offset, uv, data)
} }
@@ -299,14 +292,9 @@ func (s *stenciler) beginIntersect(sizes []image.Point) {
s.ctx.BindProgram(s.iprog.prog.prog) s.ctx.BindProgram(s.iprog.prog.prog)
} }
func (s *stenciler) endIntersect() {
s.ctx.BindFramebuffer(s.defFBO)
}
func (s *stenciler) invalidateFBO() { func (s *stenciler) invalidateFBO() {
s.intersections.invalidate(s.ctx) s.intersections.invalidate(s.ctx)
s.fbos.invalidate(s.ctx) s.fbos.invalidate(s.ctx)
s.ctx.BindFramebuffer(s.defFBO)
} }
func (s *stenciler) cover(idx int) stencilFBO { func (s *stenciler) cover(idx int) stencilFBO {
@@ -347,10 +335,6 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima
} }
} }
func (s *stenciler) end() {
s.ctx.BindFramebuffer(s.defFBO)
}
func (p *pather) cover(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff, coverScale, coverOff f32.Point) { func (p *pather) cover(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff, coverScale, coverOff f32.Point) {
p.coverer.cover(z, mat, col, scale, off, uvScale, uvOff, coverScale, coverOff) p.coverer.cover(z, mat, col, scale, off, uvScale, uvOff, coverScale, coverOff)
} }