internal/graphicsdriver/metal: Delay to get a texture for nextDrawable

See https://developer.apple.com/documentation/quartzcore/cametallayer

> To avoid stalls in your app, request a new drawable only when you
> need it, and release any references to it as quickly as possible
> after you’re done with it.

Updates #1196
This commit is contained in:
Hajime Hoshi 2021-07-08 01:56:12 +09:00
parent b314b6b9b6
commit edc2f8b961

View File

@ -320,7 +320,7 @@ type Graphics struct {
buffers map[mtl.CommandBuffer][]mtl.Buffer
unusedBuffers map[mtl.Buffer]struct{}
lastDstTexture mtl.Texture
lastDst *Image
lastStencilMode stencilMode
vb mtl.Buffer
@ -777,16 +777,17 @@ func (g *Graphics) flushRenderCommandEncoderIfNeeded() {
}
g.rce.EndEncoding()
g.rce = mtl.RenderCommandEncoder{}
g.lastDstTexture = mtl.Texture{}
g.lastDst = nil
}
func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion driver.Region, srcs [graphics.ShaderImageNum]*Image, indexLen int, indexOffset int, uniforms []interface{}, stencilMode stencilMode) error {
// When prepareing a stencil buffer, flush the current render command encoder
// to make sure the stencil buffer is cleared when loading.
// TODO: What about clearing the stencil buffer by vertices?
if g.lastDstTexture != dst.mtlTexture() || (g.lastStencilMode == noStencil) != (stencilMode == noStencil) || stencilMode == prepareStencil {
if g.lastDst != dst || (g.lastStencilMode == noStencil) != (stencilMode == noStencil) || stencilMode == prepareStencil {
g.flushRenderCommandEncoderIfNeeded()
}
g.lastDst = dst
g.lastStencilMode = stencilMode
if g.rce == (mtl.RenderCommandEncoder{}) {
@ -802,7 +803,6 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion drive
}
t := dst.mtlTexture()
g.lastDstTexture = t
if t == (mtl.Texture{}) {
return nil
}