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