gfx: drv: Fix swap interval 0 page flipping
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 29 Mar 2012 18:14:15 +0000 (21:14 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:30:50 +0000 (12:30 +0300)
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ä <ville.syrjala@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/staging/mrst/drv/mdfld_overlay.c
drivers/staging/mrst/drv/psb_page_flip.c

index ddc0b99..40d233a 100644 (file)
@@ -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;
 }
index dc0d129..573bc90 100644 (file)
@@ -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;
 }