mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-03 11:43:07 +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];
|
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;
|
||||||
}
|
}
|
||||||
|
@@ -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 =
|
||||||
|
@@ -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"/>
|
||||||
|
Reference in New Issue
Block a user