mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 15:45:38 +00:00
gpu,gpu/backend: don't assume constant output framebuffer
Return the output framebuffer from BeginFrame, to make it clear that it may change between frames. Delete CurrentFramebuffer which is no longer needed. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -274,7 +274,8 @@ func NewBackend(d *Device) (*Backend, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *Backend) BeginFrame() {
|
||||
func (b *Backend) BeginFrame() backend.Framebuffer {
|
||||
return b.currentFramebuffer()
|
||||
}
|
||||
|
||||
func (b *Backend) EndFrame() {
|
||||
@@ -368,13 +369,13 @@ func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, mi
|
||||
return &Texture{backend: b, format: d3dfmt, tex: tex, sampler: sampler, resView: resView, bindings: bindings, width: width, height: height}, nil
|
||||
}
|
||||
|
||||
func (b *Backend) CurrentFramebuffer() backend.Framebuffer {
|
||||
func (b *Backend) currentFramebuffer() backend.Framebuffer {
|
||||
renderTarget := b.dev.ctx.OMGetRenderTargets()
|
||||
if renderTarget != nil {
|
||||
// Assume someone else is holding on to it.
|
||||
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
|
||||
}
|
||||
if renderTarget == b.fbo.renderTarget {
|
||||
if b.fbo != nil && renderTarget == b.fbo.renderTarget {
|
||||
return b.fbo
|
||||
}
|
||||
return &Framebuffer{dev: b.dev, renderTarget: renderTarget, foreign: true}
|
||||
@@ -823,7 +824,7 @@ func (f *Framebuffer) Invalidate() {
|
||||
|
||||
func (f *Framebuffer) Release() {
|
||||
if f.foreign {
|
||||
panic("cannot release Framebuffer from CurrentFramebuffer")
|
||||
panic("framebuffer not created by NewBuffer")
|
||||
}
|
||||
if f.renderTarget != nil {
|
||||
_IUnknownRelease(unsafe.Pointer(f.renderTarget), f.renderTarget.vtbl.Release)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
// APIs such as OpenGL, Direct3D useful for rendering Gio
|
||||
// operations.
|
||||
type Device interface {
|
||||
BeginFrame()
|
||||
BeginFrame() Framebuffer
|
||||
EndFrame()
|
||||
Caps() Caps
|
||||
NewTimer() Timer
|
||||
@@ -20,7 +20,6 @@ type Device interface {
|
||||
// are valid at the point of call.
|
||||
IsTimeContinuous() bool
|
||||
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
|
||||
CurrentFramebuffer() Framebuffer
|
||||
NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error)
|
||||
NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
|
||||
NewBuffer(typ BufferBinding, size int) (Buffer, error)
|
||||
|
||||
+2
-4
@@ -29,7 +29,6 @@ type compute struct {
|
||||
cache *resourceCache
|
||||
maxTextureDim int
|
||||
|
||||
defFBO backend.Framebuffer
|
||||
programs struct {
|
||||
elements backend.Program
|
||||
tileAlloc backend.Program
|
||||
@@ -197,7 +196,6 @@ func newCompute(ctx backend.Device) (*compute, error) {
|
||||
}
|
||||
g := &compute{
|
||||
ctx: ctx,
|
||||
defFBO: ctx.CurrentFramebuffer(),
|
||||
cache: newResourceCache(),
|
||||
maxTextureDim: maxDim,
|
||||
conf: new(config),
|
||||
@@ -290,7 +288,7 @@ func (g *compute) Frame() error {
|
||||
Y: (viewport.Y + tileHeightPx - 1) / tileHeightPx,
|
||||
}
|
||||
|
||||
g.ctx.BeginFrame()
|
||||
defFBO := g.ctx.BeginFrame()
|
||||
defer g.ctx.EndFrame()
|
||||
|
||||
if err := g.uploadImages(g.drawOps.allImageOps); err != nil {
|
||||
@@ -305,6 +303,7 @@ func (g *compute) Frame() error {
|
||||
if err := g.render(tileDims); err != nil {
|
||||
return err
|
||||
}
|
||||
g.ctx.BindFramebuffer(defFBO)
|
||||
g.blitOutput(viewport)
|
||||
g.cache.frame()
|
||||
g.drawOps.pathCache.frame()
|
||||
@@ -331,7 +330,6 @@ func (g *compute) Profile() string {
|
||||
// shader can only write to RGBA textures, but since we actually render in sRGB
|
||||
// format we can't use glBlitFramebuffer, because it does sRGB conversion.
|
||||
func (g *compute) blitOutput(viewport image.Point) {
|
||||
g.ctx.BindFramebuffer(g.defFBO)
|
||||
g.ctx.Viewport(0, 0, viewport.X, viewport.Y)
|
||||
g.ctx.BindTexture(0, g.output.image)
|
||||
g.ctx.BindProgram(g.output.blitProg)
|
||||
|
||||
+4
-3
@@ -167,9 +167,10 @@ func NewBackend(ctx Context) (*Backend, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *Backend) BeginFrame() {
|
||||
func (b *Backend) BeginFrame() backend.Framebuffer {
|
||||
// Assume GL state is reset between frames.
|
||||
b.state = glstate{}
|
||||
return b.currentFramebuffer()
|
||||
}
|
||||
|
||||
func (b *Backend) EndFrame() {
|
||||
@@ -228,7 +229,7 @@ func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Fr
|
||||
return fbo, nil
|
||||
}
|
||||
|
||||
func (b *Backend) CurrentFramebuffer() backend.Framebuffer {
|
||||
func (b *Backend) currentFramebuffer() backend.Framebuffer {
|
||||
fboID := glimpl.Framebuffer(b.funcs.GetBinding(glimpl.FRAMEBUFFER_BINDING))
|
||||
return &gpuFramebuffer{backend: b, obj: fboID, foreign: true}
|
||||
}
|
||||
@@ -802,7 +803,7 @@ func (f *gpuFramebuffer) Invalidate() {
|
||||
|
||||
func (f *gpuFramebuffer) Release() {
|
||||
if f.foreign {
|
||||
panic("cannot release framebuffer created by CurrentFramebuffer")
|
||||
panic("framebuffer not created by NewBuffer")
|
||||
}
|
||||
f.backend.funcs.DeleteFramebuffer(f.obj)
|
||||
if f.hasDepth {
|
||||
|
||||
+5
-8
@@ -48,7 +48,6 @@ type GPU interface {
|
||||
type gpu struct {
|
||||
cache *resourceCache
|
||||
|
||||
defFBO backend.Framebuffer
|
||||
profile string
|
||||
timers *timers
|
||||
frameStart time.Time
|
||||
@@ -395,10 +394,8 @@ func New(ctx backend.Device) (GPU, error) {
|
||||
}
|
||||
|
||||
func newGPU(ctx backend.Device) (*gpu, error) {
|
||||
defFBO := ctx.CurrentFramebuffer()
|
||||
g := &gpu{
|
||||
defFBO: defFBO,
|
||||
cache: newResourceCache(),
|
||||
cache: newResourceCache(),
|
||||
}
|
||||
g.drawOps.pathCache = newOpCache()
|
||||
if err := g.init(ctx); err != nil {
|
||||
@@ -443,7 +440,7 @@ func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) {
|
||||
}
|
||||
|
||||
func (g *gpu) Frame() error {
|
||||
g.ctx.BeginFrame()
|
||||
defFBO := g.ctx.BeginFrame()
|
||||
defer g.ctx.EndFrame()
|
||||
viewport := g.renderer.blitter.viewport
|
||||
for _, img := range g.drawOps.imageOps {
|
||||
@@ -452,7 +449,7 @@ func (g *gpu) Frame() error {
|
||||
if g.drawOps.profile {
|
||||
g.zopsTimer.begin()
|
||||
}
|
||||
g.ctx.BindFramebuffer(g.defFBO)
|
||||
g.ctx.BindFramebuffer(defFBO)
|
||||
g.ctx.DepthFunc(backend.DepthFuncGreater)
|
||||
// Note that Clear must be before ClearDepth if nothing else is rendered
|
||||
// (len(zimageOps) == 0). If not, the Fairphone 2 will corrupt the depth buffer.
|
||||
@@ -472,13 +469,13 @@ func (g *gpu) Frame() error {
|
||||
g.renderer.intersect(g.drawOps.imageOps)
|
||||
g.stencilTimer.end()
|
||||
g.coverTimer.begin()
|
||||
g.ctx.BindFramebuffer(g.defFBO)
|
||||
g.ctx.BindFramebuffer(defFBO)
|
||||
g.ctx.Viewport(0, 0, viewport.X, viewport.Y)
|
||||
g.renderer.drawOps(g.cache, g.drawOps.imageOps)
|
||||
g.ctx.SetBlend(false)
|
||||
g.renderer.pather.stenciler.invalidateFBO()
|
||||
g.coverTimer.end()
|
||||
g.ctx.BindFramebuffer(g.defFBO)
|
||||
g.ctx.BindFramebuffer(defFBO)
|
||||
g.cleanupTimer.begin()
|
||||
g.cache.frame()
|
||||
g.drawOps.pathCache.frame()
|
||||
|
||||
Reference in New Issue
Block a user