mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-04 06:33:47 +00:00
Uses DisplayMetrics to disable supersampling when too slow.
This commit is contained in:
parent
d7972a7b86
commit
c5e9a74c88
@ -67,7 +67,7 @@
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
enableASanStackUseAfterReturn = "YES"
|
||||
|
@ -276,6 +276,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
// Additional pipeline information.
|
||||
size_t _lumaKernelSize;
|
||||
size_t _chromaKernelSize;
|
||||
std::atomic<bool> _isUsingSupersampling;
|
||||
|
||||
// The output view.
|
||||
__weak MTKView *_view;
|
||||
@ -359,14 +360,22 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
[self setAspectRatio];
|
||||
|
||||
@synchronized(self) {
|
||||
// Always [re]try multisampling upon a resize.
|
||||
_scanTarget.display_metrics_.announce_did_resize();
|
||||
_isUsingSupersampling = true;
|
||||
[self updateSizeBuffersToSize:size];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateSizeBuffers {
|
||||
@synchronized(self) {
|
||||
[self updateSizeBuffersToSize:_view.drawableSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateSizeBuffersToSize:(CGSize)size {
|
||||
// TODO: above what size threshold is supersampling no longer desired?
|
||||
const NSUInteger frameBufferWidth = NSUInteger(size.width * _view.layer.contentsScale) * 2;
|
||||
const NSUInteger frameBufferHeight = NSUInteger(size.height * _view.layer.contentsScale) * 2;
|
||||
const NSUInteger frameBufferWidth = NSUInteger(size.width * _view.layer.contentsScale) * (_isUsingSupersampling ? 2 : 1);
|
||||
const NSUInteger frameBufferHeight = NSUInteger(size.height * _view.layer.contentsScale) * (_isUsingSupersampling ? 2 : 1);
|
||||
|
||||
// Generate a framebuffer and a stencil.
|
||||
MTLTextureDescriptor *const textureDescriptor = [MTLTextureDescriptor
|
||||
@ -1075,9 +1084,16 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
*/
|
||||
- (void)drawInMTKView:(nonnull MTKView *)view {
|
||||
if(_isDrawing.test_and_set()) {
|
||||
_scanTarget.display_metrics_.announce_draw_status(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable supersampling if performance requires it.
|
||||
if(_isUsingSupersampling && _scanTarget.display_metrics_.should_lower_resolution()) {
|
||||
_isUsingSupersampling = false;
|
||||
[self updateSizeBuffers];
|
||||
}
|
||||
|
||||
// Schedule a copy from the current framebuffer to the view; blitting is unavailable as the target is a framebuffer texture.
|
||||
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
|
||||
|
||||
@ -1085,7 +1101,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
view.currentRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionDontCare;
|
||||
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:view.currentRenderPassDescriptor];
|
||||
|
||||
[encoder setRenderPipelineState:_supersamplePipeline];
|
||||
[encoder setRenderPipelineState:_isUsingSupersampling ? _supersamplePipeline : _copyPipeline];
|
||||
[encoder setVertexTexture:_frameBuffer atIndex:0];
|
||||
[encoder setFragmentTexture:_frameBuffer atIndex:0];
|
||||
|
||||
@ -1095,6 +1111,7 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
||||
[commandBuffer presentDrawable:view.currentDrawable];
|
||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull) {
|
||||
self->_isDrawing.clear();
|
||||
self->_scanTarget.display_metrics_.announce_draw_status(true);
|
||||
}];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ void Metrics::announce_did_resize() {
|
||||
frames_missed_ = frames_hit_ = 0;
|
||||
}
|
||||
|
||||
void Metrics::announce_draw_status(size_t, std::chrono::high_resolution_clock::duration, bool complete) {
|
||||
void Metrics::announce_draw_status(bool complete) {
|
||||
if(!complete) {
|
||||
++frames_missed_;
|
||||
} else {
|
||||
@ -79,6 +79,10 @@ void Metrics::announce_draw_status(size_t, std::chrono::high_resolution_clock::d
|
||||
}
|
||||
}
|
||||
|
||||
void Metrics::announce_draw_status(size_t, std::chrono::high_resolution_clock::duration, bool complete) {
|
||||
announce_draw_status(complete);
|
||||
}
|
||||
|
||||
bool Metrics::should_lower_resolution() const {
|
||||
// If less than 100 frames are on record, return no opinion; otherwise
|
||||
// suggest a lower resolution if more than 10 frames in the last 100-200
|
||||
|
@ -33,6 +33,9 @@ class Metrics {
|
||||
/// Provides Metrics with a new data point for output speed estimation.
|
||||
void announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete);
|
||||
|
||||
/// Provides Metrics with a new data point for output speed estimation, albeit without line-specific information.
|
||||
void announce_draw_status(bool complete);
|
||||
|
||||
/// @returns @c true if Metrics thinks a lower output buffer resolution is desirable in the abstract; @c false otherwise.
|
||||
bool should_lower_resolution() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user