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 "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 )
|
||||||
|
@ -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_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 )
|
||||||
{
|
{
|
||||||
// We probably don't want to be in portrait mode, rotate
|
// We probably don't want to be in portrait mode, rotate
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +68,15 @@ void vblank_init( void )
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue