vblank: more tweaks, align to DRM vblank.
This commit is contained in:
parent
4ca73da9f6
commit
b4893840eb
3 changed files with 46 additions and 10 deletions
|
@ -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 )
|
||||
|
@ -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_nOutputHeight = drm->mode->vdisplay;
|
||||
|
||||
g_nOutputRefresh = drm->mode->vrefresh;
|
||||
|
||||
if ( g_nOutputWidth < g_nOutputHeight )
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +67,8 @@ void vblank_init( void )
|
|||
repaintMsg.xclient.format = 32;
|
||||
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();
|
||||
|
@ -47,4 +76,7 @@ void vblank_init( void )
|
|||
|
||||
void vblank_mark_possible_vblank( void )
|
||||
{
|
||||
std::unique_lock<std::mutex> lock( g_vblankLock );
|
||||
|
||||
g_lastVblank = std::chrono::system_clock::now();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue