vblank: more tweaks, align to DRM vblank.

This commit is contained in:
Pierre-Loup A. Griffais 2020-01-26 16:28:35 -08:00
parent 4ca73da9f6
commit b4893840eb
3 changed files with 46 additions and 10 deletions

View file

@ -15,6 +15,7 @@
#include "drm.hpp" #include "drm.hpp"
#include "main.hpp" #include "main.hpp"
#include "vblankmanager.hpp"
#include "gpuvis_trace_utils.h" #include "gpuvis_trace_utils.h"
@ -191,6 +192,8 @@ static int get_plane_id(struct drm_t *drm)
static void page_flip_handler(int fd, unsigned int frame, static void page_flip_handler(int fd, unsigned int frame,
unsigned int sec, unsigned int usec, void *data) unsigned int sec, unsigned int usec, void *data)
{ {
vblank_mark_possible_vblank();
// TODO: get the fbids_in_req instance from data if we ever have more than one in flight // TODO: get the fbids_in_req instance from data if we ever have more than one in flight
if ( s_drm_log != 0 ) if ( s_drm_log != 0 )
@ -444,6 +447,8 @@ int init_drm(struct drm_t *drm, const char *device, const char *mode_str, unsign
g_nOutputWidth = drm->mode->hdisplay; g_nOutputWidth = drm->mode->hdisplay;
g_nOutputHeight = drm->mode->vdisplay; g_nOutputHeight = drm->mode->vdisplay;
g_nOutputRefresh = drm->mode->vrefresh;
if ( g_nOutputWidth < g_nOutputHeight ) if ( g_nOutputWidth < g_nOutputHeight )
{ {

View file

@ -2371,6 +2371,7 @@ steamcompmgr_main (int argc, char **argv)
if ( ev.xclient.data.l[0] == 24 && ev.xclient.data.l[1] == 8 ) if ( ev.xclient.data.l[0] == 24 && ev.xclient.data.l[1] == 8 )
{ {
// Message from vblankmanager // Message from vblankmanager
gpuvis_trace_printf( "got vblank\n" );
vblank = true; vblank = true;
} }
@ -2456,12 +2457,11 @@ steamcompmgr_main (int argc, char **argv)
check_new_wayland_res(); check_new_wayland_res();
bool bDidRepaint = false;
if ( hasRepaint == true && vblank == true ) if ( hasRepaint == true && vblank == true )
{ {
paint_all(dpy); paint_all(dpy);
bDidRepaint = true;
// Consumed the need to repaint here
hasRepaint = false; hasRepaint = false;
} }
@ -2511,9 +2511,8 @@ steamcompmgr_main (int argc, char **argv)
} }
} }
// Send frame done event to all Wayland surfaces // Ask for a new surface every vblank
if ( vblank == true )
if ( bDidRepaint == true )
{ {
for (win *w = list; w; w = w->next) for (win *w = list; w; w = w->next)
{ {

View file

@ -3,10 +3,13 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <chrono> #include <chrono>
#include <atomic>
#include "X11/Xlib.h" #include "X11/Xlib.h"
#include "assert.h" #include "assert.h"
#include "gpuvis_trace_utils.h"
#include "vblankmanager.hpp" #include "vblankmanager.hpp"
#include "steamcompmgr.hpp" #include "steamcompmgr.hpp"
#include "wlserver.h" #include "wlserver.h"
@ -15,18 +18,42 @@
static Display *g_nestedDpy; static Display *g_nestedDpy;
static XEvent repaintMsg; static XEvent repaintMsg;
std::mutex g_vblankLock;
std::chrono::time_point< std::chrono::system_clock > g_lastVblank;
float g_flVblankDrawBufferMS = 5.0;
void vblankThreadRun( void ) void vblankThreadRun( void )
{ {
while ( true ) while ( true )
{ {
int usec = 1.0 / g_nOutputRefresh * 1000.0 * 1000.0; std::chrono::time_point< std::chrono::system_clock > lastVblank;
std::chrono::system_clock::time_point timePoint = int usecInterval = 1.0 / g_nOutputRefresh * 1000.0 * 1000.0;
std::chrono::system_clock::now() + std::chrono::microseconds( usec );
std::this_thread::sleep_until( timePoint ); {
std::unique_lock<std::mutex> lock( g_vblankLock );
lastVblank = g_lastVblank;
}
lastVblank -= std::chrono::microseconds( (int)(g_flVblankDrawBufferMS * 1000) );
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::time_point targetPoint = lastVblank + std::chrono::microseconds( usecInterval );
while ( targetPoint < now )
{
targetPoint += std::chrono::microseconds( usecInterval );
}
std::this_thread::sleep_until( targetPoint );
XSendEvent( g_nestedDpy , DefaultRootWindow( g_nestedDpy ), True, SubstructureRedirectMask, &repaintMsg); XSendEvent( g_nestedDpy , DefaultRootWindow( g_nestedDpy ), True, SubstructureRedirectMask, &repaintMsg);
XFlush( g_nestedDpy ); XFlush( g_nestedDpy );
gpuvis_trace_printf( "sent vblank\n" );
// Get on the other side of it now
std::this_thread::sleep_for( std::chrono::microseconds( (int)((g_flVblankDrawBufferMS + 1.0) * 1000) ) );
} }
} }
@ -40,6 +67,8 @@ void vblank_init( void )
repaintMsg.xclient.format = 32; repaintMsg.xclient.format = 32;
repaintMsg.xclient.data.l[0] = 24; repaintMsg.xclient.data.l[0] = 24;
repaintMsg.xclient.data.l[1] = 8; repaintMsg.xclient.data.l[1] = 8;
g_lastVblank = std::chrono::system_clock::now();
std::thread vblankThread( vblankThreadRun ); std::thread vblankThread( vblankThreadRun );
vblankThread.detach(); vblankThread.detach();
@ -47,4 +76,7 @@ void vblank_init( void )
void vblank_mark_possible_vblank( void ) void vblank_mark_possible_vblank( void )
{ {
std::unique_lock<std::mutex> lock( g_vblankLock );
g_lastVblank = std::chrono::system_clock::now();
} }