mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-03 06:13:23 +02:00
Fix a bug where the Metal renderer would sometimes flicker in the Cocoa/iOS frontends
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ static const vector_float2 rect[] =
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) loadShader
|
||||
- (void)loadShader
|
||||
{
|
||||
NSError *error = nil;
|
||||
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 replaceRegion:region
|
||||
mipmapLevel:0
|
||||
withBytes:[self currentBuffer]
|
||||
bytesPerRow:texture.width * 4];
|
||||
if ([self frameBlendingMode]) {
|
||||
[previous_texture replaceRegion:region
|
||||
mipmapLevel:0
|
||||
withBytes:[self previousBuffer]
|
||||
bytesPerRow:texture.width * 4];
|
||||
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 =
|
||||
|
@@ -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"/>
|
||||
|
Reference in New Issue
Block a user