[PATCH 2/3] ddx/dri2: Repair broken pageflip swap scheduling.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit 7538be3315b8683b05e8f6b22023baadcc0bc4da together
with DRI2/OpenGL triple-buffering support added an
optimization which breaks kms pageflip swap scheduling for most
meaningful use cases and thereby violates the OML_sync_control,
GLX_SGI_swap_control, GLX_swap_control and MESA_swap_control
specs, except for the trivial case of a glXSwapBuffers call
with swap_interval == 1.

This small modification allows to keep the optimization in
the intended way, while removing the hilarious side effects
for timing sensitive applications.

Signed-off-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
---
 src/intel_dri.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/intel_dri.c b/src/intel_dri.c
index 126acb2..8786bf4 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -1275,9 +1275,6 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	 * the swap.
 	 */
 	if (divisor == 0 || current_msc < *target_msc) {
-		if (flip && I830DRI2ScheduleFlip(intel, draw, swap_info))
-			return TRUE;
-
 		vbl.request.type =
 			DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe);
 
@@ -1295,6 +1292,25 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		if (current_msc >= *target_msc)
 			*target_msc = current_msc;
 
+		/* If pageflip is requested for the next possible vblank,
+		 * then avoid the roundtrip to the kernels vblank event
+	         * delivery and schedule the pageflip for next vblank
+		 * directly. This can't be done for any other case, as
+		 * it would violate the OML_sync_control spec and
+		 * SGI/MESA/GLX_swap_control spec!
+		 */
+		if (flip && (current_msc == *target_msc) && 
+		    I830DRI2ScheduleFlip(intel, draw, swap_info)) {
+			/* Create approximate target vblank of flip-completion,
+			 * so basic consistency checks and swap_interval still
+			 * work correctly.
+			 */
+			*target_msc += flip;
+			swap_info->frame = *target_msc;
+
+			return TRUE;
+		}
+
 		vbl.request.sequence = *target_msc;
 		vbl.request.signal = (unsigned long)swap_info;
 		ret = drmWaitVBlank(intel->drmSubFD, &vbl);
-- 
1.7.10.4



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux