From 3610a365da9c7b73154806cf165b7bc4c7f8be59 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 29 Mar 2012 21:14:15 +0300 Subject: [PATCH] gfx: drv: Fix swap interval 0 page flipping MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When issuing flips faster than the screen refresh rate, swap the previous mem infos around for the current and previous flip. This causes the completion of the previous flip to incement the completed read ops counter of the previous flip's front buffer instead of the current scanout buffer. Any new rendering targeting the scanout buffer will thus be blocked until the next vblank occurs. Issue: ANDROID-2373 Signed-off-by: Ville Syrjälä Signed-off-by: Artem Bityutskiy --- drivers/staging/mrst/drv/mdfld_overlay.c | 14 ++++++++++++-- drivers/staging/mrst/drv/psb_page_flip.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/staging/mrst/drv/mdfld_overlay.c b/drivers/staging/mrst/drv/mdfld_overlay.c index ddc0b99..40d233a 100644 --- a/drivers/staging/mrst/drv/mdfld_overlay.c +++ b/drivers/staging/mrst/drv/mdfld_overlay.c @@ -1647,8 +1647,18 @@ static bool ovl_flip(struct drm_flip *flip, spin_unlock_irqrestore(&ovl->regs_lock, flags); - if (pending_flip) - return (dovsta & OVL_DOVSTA_OVR_UPDT) != 0; + if (pending_flip) { + struct mfld_overlay_flip *old_oflip = + container_of(pending_flip, struct mfld_overlay_flip, base); + bool flipped = (dovsta & OVL_DOVSTA_OVR_UPDT) != 0; + + if (!flipped) { + swap(oflip->old_mem_info, old_oflip->old_mem_info); + swap(oflip->pending_values, old_oflip->pending_values); + } + + return flipped; + } return false; } diff --git a/drivers/staging/mrst/drv/psb_page_flip.c b/drivers/staging/mrst/drv/psb_page_flip.c index dc0d129..573bc90 100644 --- a/drivers/staging/mrst/drv/psb_page_flip.c +++ b/drivers/staging/mrst/drv/psb_page_flip.c @@ -335,8 +335,18 @@ static bool crtc_flip(struct drm_flip *flip, /* This flip will happen on the next vblank */ crtc_flip->vbl_count = (vbl_count + 1) & 0xffffff; - if (pending_flip) - return crtc_check(pending_flip, vbl_count); + if (pending_flip) { + struct pending_flip *old_crtc_flip = + container_of(pending_flip, struct pending_flip, base); + bool flipped = crtc_check(pending_flip, vbl_count); + + if (!flipped) { + swap(crtc_flip->old_mem_info, old_crtc_flip->old_mem_info); + swap(crtc_flip->pending_values, old_crtc_flip->pending_values); + } + + return flipped; + } return false; } -- 2.7.4