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>
* Version 0.7.1
* 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*)
{
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::quit_code {EXIT_SUCCESS};
bool FApplication::quit_now {false};
bool FApplication::pending_updates {false};
uInt64 FApplication::next_event_wait {5000}; // 5 ms (200 Hz)
struct timeval FApplication::time_last_event {};
@ -391,9 +390,6 @@ void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev)
void FApplication::processExternalUserEvent()
{
// 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);
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[])
{
@ -1328,11 +1304,8 @@ bool FApplication::processNextEvent()
processMouseEvent();
processResizeEvent();
processCloseWidget();
if ( processTerminalUpdate() ) // after terminal changes
pending_updates = true;
flushTerminal();
processTerminalUpdate(); // after terminal changes
flush();
processLogger();
}
@ -1342,8 +1315,6 @@ bool FApplication::processNextEvent()
{
sendQueuedEvents();
num_events += processTimerEvent();
uInt64 wait{next_event_wait / 2};
std::this_thread::sleep_for(std::chrono::microseconds(wait));
}
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 )
GPM_DRAWPOINTER(&gpm_ev);
@ -1605,7 +1605,7 @@ bool FMouseControl::getGpmKeyPressed (bool)
//----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer()
void FMouseControl::drawPointer()
{
if ( mouse_protocol.empty() )
return;
@ -1614,10 +1614,10 @@ void FMouseControl::drawGpmPointer()
auto gpm_mouse = static_cast<FMouseGPM*>(mouse);
if ( gpm_mouse )
gpm_mouse->drawGpmPointer();
gpm_mouse->drawPointer();
}
#else // F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer()
void FMouseControl::drawPointer()
{ }
#endif // F_HAVE_LIBGPM

View File

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

View File

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

View File

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

View File

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