mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-11-04 00:16:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
//  DisplayMetrics.cpp
 | 
						|
//  Clock Signal
 | 
						|
//
 | 
						|
//  Created by Thomas Harte on 04/03/2019.
 | 
						|
//  Copyright © 2019 Thomas Harte. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#include "DisplayMetrics.hpp"
 | 
						|
 | 
						|
#include <numeric>
 | 
						|
 | 
						|
using namespace Outputs::Display;
 | 
						|
 | 
						|
// MARK: Frame size estimation.
 | 
						|
 | 
						|
void Metrics::announce_event(const ScanTarget::Event event) {
 | 
						|
	switch(event) {
 | 
						|
		case ScanTarget::Event::EndHorizontalRetrace:
 | 
						|
			++lines_this_frame_;
 | 
						|
		break;
 | 
						|
		case ScanTarget::Event::BeginVerticalRetrace:
 | 
						|
			add_line_total(lines_this_frame_);
 | 
						|
		break;
 | 
						|
		case ScanTarget::Event::EndVerticalRetrace:
 | 
						|
			lines_this_frame_ = 0;
 | 
						|
		break;
 | 
						|
		default: break;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void Metrics::add_line_total(const int total) {
 | 
						|
	line_total_history_[line_total_history_pointer_] = total;
 | 
						|
	line_total_history_pointer_ = (line_total_history_pointer_ + 1) % line_total_history_.size();
 | 
						|
}
 | 
						|
 | 
						|
float Metrics::visible_lines_per_frame_estimate() const {
 | 
						|
	// Just average the number of records contained in line_total_history_ to provide this estimate;
 | 
						|
	// that array should be an even number, to allow for potential interlaced sources.
 | 
						|
	return float(
 | 
						|
		std::accumulate(line_total_history_.begin(), line_total_history_.end(), 0)) / float(line_total_history_.size()
 | 
						|
	);
 | 
						|
}
 | 
						|
 | 
						|
int Metrics::current_line() const {
 | 
						|
	return lines_this_frame_;
 | 
						|
}
 | 
						|
 | 
						|
// MARK: GPU processing speed decisions.
 | 
						|
 | 
						|
void Metrics::announce_did_resize() {
 | 
						|
	frames_missed_ = frames_hit_ = 0;
 | 
						|
}
 | 
						|
 | 
						|
void Metrics::announce_draw_status(const bool complete) {
 | 
						|
	if(!complete) {
 | 
						|
		++frames_missed_;
 | 
						|
	} else {
 | 
						|
		++frames_hit_;
 | 
						|
	}
 | 
						|
 | 
						|
	// Don't allow the record of history to extend too far into the past.
 | 
						|
	if(frames_hit_ + frames_missed_ > 200) {
 | 
						|
		// Subtract from whichever wasn't just incremented, to ensure the
 | 
						|
		// most recent information is more important than the historic stuff.
 | 
						|
		if(!complete) {
 | 
						|
			--frames_hit_;
 | 
						|
		} else {
 | 
						|
			--frames_missed_;
 | 
						|
		}
 | 
						|
 | 
						|
		// Rebalance if either thing has gone negative.
 | 
						|
		if(frames_hit_ < 0) {
 | 
						|
			frames_missed_ += frames_hit_;
 | 
						|
			frames_hit_ = 0;
 | 
						|
		}
 | 
						|
		if(frames_missed_ < 0) {
 | 
						|
			frames_hit_ += frames_missed_;
 | 
						|
			frames_missed_ = 0;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void Metrics::announce_draw_status(size_t, std::chrono::high_resolution_clock::duration, const 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
 | 
						|
	// took too long to produce.
 | 
						|
	if(frames_hit_ + frames_missed_ < 100) return false;
 | 
						|
	return frames_missed_ > 10;
 | 
						|
}
 |