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>
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;
}
/* 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;
}