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.
IsTimeContinuous() bool
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
DefaultFramebuffer() Framebuffer
CurrentFramebuffer() Framebuffer
NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error)
NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
NewBuffer(typ BufferBinding, size int) (Buffer, error)
+9 -7
View File
@@ -15,8 +15,7 @@ import (
// Backend implements gpu.Backend.
type Backend struct {
funcs Functions
defFBO *gpuFramebuffer
funcs Functions
state glstate
@@ -59,10 +58,11 @@ type gpuTexture struct {
}
type gpuFramebuffer struct {
backend *Backend
backend *Backend
obj Framebuffer
hasDepth bool
depthBuf Renderbuffer
foreign bool
}
type gpuBuffer struct {
@@ -127,14 +127,12 @@ func NewBackend(f Functions) (*Backend, error) {
if err != nil {
return nil, err
}
defFBO := Framebuffer(f.GetBinding(FRAMEBUFFER_BINDING))
b := &Backend{
funcs: f,
floatTriple: floatTriple,
alphaTriple: alphaTripleFor(ver),
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") {
b.feats.Features |= gpu.FeatureTimers
}
@@ -202,8 +200,9 @@ func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffe
return fbo, nil
}
func (b *Backend) DefaultFramebuffer() gpu.Framebuffer {
return b.defFBO
func (b *Backend) CurrentFramebuffer() gpu.Framebuffer {
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) {
@@ -612,6 +611,9 @@ func (f *gpuFramebuffer) Invalidate() {
}
func (f *gpuFramebuffer) Release() {
if f.foreign {
panic("cannot release framebuffer created by CurrentFramebuffer")
}
f.backend.funcs.DeleteFramebuffer(f.obj)
if f.hasDepth {
f.backend.funcs.DeleteRenderbuffer(f.depthBuf)
+5 -2
View File
@@ -30,6 +30,7 @@ type GPU struct {
pathCache *opCache
cache *resourceCache
defFBO Framebuffer
profile string
timers *timers
frameStart time.Time
@@ -275,7 +276,9 @@ const (
)
func New(ctx Backend) (*GPU, error) {
defFBO := ctx.CurrentFramebuffer()
g := &GPU{
defFBO: defFBO,
pathCache: newOpCache(),
cache: newResourceCache(),
}
@@ -332,6 +335,7 @@ func (g *GPU) BeginFrame() {
if g.drawOps.profile {
g.zopsTimer.begin()
}
g.ctx.BindFramebuffer(g.defFBO)
g.ctx.DepthFunc(DepthFuncGreater)
g.ctx.ClearColor(g.drawOps.clearColor[0], g.drawOps.clearColor[1], g.drawOps.clearColor[2], 1.0)
g.ctx.ClearDepth(0.0)
@@ -347,6 +351,7 @@ func (g *GPU) BeginFrame() {
g.renderer.intersect(g.drawOps.imageOps)
g.stencilTimer.end()
g.coverTimer.begin()
g.ctx.BindFramebuffer(g.defFBO)
g.ctx.Viewport(0, 0, viewport.X, viewport.Y)
g.renderer.drawOps(g.drawOps.imageOps)
g.ctx.SetBlend(false)
@@ -502,7 +507,6 @@ func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) {
data, _ := pathCache.get(p.pathKey)
r.pather.stencilPath(p.clip, p.off, p.place.Pos, data.(*pathData))
}
r.pather.end()
}
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.intersectPath(img.path, img.clip)
}
r.pather.stenciler.endIntersect()
}
func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) {
+2 -18
View File
@@ -56,9 +56,8 @@ type coverUniforms struct {
}
type stenciler struct {
ctx Backend
defFBO Framebuffer
prog struct {
ctx Backend
prog struct {
prog *program
uniforms struct {
vert struct {
@@ -138,7 +137,6 @@ func newCoverer(ctx Backend) *coverer {
}
func newStenciler(ctx Backend) *stenciler {
defFBO := ctx.DefaultFramebuffer()
// Allocate a suitably large index buffer for drawing paths.
indices := make([]uint16, pathBatchSize*6)
for i := 0; i < pathBatchSize; i++ {
@@ -173,7 +171,6 @@ func newStenciler(ctx Backend) *stenciler {
}
st := &stenciler{
ctx: ctx,
defFBO: defFBO,
indexBuf: indexBuf,
}
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)
}
func (p *pather) end() {
p.stenciler.end()
}
func (p *pather) stencilPath(bounds image.Rectangle, offset f32.Point, uv image.Point, data *pathData) {
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)
}
func (s *stenciler) endIntersect() {
s.ctx.BindFramebuffer(s.defFBO)
}
func (s *stenciler) invalidateFBO() {
s.intersections.invalidate(s.ctx)
s.fbos.invalidate(s.ctx)
s.ctx.BindFramebuffer(s.defFBO)
}
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) {
p.coverer.cover(z, mat, col, scale, off, uvScale, uvOff, coverScale, coverOff)
}