From 9cb1ff9ceae7cfa782620a1f1f3d9ddc79347928 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 7 Jul 2021 00:38:50 +0900 Subject: [PATCH] internal/graphicsdriver/metal: Set framebufferOnly true Updates #1196 --- internal/graphicsdriver/metal/ca/ca.go | 12 ++++++++++++ internal/graphicsdriver/metal/ca/ca.h | 1 + internal/graphicsdriver/metal/ca/ca.m | 4 ++++ internal/graphicsdriver/metal/graphics.go | 2 +- internal/graphicsdriver/metal/view.go | 4 +++- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/internal/graphicsdriver/metal/ca/ca.go b/internal/graphicsdriver/metal/ca/ca.go index 860d99790..008021acc 100644 --- a/internal/graphicsdriver/metal/ca/ca.go +++ b/internal/graphicsdriver/metal/ca/ca.go @@ -147,6 +147,18 @@ func (ml MetalLayer) NextDrawable() (MetalDrawable, error) { return MetalDrawable{md}, nil } +// SetFramebufferOnly sets a Boolean value that determines whether the layer’s textures are used only for rendering. +// +// https://developer.apple.com/documentation/quartzcore/cametallayer/1478168-framebufferonly +func (ml MetalLayer) SetFramebufferOnly(framebufferOnly bool) { + switch framebufferOnly { + case true: + C.MetalLayer_SetFramebufferOnly(ml.metalLayer, 1) + case false: + C.MetalLayer_SetFramebufferOnly(ml.metalLayer, 0) + } +} + // MetalDrawable is a displayable resource that can be rendered or written to by Metal. // // Reference: https://developer.apple.com/documentation/quartzcore/cametaldrawable. diff --git a/internal/graphicsdriver/metal/ca/ca.h b/internal/graphicsdriver/metal/ca/ca.h index a4e1e35d5..9b5dab957 100644 --- a/internal/graphicsdriver/metal/ca/ca.h +++ b/internal/graphicsdriver/metal/ca/ca.h @@ -30,5 +30,6 @@ void MetalLayer_SetDisplaySyncEnabled(void *metalLayer, uint8_t displaySyncEnabled); void MetalLayer_SetDrawableSize(void *metalLayer, double width, double height); void *MetalLayer_NextDrawable(void *metalLayer); +void MetalLayer_SetFramebufferOnly(void *metalLayer, uint8_t framebufferOnly); void *MetalDrawable_Texture(void *drawable); diff --git a/internal/graphicsdriver/metal/ca/ca.m b/internal/graphicsdriver/metal/ca/ca.m index 2ae631835..0ceeb7eb2 100644 --- a/internal/graphicsdriver/metal/ca/ca.m +++ b/internal/graphicsdriver/metal/ca/ca.m @@ -98,3 +98,7 @@ void *MetalLayer_NextDrawable(void *metalLayer) { void *MetalDrawable_Texture(void *metalDrawable) { return ((id)metalDrawable).texture; } + +void MetalLayer_SetFramebufferOnly(void *metalLayer, uint8_t framebufferOnly) { + [((CAMetalLayer *)metalLayer) setFramebufferOnly:framebufferOnly]; +} diff --git a/internal/graphicsdriver/metal/graphics.go b/internal/graphicsdriver/metal/graphics.go index fa3f689e7..2095ce32a 100644 --- a/internal/graphicsdriver/metal/graphics.go +++ b/internal/graphicsdriver/metal/graphics.go @@ -1215,7 +1215,7 @@ func (i *Image) mtlTexture() mtl.Texture { if i.screen { g := i.graphics if g.screenDrawable == (ca.MetalDrawable{}) { - drawable := g.view.drawable() + drawable := g.view.nextDrawable() if drawable == (ca.MetalDrawable{}) { return mtl.Texture{} } diff --git a/internal/graphicsdriver/metal/view.go b/internal/graphicsdriver/metal/view.go index a2b199462..c221d12a2 100644 --- a/internal/graphicsdriver/metal/view.go +++ b/internal/graphicsdriver/metal/view.go @@ -73,10 +73,12 @@ func (v *view) reset() error { // The vsync state might be reset. Set the state again (#1364). v.ml.SetDisplaySyncEnabled(v.vsync) + v.ml.SetFramebufferOnly(true) + return nil } -func (v *view) drawable() ca.MetalDrawable { +func (v *view) nextDrawable() ca.MetalDrawable { d, err := v.ml.NextDrawable() if err != nil { // Drawable is nil. This can happen at the initial state. Let's wait and see.