The terminal update rate is now limited to 60 Hz

This commit is contained in:
Markus Gans 2020-11-18 22:10:09 +01:00
parent 6c7fe98805
commit ae1fdecb40
8 changed files with 38 additions and 66 deletions

View File

@ -1,3 +1,6 @@
2019-11-18 Markus Gans <guru.mail@muenster.de>
* The terminal update rate is now limited to 60 Hz
2019-11-14 Markus Gans <guru.mail@muenster.de> 2019-11-14 Markus Gans <guru.mail@muenster.de>
* Version 0.7.1 * Version 0.7.1
* Bugfix: The cursor position was not changed anymore * Bugfix: The cursor position was not changed anymore

View File

@ -248,7 +248,7 @@ void MainWindow::onClose (finalcut::FCloseEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void MainWindow::onShow (finalcut::FShowEvent*) void MainWindow::onShow (finalcut::FShowEvent*)
{ {
addTimer(100); // Call onTimer() every 100 ms addTimer(90); // Call onTimer() every 90 ms
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -73,7 +73,6 @@ FMouseControl* FApplication::mouse {nullptr}; // mouse control
int FApplication::loop_level {0}; // event loop level int FApplication::loop_level {0}; // event loop level
int FApplication::quit_code {EXIT_SUCCESS}; int FApplication::quit_code {EXIT_SUCCESS};
bool FApplication::quit_now {false}; bool FApplication::quit_now {false};
bool FApplication::pending_updates {false};
uInt64 FApplication::next_event_wait {5000}; // 5 ms (200 Hz) uInt64 FApplication::next_event_wait {5000}; // 5 ms (200 Hz)
struct timeval FApplication::time_last_event {}; struct timeval FApplication::time_last_event {};
@ -391,9 +390,6 @@ void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev)
void FApplication::processExternalUserEvent() void FApplication::processExternalUserEvent()
{ {
// This method can be overloaded and replaced by own code // This method can be overloaded and replaced by own code
if ( FKeyboard::getReadBlockingTime() < 10000 )
std::this_thread::sleep_for(std::chrono::milliseconds(5));
} }
@ -758,9 +754,6 @@ void FApplication::mouseEvent (const FMouseData& md)
unselectMenubarItems (md); unselectMenubarItems (md);
sendMouseEvent (md); sendMouseEvent (md);
} }
if ( mouse )
mouse->drawGpmPointer();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1231,23 +1224,6 @@ void FApplication::sendWheelEvent ( const FMouseData& md
} }
} }
//----------------------------------------------------------------------
inline void FApplication::flushTerminal()
{
if ( ! pending_updates )
return;
if ( flush_count < 4 )
{
flush_count++;
return;
}
flush();
flush_count = 0;
pending_updates = false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FWidget* FApplication::processParameters (const int& argc, char* argv[]) FWidget* FApplication::processParameters (const int& argc, char* argv[])
{ {
@ -1328,11 +1304,8 @@ bool FApplication::processNextEvent()
processMouseEvent(); processMouseEvent();
processResizeEvent(); processResizeEvent();
processCloseWidget(); processCloseWidget();
processTerminalUpdate(); // after terminal changes
if ( processTerminalUpdate() ) // after terminal changes flush();
pending_updates = true;
flushTerminal();
processLogger(); processLogger();
} }
@ -1342,8 +1315,6 @@ bool FApplication::processNextEvent()
{ {
sendQueuedEvents(); sendQueuedEvents();
num_events += processTimerEvent(); num_events += processTimerEvent();
uInt64 wait{next_event_wait / 2};
std::this_thread::sleep_for(std::chrono::microseconds(wait));
} }
return ( num_events > 0 ); return ( num_events > 0 );

View File

@ -510,7 +510,7 @@ bool FMouseGPM::getGpmKeyPressed (bool is_pending)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMouseGPM::drawGpmPointer() const void FMouseGPM::drawPointer() const
{ {
if ( isGpmMouseEnabled() && gpm_ev.x != -1 ) if ( isGpmMouseEnabled() && gpm_ev.x != -1 )
GPM_DRAWPOINTER(&gpm_ev); GPM_DRAWPOINTER(&gpm_ev);
@ -1605,7 +1605,7 @@ bool FMouseControl::getGpmKeyPressed (bool)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer() void FMouseControl::drawPointer()
{ {
if ( mouse_protocol.empty() ) if ( mouse_protocol.empty() )
return; return;
@ -1614,10 +1614,10 @@ void FMouseControl::drawGpmPointer()
auto gpm_mouse = static_cast<FMouseGPM*>(mouse); auto gpm_mouse = static_cast<FMouseGPM*>(mouse);
if ( gpm_mouse ) if ( gpm_mouse )
gpm_mouse->drawGpmPointer(); gpm_mouse->drawPointer();
} }
#else // F_HAVE_LIBGPM #else // F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer() void FMouseControl::drawPointer()
{ } { }
#endif // F_HAVE_LIBGPM #endif // F_HAVE_LIBGPM

View File

@ -34,6 +34,7 @@
#include "final/fcolorpair.h" #include "final/fcolorpair.h"
#include "final/fkeyboard.h" #include "final/fkeyboard.h"
#include "final/flog.h" #include "final/flog.h"
#include "final/fmouse.h"
#include "final/foptiattr.h" #include "final/foptiattr.h"
#include "final/foptimove.h" #include "final/foptimove.h"
#include "final/fstyle.h" #include "final/fstyle.h"
@ -55,13 +56,14 @@ bool FVTerm::draw_completed{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};
int FVTerm::skipped_terminal_update{0}; uInt64 FVTerm::flush_wait{16667}; // 16.6 ms (60 Hz)
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{};
uInt FVTerm::clr_bol_length{}; uInt FVTerm::clr_bol_length{};
uInt FVTerm::clr_eol_length{}; uInt FVTerm::clr_eol_length{};
uInt FVTerm::cursor_address_length{}; uInt FVTerm::cursor_address_length{};
struct timeval FVTerm::time_last_flush{};
struct timeval FVTerm::last_term_size_check{}; struct timeval FVTerm::last_term_size_check{};
std::vector<int>* FVTerm::output_buffer{nullptr}; std::vector<int>* FVTerm::output_buffer{nullptr};
FPoint* FVTerm::term_pos{nullptr}; FPoint* FVTerm::term_pos{nullptr};
@ -71,7 +73,7 @@ FTerm* FVTerm::fterm{nullptr};
FVTerm::FTermArea* FVTerm::vterm{nullptr}; FVTerm::FTermArea* FVTerm::vterm{nullptr};
FVTerm::FTermArea* FVTerm::vdesktop{nullptr}; FVTerm::FTermArea* FVTerm::vdesktop{nullptr};
FVTerm::FTermArea* FVTerm::active_area{nullptr}; FVTerm::FTermArea* FVTerm::active_area{nullptr};
FKeyboard* FVTerm::keyboard{nullptr}; FMouseControl* FVTerm::mouse{nullptr};
FChar FVTerm::term_attribute{}; FChar FVTerm::term_attribute{};
FChar FVTerm::next_attribute{}; FChar FVTerm::next_attribute{};
FChar FVTerm::s_ch{}; FChar FVTerm::s_ch{};
@ -280,25 +282,14 @@ bool FVTerm::updateTerminal() const
} }
std::size_t changedlines = 0; std::size_t changedlines = 0;
static constexpr int check_interval = 5;
for (uInt y{0}; y < uInt(vterm->height); y++) for (uInt y{0}; y < uInt(vterm->height); y++)
{ {
if ( updateTerminalLine(y) ) if ( updateTerminalLine(y) )
changedlines++; changedlines++;
if ( ! force_terminal_update
&& changedlines % check_interval == 0
&& (keyboard->hasUnprocessedInput() || keyboard->isKeyPressed(0) )
&& skipped_terminal_update < max_skip )
{
// Skipping terminal updates if there is unprocessed inputs
skipped_terminal_update++;
return false;
}
} }
skipped_terminal_update = 0;
vterm->has_changes = false; vterm->has_changes = false;
// sets the new input cursor position // sets the new input cursor position
@ -586,7 +577,8 @@ void FVTerm::flush()
{ {
// Flush the output buffer // Flush the output buffer
if ( ! output_buffer || output_buffer->empty() ) if ( ! output_buffer || output_buffer->empty()
|| ! (isFlushTimeout() || force_terminal_update) )
return; return;
static const FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); static const FTerm::defaultPutChar& FTermPutchar = FTerm::putchar();
@ -599,6 +591,8 @@ void FVTerm::flush()
output_buffer->clear(); output_buffer->clear();
std::fflush(stdout); std::fflush(stdout);
mouse->drawPointer();
FObject::getCurrentTime (&time_last_flush);
} }
@ -1259,7 +1253,6 @@ bool FVTerm::processTerminalUpdate() const
} }
// Update data on VTerm // Update data on VTerm
if ( force_terminal_update || skipped_terminal_update == 0 )
updateVTerm(); updateVTerm();
// Update the visible terminal // Update the visible terminal
@ -1286,8 +1279,8 @@ void FVTerm::initTerminal()
if ( fterm ) if ( fterm )
fterm->initTerminal(); fterm->initTerminal();
// Get FKeyboard object // Get the global FMouseControl object
keyboard = FTerm::getFKeyboard(); mouse = FTerm::getFMouseControl();
// Hide the input cursor // Hide the input cursor
cursor_hideable = FTerm::isCursorHideable(); cursor_hideable = FTerm::isCursorHideable();
@ -1863,7 +1856,9 @@ void FVTerm::init()
vdesktop->visible = true; vdesktop->visible = true;
active_area = vdesktop; active_area = vdesktop;
// Initialize the last terminal size check time // Initialize the flush and last terminal size check time
time_last_flush.tv_sec = 0;
time_last_flush.tv_usec = 0;
last_term_size_check.tv_sec = 0; last_term_size_check.tv_sec = 0;
last_term_size_check.tv_usec = 0; last_term_size_check.tv_usec = 0;
} }
@ -1902,7 +1897,7 @@ void FVTerm::finish()
&& FTerm::getFTermData()->isInAlternateScreen() ) && FTerm::getFTermData()->isInAlternateScreen() )
clearTerm(); clearTerm();
flush(); forceTerminalUpdate();
if ( output_buffer ) if ( output_buffer )
delete output_buffer; delete output_buffer;
@ -2866,6 +2861,12 @@ inline bool FVTerm::isTermSizeChanged() const
return false; return false;
} }
//----------------------------------------------------------------------
inline bool FVTerm::isFlushTimeout()
{
return FObject::isTimeout (&time_last_flush, flush_wait);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FVTerm::isTermSizeCheckTimeout() inline bool FVTerm::isTermSizeCheckTimeout()
{ {

View File

@ -222,7 +222,6 @@ class FApplication : public FWidget
void sendWheelEvent ( const FMouseData& void sendWheelEvent ( const FMouseData&
, const FPoint& , const FPoint&
, const FPoint& ) const; , const FPoint& ) const;
void flushTerminal();
static FWidget* processParameters (const int&, char*[]); static FWidget* processParameters (const int&, char*[]);
void processResizeEvent() const; void processResizeEvent() const;
void processCloseWidget(); void processCloseWidget();
@ -240,13 +239,11 @@ class FApplication : public FWidget
std::streambuf* default_clog_rdbuf{std::clog.rdbuf()}; std::streambuf* default_clog_rdbuf{std::clog.rdbuf()};
FWidget* clicked_widget{}; FWidget* clicked_widget{};
FEventQueue event_queue{}; FEventQueue event_queue{};
int flush_count{0};
static uInt64 next_event_wait; static uInt64 next_event_wait;
static timeval time_last_event; static timeval time_last_event;
static int loop_level; static int loop_level;
static int quit_code; static int quit_code;
static bool quit_now; static bool quit_now;
static bool pending_updates;
static FMouseControl* mouse; static FMouseControl* mouse;
static FKeyboard* keyboard; static FKeyboard* keyboard;
static FWidget* keyboard_widget; static FWidget* keyboard_widget;

View File

@ -279,7 +279,7 @@ class FMouseGPM final : public FMouse
void interpretKeyDown(); void interpretKeyDown();
void interpretKeyUp(); void interpretKeyUp();
bool getGpmKeyPressed(bool); bool getGpmKeyPressed(bool);
void drawGpmPointer() const; void drawPointer() const;
private: private:
// Enumeration // Enumeration
@ -578,7 +578,7 @@ class FMouseControl
virtual void processEvent (struct timeval* time); virtual void processEvent (struct timeval* time);
void processQueuedInput(); void processQueuedInput();
bool getGpmKeyPressed (bool); bool getGpmKeyPressed (bool);
void drawGpmPointer(); void drawPointer();
private: private:
// Typedef // Typedef

View File

@ -68,7 +68,6 @@ namespace finalcut
// class forward declaration // class forward declaration
class FColorPair; class FColorPair;
class FKeyboard;
class FMouseControl; class FMouseControl;
class FPoint; class FPoint;
class FRect; class FRect;
@ -341,7 +340,6 @@ class FVTerm
// Constants // Constants
// Buffer size for character output on the terminal // Buffer size for character output on the terminal
static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072; static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072;
static constexpr int max_skip = 2;
// Methods // Methods
void resetTextAreaToDefault ( const FTermArea* void resetTextAreaToDefault ( const FTermArea*
@ -408,6 +406,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;
static bool isFlushTimeout();
static bool isTermSizeCheckTimeout(); static bool isTermSizeCheckTimeout();
static bool hasPendingUpdates (const FTermArea*); static bool hasPendingUpdates (const FTermArea*);
static void markAsPrinted (uInt, uInt); static void markAsPrinted (uInt, uInt);
@ -438,12 +437,13 @@ class FVTerm
static FChar s_ch; // shadow character static FChar s_ch; // shadow character
static FChar i_ch; // inherit background character static FChar i_ch; // inherit background character
static FPoint* term_pos; // terminal cursor position static FPoint* term_pos; // terminal cursor position
static FKeyboard* keyboard; static FMouseControl* mouse;
static timeval time_last_flush;
static timeval last_term_size_check; static timeval last_term_size_check;
static bool draw_completed; static bool draw_completed;
static bool no_terminal_updates; static bool no_terminal_updates;
static bool force_terminal_update; static bool force_terminal_update;
static int skipped_terminal_update; static uInt64 flush_wait;
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;