Fix a bug where the Metal renderer would sometimes flicker in the Cocoa/iOS frontends

This commit is contained in:
Lior Halphon
2024-01-13 15:49:37 +02:00
parent 686a506e17
commit a9c01d35fc
3 changed files with 37 additions and 13 deletions

View File

@@ -5,6 +5,7 @@
uint32_t *_imageBuffers[3]; uint32_t *_imageBuffers[3];
unsigned _currentBuffer; unsigned _currentBuffer;
GB_frame_blending_mode_t _frameBlendingMode; GB_frame_blending_mode_t _frameBlendingMode;
bool _oddFrame;
} }
- (void)screenSizeChanged - (void)screenSizeChanged
@@ -23,6 +24,7 @@
- (void)flip - (void)flip
{ {
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers; _currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
_oddFrame = GB_is_odd_frame(_gb);
} }
- (unsigned) numberOfBuffers - (unsigned) numberOfBuffers
@@ -62,7 +64,7 @@
if (!_gb || GB_is_sgb(_gb)) { if (!_gb || GB_is_sgb(_gb)) {
return GB_FRAME_BLENDING_MODE_SIMPLE; return GB_FRAME_BLENDING_MODE_SIMPLE;
} }
return GB_is_odd_frame(_gb)? GB_FRAME_BLENDING_MODE_ACCURATE_ODD : GB_FRAME_BLENDING_MODE_ACCURATE_EVEN; return _oddFrame ? GB_FRAME_BLENDING_MODE_ACCURATE_ODD : GB_FRAME_BLENDING_MODE_ACCURATE_EVEN;
} }
return _frameBlendingMode; return _frameBlendingMode;
} }

View File

@@ -85,7 +85,7 @@ static const vector_float2 rect[] =
#endif #endif
} }
- (void) loadShader - (void)loadShader
{ {
NSError *error = nil; NSError *error = nil;
NSString *shader_source = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MasterShader" NSString *shader_source = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MasterShader"
@@ -160,22 +160,44 @@ static const vector_float2 rect[] =
{texture.width, texture.height, 1} // MTLSize {texture.width, texture.height, 1} // MTLSize
}; };
[texture replaceRegion:region GB_frame_blending_mode_t mode = [self frameBlendingMode];
mipmapLevel:0
withBytes:[self currentBuffer] switch (mode) {
bytesPerRow:texture.width * 4]; case GB_FRAME_BLENDING_MODE_SIMPLE:
if ([self frameBlendingMode]) { case GB_FRAME_BLENDING_MODE_ACCURATE_EVEN:
[previous_texture replaceRegion:region [previous_texture replaceRegion:region
mipmapLevel:0 mipmapLevel:0
withBytes:[self previousBuffer] withBytes:[self previousBuffer]
bytesPerRow:texture.width * 4]; bytesPerRow:texture.width * 4];
case GB_FRAME_BLENDING_MODE_DISABLED:
[texture replaceRegion:region
mipmapLevel:0
withBytes:[self currentBuffer]
bytesPerRow:texture.width * 4];
break;
case GB_FRAME_BLENDING_MODE_ACCURATE_ODD:
/*
I don't understand GPUs. When rapidly changing `mode`, the shader might sometimes incorrectly
use the old value. I couldn't figure out how to fix it, so I just work around the issue by
avoiding rapid changes in `mode`.
*/
mode = GB_FRAME_BLENDING_MODE_ACCURATE_EVEN;
[previous_texture replaceRegion:region
mipmapLevel:0
withBytes:[self currentBuffer]
bytesPerRow:texture.width * 4];
[texture replaceRegion:region
mipmapLevel:0
withBytes:[self previousBuffer]
bytesPerRow:texture.width * 4];
break;
} }
MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor;
id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer]; id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer];
if (render_pass_descriptor) { if (render_pass_descriptor) {
*(GB_frame_blending_mode_t *)[frame_blending_mode_buffer contents] = [self frameBlendingMode]; *(GB_frame_blending_mode_t *)[frame_blending_mode_buffer contents] = mode;
*(vector_float2 *)[output_resolution_buffer contents] = output_resolution; *(vector_float2 *)[output_resolution_buffer contents] = output_resolution;
id<MTLRenderCommandEncoder> render_encoder = id<MTLRenderCommandEncoder> render_encoder =

View File

@@ -703,7 +703,7 @@
</toolbarItem> </toolbarItem>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="AoG-LH-J4b"/> <toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="AoG-LH-J4b"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="Q0x-n5-Q2Y"/> <toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="Q0x-n5-Q2Y"/>
<toolbarItem implicitItemIdentifier="E8F74F8F-6DE2-4774-A690-F71D92CD932E" label="" paletteLabel="" tag="-1" title="wtf" sizingBehavior="auto" id="CJX-Ff-7iQ"> <toolbarItem implicitItemIdentifier="E8F74F8F-6DE2-4774-A690-F71D92CD932E" label="" paletteLabel="" tag="-1" sizingBehavior="auto" id="CJX-Ff-7iQ">
<nil key="toolTip"/> <nil key="toolTip"/>
<progressIndicator key="view" wantsLayer="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" id="rrz-Uh-Nae"> <progressIndicator key="view" wantsLayer="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" id="rrz-Uh-Nae">
<rect key="frame" x="0.0" y="14" width="16" height="16"/> <rect key="frame" x="0.0" y="14" width="16" height="16"/>