Dynamic adjustment of the terminal refresh rate between 5 and 60 Hz
This commit is contained in:
parent
d4f629f183
commit
e6dfd73e7a
|
@ -1,4 +1,8 @@
|
||||||
2021-02-09 Markus Gans <guru.mail@muenster.de>
|
2021-03-15 Markus Gans <guru.mail@muenster.de>
|
||||||
|
* Dynamic adjustment of the terminal refresh rate between
|
||||||
|
5 and 60 Hz
|
||||||
|
|
||||||
|
2021-03-09 Markus Gans <guru.mail@muenster.de>
|
||||||
* Implementation of an own padding print method for sending
|
* Implementation of an own padding print method for sending
|
||||||
control codes to the terminal
|
control codes to the terminal
|
||||||
|
|
||||||
|
|
|
@ -149,13 +149,11 @@ bool FKeyboard::isKeyPressed (uInt64 blocking_time)
|
||||||
tv.tv_sec = tv.tv_usec = 0; // Non-blocking input
|
tv.tv_sec = tv.tv_usec = 0; // Non-blocking input
|
||||||
|
|
||||||
if ( blocking_time > 0
|
if ( blocking_time > 0
|
||||||
&& non_blocking_input_support
|
&& non_blocking_input_support
|
||||||
&& select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0
|
&& select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0
|
||||||
&& FD_ISSET(stdin_no, &ifds) )
|
&& FD_ISSET(stdin_no, &ifds) )
|
||||||
{
|
{
|
||||||
has_pending_input = true;
|
return (has_pending_input = true);
|
||||||
FD_CLR (stdin_no, &ifds);
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isKeypressTimeout() || ! non_blocking_input_support )
|
if ( isKeypressTimeout() || ! non_blocking_input_support )
|
||||||
|
|
|
@ -438,7 +438,6 @@ std::string FTermcap::encodeParams ( const std::string& cap
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FTermcap::delay_output (int ms, const defaultPutChar& outc)
|
void FTermcap::delay_output (int ms, const defaultPutChar& outc)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( no_padding_char )
|
if ( no_padding_char )
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||||
|
|
|
@ -60,7 +60,9 @@ bool FVTerm::combined_char_support{false};
|
||||||
bool FVTerm::no_terminal_updates{false};
|
bool FVTerm::no_terminal_updates{false};
|
||||||
bool FVTerm::cursor_hideable{false};
|
bool FVTerm::cursor_hideable{false};
|
||||||
bool FVTerm::force_terminal_update{false};
|
bool FVTerm::force_terminal_update{false};
|
||||||
uInt64 FVTerm::flush_wait{16667}; // 16.6 ms (60 Hz)
|
uInt64 FVTerm::flush_wait{MIN_FLUSH_WAIT};
|
||||||
|
uInt64 FVTerm::flush_average{MIN_FLUSH_WAIT};
|
||||||
|
uInt64 FVTerm::flush_median{MIN_FLUSH_WAIT};
|
||||||
uInt64 FVTerm::term_size_check_timeout{500000}; // 500 ms
|
uInt64 FVTerm::term_size_check_timeout{500000}; // 500 ms
|
||||||
uInt FVTerm::erase_char_length{};
|
uInt FVTerm::erase_char_length{};
|
||||||
uInt FVTerm::repeat_char_length{};
|
uInt FVTerm::repeat_char_length{};
|
||||||
|
@ -573,6 +575,8 @@ void FVTerm::flush() const
|
||||||
{
|
{
|
||||||
// Flush the output buffer
|
// Flush the output buffer
|
||||||
|
|
||||||
|
flushTimeAdjustment();
|
||||||
|
|
||||||
if ( ! output_buffer || output_buffer->empty()
|
if ( ! output_buffer || output_buffer->empty()
|
||||||
|| ! (isFlushTimeout() || force_terminal_update) )
|
|| ! (isFlushTimeout() || force_terminal_update) )
|
||||||
return;
|
return;
|
||||||
|
@ -2888,6 +2892,52 @@ inline bool FVTerm::isTermSizeChanged() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
inline void FVTerm::flushTimeAdjustment() const
|
||||||
|
{
|
||||||
|
timeval now;
|
||||||
|
FObject::getCurrentTime(&now);
|
||||||
|
timeval diff = now - time_last_flush;
|
||||||
|
|
||||||
|
if ( diff.tv_sec > 0 || diff.tv_usec > 400000 )
|
||||||
|
{
|
||||||
|
flush_wait = MIN_FLUSH_WAIT; // Reset to minimum values after 400 ms
|
||||||
|
flush_average = MIN_FLUSH_WAIT;
|
||||||
|
flush_median = MIN_FLUSH_WAIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uInt64 usec = diff.tv_usec;
|
||||||
|
|
||||||
|
if ( usec < MIN_FLUSH_WAIT )
|
||||||
|
usec = MIN_FLUSH_WAIT;
|
||||||
|
else if ( usec > MAX_FLUSH_WAIT )
|
||||||
|
usec = MAX_FLUSH_WAIT;
|
||||||
|
|
||||||
|
if ( usec >= flush_average )
|
||||||
|
flush_average += (usec - flush_average) / 10;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uInt64 delta = (flush_average - usec) / 10;
|
||||||
|
|
||||||
|
if ( flush_average >= delta ) // Avoid uInt64 underflow
|
||||||
|
flush_average -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( usec >= flush_median )
|
||||||
|
flush_median += flush_average / 5;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uInt64 delta = flush_average / 5;
|
||||||
|
|
||||||
|
if ( flush_median >= delta ) // Avoid uInt64 underflow
|
||||||
|
flush_median -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_wait = flush_median;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FVTerm::isFlushTimeout()
|
inline bool FVTerm::isFlushTimeout()
|
||||||
{
|
{
|
||||||
|
|
|
@ -345,6 +345,9 @@ class FVTerm
|
||||||
// Constants
|
// Constants
|
||||||
// Buffer limit for character output on the terminal
|
// Buffer limit for character output on the terminal
|
||||||
static constexpr std::size_t TERMINAL_OUTPUT_BUFFER_LIMIT = 1024;
|
static constexpr std::size_t TERMINAL_OUTPUT_BUFFER_LIMIT = 1024;
|
||||||
|
// Upper and lower flush limit
|
||||||
|
static constexpr uInt64 MIN_FLUSH_WAIT = 16667; // 16.6 ms = 60 Hz
|
||||||
|
static constexpr uInt64 MAX_FLUSH_WAIT = 200000; // 200.0 ms = 5 Hz
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void resetTextAreaToDefault ( const FTermArea*
|
void resetTextAreaToDefault ( const FTermArea*
|
||||||
|
@ -412,6 +415,7 @@ class FVTerm
|
||||||
bool updateTerminalCursor() const;
|
bool updateTerminalCursor() const;
|
||||||
bool isInsideTerminal (const FPoint&) const;
|
bool isInsideTerminal (const FPoint&) const;
|
||||||
bool isTermSizeChanged() const;
|
bool isTermSizeChanged() const;
|
||||||
|
void flushTimeAdjustment() const;
|
||||||
static bool isFlushTimeout();
|
static bool isFlushTimeout();
|
||||||
static bool isTermSizeCheckTimeout();
|
static bool isTermSizeCheckTimeout();
|
||||||
static bool hasPendingUpdates (const FTermArea*);
|
static bool hasPendingUpdates (const FTermArea*);
|
||||||
|
@ -451,6 +455,8 @@ class FVTerm
|
||||||
static bool no_terminal_updates;
|
static bool no_terminal_updates;
|
||||||
static bool force_terminal_update;
|
static bool force_terminal_update;
|
||||||
static uInt64 flush_wait;
|
static uInt64 flush_wait;
|
||||||
|
static uInt64 flush_average;
|
||||||
|
static uInt64 flush_median;
|
||||||
static uInt64 term_size_check_timeout;
|
static uInt64 term_size_check_timeout;
|
||||||
static uInt erase_char_length;
|
static uInt erase_char_length;
|
||||||
static uInt repeat_char_length;
|
static uInt repeat_char_length;
|
||||||
|
|
|
@ -276,6 +276,13 @@ void FTermcapTest::paddingPrintTest()
|
||||||
CPPUNIT_ASSERT ( ! output.empty() );
|
CPPUNIT_ASSERT ( ! output.empty() );
|
||||||
CPPUNIT_ASSERT ( output == "12$3$<4567" );
|
CPPUNIT_ASSERT ( output == "12$3$<4567" );
|
||||||
|
|
||||||
|
// Without a digit
|
||||||
|
output.clear();
|
||||||
|
status = tcap.paddingPrint ("12$3$<x>4567", 1, FTermcapTest::putchar_test);
|
||||||
|
CPPUNIT_ASSERT ( status == finalcut::FTermcap::Status::OK );
|
||||||
|
CPPUNIT_ASSERT ( ! output.empty() );
|
||||||
|
CPPUNIT_ASSERT ( output == "12$3$<x>4567" );
|
||||||
|
|
||||||
// With 2 ms print delay
|
// With 2 ms print delay
|
||||||
output.clear();
|
output.clear();
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
|
|
Loading…
Reference in New Issue