Skip to content

Commit

Permalink
Don't wait for vsync for late frames
Browse files Browse the repository at this point in the history
If multiple frames are ready to be displayed, then block only on the last
one. This condition happens rarely in practice, usually when there is a high
spike of CPU activity. This change may prevent unnecessary frame drops.
  • Loading branch information
digetx committed Jul 12, 2020
1 parent ee7032a commit 1b31790
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
20 changes: 16 additions & 4 deletions src/presentation_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ static void * presentation_queue_thr(void *opaque)
{
tegra_pq *pq = opaque;
tegra_pqt *pqt = pq->pqt;
tegra_surface *surf, *tmp, *next;
tegra_surface *disp_surf, *surf, *tmp, *next;
VdpTime earliest_time = UINT64_MAX;
VdpTime time = UINT64_MAX;
struct timespec tp;
Expand Down Expand Up @@ -70,6 +70,8 @@ static void * presentation_queue_thr(void *opaque)
}

earliest_time = UINT64_MAX;
disp_surf = NULL;
next = NULL;

LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &pq->surf_list, list_item) {
pthread_mutex_lock(&surf->lock);
Expand All @@ -95,13 +97,23 @@ static void * presentation_queue_thr(void *opaque)

DebugMsg("displaying surface %u\n", surf->surface_id);

pqt_display_surface(pqt, surf, true, false);
if (disp_surf) {
pqt_display_surface(pqt, disp_surf, true, false, false);
}

disp_surf = surf;
}

if (disp_surf) {
pqt_display_surface(pqt, disp_surf, true, false, true);
}

time = earliest_time;

if (time != UINT64_MAX) {
pqt_prepare_dri_surface(pqt, next);
if (next) {
pqt_prepare_dri_surface(pqt, next);
}

DebugMsg("next wake on %llu\n", time);
} else {
Expand Down Expand Up @@ -356,7 +368,7 @@ VdpStatus vdp_presentation_queue_display(
surf->disp_height = clip_height ?: surf->height;

if (earliest_presentation_time == 0 || !_Xglobal_lock) {
pqt_display_surface(pq->pqt, surf, true, false);
pqt_display_surface(pq->pqt, surf, true, false, true);
goto unlock_surf;
}

Expand Down
16 changes: 9 additions & 7 deletions src/presentation_queue_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ static bool initialize_dri2(tegra_pqt *pqt)
return dev->dri2_ready;
}

static void pqt_display_dri(tegra_pqt *pqt, tegra_surface *surf)
static void pqt_display_dri(tegra_pqt *pqt, tegra_surface *surf, bool vsync)
{
tegra_device *dev = pqt->dev;
CARD64 ust, msc, sbc;
Expand All @@ -206,7 +206,9 @@ static void pqt_display_dri(tegra_pqt *pqt, tegra_surface *surf)

DRI2GetMSC(dev->display, pqt->drawable, &ust, &msc, &sbc);
DRI2SwapBuffers(dev->display, pqt->drawable, msc + 1, 0, 0, &count);
DRI2WaitMSC(dev->display, pqt->drawable, msc + 1, 0, 0, &ust, &msc, &sbc);
if (vsync) {
DRI2WaitMSC(dev->display, pqt->drawable, msc + 1, 0, 0, &ust, &msc, &sbc);
}

if (pqt->dri_prep_surf == surf) {
pqt->dri_prep_surf = NULL;
Expand Down Expand Up @@ -598,7 +600,7 @@ void pqt_prepare_dri_surface(tegra_pqt *pqt, tegra_surface *surf)
}

void pqt_display_surface(tegra_pqt *pqt, tegra_surface *surf,
bool update_status, bool transit)
bool update_status, bool transit, bool vsync)
{
tegra_device *dev = pqt->dev;

Expand All @@ -618,13 +620,13 @@ void pqt_display_surface(tegra_pqt *pqt, tegra_surface *surf,
dev->dri2_ready)
{
pqt_update_dri_buffer(pqt, surf);
pqt_display_dri(pqt, surf);
pqt_display_dri(pqt, surf, vsync);

if (transit || pqt->disp_state != TEGRA_PQT_DRI) {
transit_display_to_dri(pqt);
}
} else {
pqt_display_xv(pqt, surf, update_status);
pqt_display_xv(pqt, surf, vsync);

if (transit || pqt->disp_state != TEGRA_PQT_XV) {
transit_display_to_xv(pqt);
Expand Down Expand Up @@ -671,14 +673,14 @@ static void * pqt_display_thr(void *opaque)
pqt->overlapped_current = overlapped;

if (pqt->disp_surf) {
pqt_display_surface(pqt, pqt->disp_surf, false, true);
pqt_display_surface(pqt, pqt->disp_surf, false, true, false);
}
}
if (pqt->win_move) {
pqt->win_move = false;

if (pqt->disp_surf) {
pqt_display_surface(pqt, pqt->disp_surf, false, false);
pqt_display_surface(pqt, pqt->disp_surf, false, false, false);
}
}
pthread_mutex_unlock(&pqt->lock);
Expand Down
2 changes: 1 addition & 1 deletion src/vdpau_tegra.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void set_presentation_queue_target(VdpPresentationQueueTarget target,
tegra_pqt *pqt);
void pqt_display_surface_to_idle_state(tegra_pqt *pqt);
void pqt_display_surface(tegra_pqt *pqt, tegra_surface *surf,
bool update_status, bool transit);
bool update_status, bool transit, bool vsync);
void pqt_prepare_dri_surface(tegra_pqt *pqt, tegra_surface *surf);

tegra_pq * __get_presentation_queue(VdpPresentationQueue presentation_queue);
Expand Down

0 comments on commit 1b31790

Please sign in to comment.