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 "main.hpp"
#include "vblankmanager.hpp"
#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,
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
if ( s_drm_log != 0 )
@ -445,6 +448,8 @@ int init_drm(struct drm_t *drm, const char *device, const char *mode_str, unsign
g_nOutputWidth = drm->mode->hdisplay;
g_nOutputHeight = drm->mode->vdisplay;
g_nOutputRefresh = drm->mode->vrefresh;
if ( g_nOutputWidth < g_nOutputHeight )
{
// We probably don't want to be in portrait mode, rotate

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

View file

@ -3,10 +3,13 @@
#include <thread>
#include <vector>
#include <chrono>
#include <atomic>
#include "X11/Xlib.h"
#include "assert.h"
#include "gpuvis_trace_utils.h"
#include "vblankmanager.hpp"
#include "steamcompmgr.hpp"
#include "wlserver.h"
@ -15,18 +18,42 @@
static Display *g_nestedDpy;
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 )
{
while ( true )
{
int usec = 1.0 / g_nOutputRefresh * 1000.0 * 1000.0;
std::chrono::system_clock::time_point timePoint =
std::chrono::system_clock::now() + std::chrono::microseconds( usec );
std::chrono::time_point< std::chrono::system_clock > lastVblank;
int usecInterval = 1.0 / g_nOutputRefresh * 1000.0 * 1000.0;
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);
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) ) );
}
}
@ -41,10 +68,15 @@ void vblank_init( void )
repaintMsg.xclient.data.l[0] = 24;
repaintMsg.xclient.data.l[1] = 8;
g_lastVblank = std::chrono::system_clock::now();
std::thread vblankThread( vblankThreadRun );
vblankThread.detach();
}
void vblank_mark_possible_vblank( void )
{
std::unique_lock<std::mutex> lock( g_vblankLock );
g_lastVblank = std::chrono::system_clock::now();
}