mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/graphicsdriver/metal: Make FPS stable by 'presentsWithTransaction'
Closes #1196
This commit is contained in:
parent
ae0e30196b
commit
4573883b03
@ -147,6 +147,13 @@ func (ml MetalLayer) NextDrawable() (MetalDrawable, error) {
|
||||
return MetalDrawable{md}, nil
|
||||
}
|
||||
|
||||
// PresentsWithTransaction returns a Boolean value that determines whether the layer presents its content using a Core Animation transaction.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction
|
||||
func (ml MetalLayer) PresentsWithTransaction() bool {
|
||||
return C.MetalLayer_PresentsWithTransaction(ml.metalLayer) != 0
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -175,3 +182,10 @@ func (md MetalDrawable) Drawable() unsafe.Pointer { return md.metalDrawable }
|
||||
func (md MetalDrawable) Texture() mtl.Texture {
|
||||
return mtl.NewTexture(C.MetalDrawable_Texture(md.metalDrawable))
|
||||
}
|
||||
|
||||
// Present presents the drawable onscreen as soon as possible.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldrawable/1470284-present.
|
||||
func (md MetalDrawable) Present() {
|
||||
C.MetalDrawable_Present(md.metalDrawable)
|
||||
}
|
||||
|
@ -31,5 +31,7 @@ void MetalLayer_SetDisplaySyncEnabled(void *metalLayer,
|
||||
void MetalLayer_SetDrawableSize(void *metalLayer, double width, double height);
|
||||
void *MetalLayer_NextDrawable(void *metalLayer);
|
||||
void MetalLayer_SetFramebufferOnly(void *metalLayer, uint8_t framebufferOnly);
|
||||
uint8_t MetalLayer_PresentsWithTransaction(void *metalLayer);
|
||||
|
||||
void *MetalDrawable_Texture(void *drawable);
|
||||
void MetalDrawable_Present(void *drawable);
|
||||
|
@ -85,6 +85,14 @@ void MetalLayer_SetDisplaySyncEnabled(void *metalLayer,
|
||||
[((CAMetalLayer *)metalLayer) setDisplaySyncEnabled:displaySyncEnabled];
|
||||
}
|
||||
#endif
|
||||
|
||||
// setting presentsWithTransaction YES makes the FPS stable (#1196). We're not
|
||||
// sure why...
|
||||
if (displaySyncEnabled) {
|
||||
[((CAMetalLayer *)metalLayer) setPresentsWithTransaction:YES];
|
||||
} else {
|
||||
[((CAMetalLayer *)metalLayer) setPresentsWithTransaction:NO];
|
||||
}
|
||||
}
|
||||
|
||||
void MetalLayer_SetDrawableSize(void *metalLayer, double width, double height) {
|
||||
@ -99,6 +107,14 @@ void *MetalDrawable_Texture(void *metalDrawable) {
|
||||
return ((id<CAMetalDrawable>)metalDrawable).texture;
|
||||
}
|
||||
|
||||
void MetalDrawable_Present(void *metalDrawable) {
|
||||
[((id<CAMetalDrawable>)metalDrawable) present];
|
||||
}
|
||||
|
||||
void MetalLayer_SetFramebufferOnly(void *metalLayer, uint8_t framebufferOnly) {
|
||||
[((CAMetalLayer *)metalLayer) setFramebufferOnly:framebufferOnly];
|
||||
}
|
||||
|
||||
uint8_t MetalLayer_PresentsWithTransaction(void *metalLayer) {
|
||||
return [((CAMetalLayer *)metalLayer) presentsWithTransaction];
|
||||
}
|
||||
|
@ -467,10 +467,14 @@ func (g *Graphics) flushIfNeeded(present bool) {
|
||||
}
|
||||
g.flushRenderCommandEncoderIfNeeded()
|
||||
|
||||
if present && g.screenDrawable != (ca.MetalDrawable{}) {
|
||||
if !g.view.presentsWithTransaction() && present && g.screenDrawable != (ca.MetalDrawable{}) {
|
||||
g.cb.PresentDrawable(g.screenDrawable)
|
||||
}
|
||||
g.cb.Commit()
|
||||
if g.view.presentsWithTransaction() && present && g.screenDrawable != (ca.MetalDrawable{}) {
|
||||
g.cb.WaitUntilScheduled()
|
||||
g.screenDrawable.Present()
|
||||
}
|
||||
|
||||
for _, t := range g.tmpTextures {
|
||||
t.Release()
|
||||
|
@ -670,6 +670,13 @@ func (cb CommandBuffer) WaitUntilCompleted() {
|
||||
C.CommandBuffer_WaitUntilCompleted(cb.commandBuffer)
|
||||
}
|
||||
|
||||
// WaitUntilScheduled blocks execution of the current thread until the command buffer is scheduled.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443036-waituntilscheduled.
|
||||
func (cb CommandBuffer) WaitUntilScheduled() {
|
||||
C.CommandBuffer_WaitUntilScheduled(cb.commandBuffer)
|
||||
}
|
||||
|
||||
// MakeRenderCommandEncoder creates an encoder object that can
|
||||
// encode graphics rendering commands into this command buffer.
|
||||
//
|
||||
|
@ -153,6 +153,7 @@ uint8_t CommandBuffer_Status(void *commandBuffer);
|
||||
void CommandBuffer_PresentDrawable(void *commandBuffer, void *drawable);
|
||||
void CommandBuffer_Commit(void *commandBuffer);
|
||||
void CommandBuffer_WaitUntilCompleted(void *commandBuffer);
|
||||
void CommandBuffer_WaitUntilScheduled(void *commandBuffer);
|
||||
void *
|
||||
CommandBuffer_MakeRenderCommandEncoder(void *commandBuffer,
|
||||
struct RenderPassDescriptor descriptor);
|
||||
|
@ -188,6 +188,10 @@ void CommandBuffer_WaitUntilCompleted(void *commandBuffer) {
|
||||
[(id<MTLCommandBuffer>)commandBuffer waitUntilCompleted];
|
||||
}
|
||||
|
||||
void CommandBuffer_WaitUntilScheduled(void *commandBuffer) {
|
||||
[(id<MTLCommandBuffer>)commandBuffer waitUntilScheduled];
|
||||
}
|
||||
|
||||
void *
|
||||
CommandBuffer_MakeRenderCommandEncoder(void *commandBuffer,
|
||||
struct RenderPassDescriptor descriptor) {
|
||||
|
@ -69,7 +69,10 @@ func (v *view) reset() error {
|
||||
// MTLPixelFormatBGRA8Unorm_sRGB, MTLPixelFormatRGBA16Float, MTLPixelFormatBGRA10_XR, or
|
||||
// MTLPixelFormatBGRA10_XR_sRGB.
|
||||
v.ml.SetPixelFormat(mtl.PixelFormatBGRA8UNorm)
|
||||
v.ml.SetMaximumDrawableCount(3)
|
||||
|
||||
// When presentsWithTransaction is YES and triple buffering is enabled, nextDrawing returns immediately once every two times.
|
||||
// This makes FPS doubled. To avoid this, disable the triple buffering.
|
||||
v.ml.SetMaximumDrawableCount(2)
|
||||
|
||||
// The vsync state might be reset. Set the state again (#1364).
|
||||
v.ml.SetDisplaySyncEnabled(v.vsync)
|
||||
@ -86,3 +89,7 @@ func (v *view) nextDrawable() ca.MetalDrawable {
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func (v *view) presentsWithTransaction() bool {
|
||||
return v.ml.PresentsWithTransaction()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user