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];
unsigned _currentBuffer;
GB_frame_blending_mode_t _frameBlendingMode;
bool _oddFrame;
}
- (void)screenSizeChanged
@@ -23,6 +24,7 @@
- (void)flip
{
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
_oddFrame = GB_is_odd_frame(_gb);
}
- (unsigned) numberOfBuffers
@@ -62,7 +64,7 @@
if (!_gb || GB_is_sgb(_gb)) {
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;
}

View File

@@ -160,22 +160,44 @@ static const vector_float2 rect[] =
{texture.width, texture.height, 1} // MTLSize
};
[texture replaceRegion:region
mipmapLevel:0
withBytes:[self currentBuffer]
bytesPerRow:texture.width * 4];
if ([self frameBlendingMode]) {
GB_frame_blending_mode_t mode = [self frameBlendingMode];
switch (mode) {
case GB_FRAME_BLENDING_MODE_SIMPLE:
case GB_FRAME_BLENDING_MODE_ACCURATE_EVEN:
[previous_texture replaceRegion:region
mipmapLevel:0
withBytes:[self previousBuffer]
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;
id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer];
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;
id<MTLRenderCommandEncoder> render_encoder =

View File

@@ -703,7 +703,7 @@
</toolbarItem>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="AoG-LH-J4b"/>
<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"/>
<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"/>