Eliminate one terminal copy per frame (20% speedup on benchmark)
This commit is contained in:
@@ -50,12 +50,17 @@ extern "C" {
|
|||||||
|
|
||||||
const int ITERATIONS = 1000;
|
const int ITERATIONS = 1000;
|
||||||
|
|
||||||
|
using namespace Terminal;
|
||||||
|
|
||||||
int main( void )
|
int main( void )
|
||||||
{
|
{
|
||||||
Terminal::Framebuffer local_framebuffer( 80, 24 );
|
int fbmod = 0;
|
||||||
|
Framebuffer local_framebuffers[ 2 ] = { Framebuffer(80,24), Framebuffer(80,24) };
|
||||||
|
Framebuffer *local_framebuffer = &(local_framebuffers[ fbmod ]);
|
||||||
|
Framebuffer *new_state = &(local_framebuffers[ !fbmod ]);
|
||||||
Overlay::OverlayManager overlays;
|
Overlay::OverlayManager overlays;
|
||||||
Terminal::Display display( true );
|
Display display( true );
|
||||||
Terminal::Complete local_terminal( 80, 24 );
|
Complete local_terminal( 80, 24 );
|
||||||
|
|
||||||
/* Adopt native locale */
|
/* Adopt native locale */
|
||||||
if ( NULL == setlocale( LC_ALL, "" ) ) {
|
if ( NULL == setlocale( LC_ALL, "" ) ) {
|
||||||
@@ -71,25 +76,27 @@ int main( void )
|
|||||||
|
|
||||||
for ( int i = 0; i < ITERATIONS; i++ ) {
|
for ( int i = 0; i < ITERATIONS; i++ ) {
|
||||||
/* type a character */
|
/* type a character */
|
||||||
overlays.get_prediction_engine().new_user_byte( i + 'x', local_framebuffer );
|
overlays.get_prediction_engine().new_user_byte( i + 'x', *local_framebuffer );
|
||||||
|
|
||||||
/* fetch target state */
|
/* fetch target state */
|
||||||
Terminal::Framebuffer new_state( local_terminal.get_fb() );
|
*new_state = local_terminal.get_fb();
|
||||||
|
|
||||||
/* apply local overlays */
|
/* apply local overlays */
|
||||||
overlays.apply( new_state );
|
overlays.apply( *new_state );
|
||||||
|
|
||||||
/* calculate minimal difference from where we are */
|
/* calculate minimal difference from where we are */
|
||||||
const string diff( display.new_frame( false,
|
const string diff( display.new_frame( false,
|
||||||
local_framebuffer,
|
*local_framebuffer,
|
||||||
new_state ) );
|
*new_state ) );
|
||||||
|
|
||||||
/* make sure to use diff */
|
/* make sure to use diff */
|
||||||
if ( diff.size() > INT_MAX ) {
|
if ( diff.size() > INT_MAX ) {
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
local_framebuffer = new_state;
|
fbmod = !fbmod;
|
||||||
|
local_framebuffer = &(local_framebuffers[ fbmod ]);
|
||||||
|
new_state = &(local_framebuffers[ !fbmod ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ void STMClient::main_init( void )
|
|||||||
|
|
||||||
/* local state */
|
/* local state */
|
||||||
local_framebuffer = new Terminal::Framebuffer( window_size.ws_col, window_size.ws_row );
|
local_framebuffer = new Terminal::Framebuffer( window_size.ws_col, window_size.ws_row );
|
||||||
|
new_state = new Terminal::Framebuffer( 1, 1 );
|
||||||
|
|
||||||
/* initialize screen */
|
/* initialize screen */
|
||||||
string init = display.new_frame( false, *local_framebuffer, *local_framebuffer );
|
string init = display.new_frame( false, *local_framebuffer, *local_framebuffer );
|
||||||
@@ -152,19 +153,23 @@ void STMClient::output_new_frame( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fetch target state */
|
/* fetch target state */
|
||||||
Terminal::Framebuffer new_state( network->get_latest_remote_state().state.get_fb() );
|
*new_state = network->get_latest_remote_state().state.get_fb();
|
||||||
|
|
||||||
/* apply local overlays */
|
/* apply local overlays */
|
||||||
overlays.apply( new_state );
|
overlays.apply( *new_state );
|
||||||
|
|
||||||
/* calculate minimal difference from where we are */
|
/* calculate minimal difference from where we are */
|
||||||
const string diff( display.new_frame( !repaint_requested,
|
const string diff( display.new_frame( !repaint_requested,
|
||||||
*local_framebuffer,
|
*local_framebuffer,
|
||||||
new_state ) );
|
*new_state ) );
|
||||||
swrite( STDOUT_FILENO, diff.data(), diff.size() );
|
swrite( STDOUT_FILENO, diff.data(), diff.size() );
|
||||||
*local_framebuffer = new_state;
|
|
||||||
|
|
||||||
repaint_requested = false;
|
repaint_requested = false;
|
||||||
|
|
||||||
|
/* switch pointers */
|
||||||
|
Terminal::Framebuffer *tmp = new_state;
|
||||||
|
new_state = local_framebuffer;
|
||||||
|
local_framebuffer = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STMClient::process_network_input( void )
|
bool STMClient::process_network_input( void )
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
int signal_fd;
|
int signal_fd;
|
||||||
struct winsize window_size;
|
struct winsize window_size;
|
||||||
|
|
||||||
Terminal::Framebuffer *local_framebuffer;
|
Terminal::Framebuffer *local_framebuffer, *new_state;
|
||||||
Overlay::OverlayManager overlays;
|
Overlay::OverlayManager overlays;
|
||||||
Network::Transport< Network::UserStream, Terminal::Complete > *network;
|
Network::Transport< Network::UserStream, Terminal::Complete > *network;
|
||||||
Terminal::Display display;
|
Terminal::Display display;
|
||||||
@@ -60,6 +60,7 @@ public:
|
|||||||
signal_fd(),
|
signal_fd(),
|
||||||
window_size(),
|
window_size(),
|
||||||
local_framebuffer( NULL ),
|
local_framebuffer( NULL ),
|
||||||
|
new_state( NULL ),
|
||||||
overlays(),
|
overlays(),
|
||||||
network( NULL ),
|
network( NULL ),
|
||||||
display( true ), /* use TERM environment var to initialize display */
|
display( true ), /* use TERM environment var to initialize display */
|
||||||
@@ -90,6 +91,10 @@ public:
|
|||||||
delete local_framebuffer;
|
delete local_framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( new_state != NULL ) {
|
||||||
|
delete new_state;
|
||||||
|
}
|
||||||
|
|
||||||
if ( network != NULL ) {
|
if ( network != NULL ) {
|
||||||
delete network;
|
delete network;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user