xf86-video-intel: Branch 'dri2-swapbuffers' - src/drmmode_display.c src/i830_dri.c src/i830.h

Kristian Høgsberg krh at kemper.freedesktop.org
Thu Jul 23 12:42:04 PDT 2009


Rebased ref, commits from common ancestor:
commit 8dba7b05f901447a94756b9ec037b0fae1b6d0ac
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Jul 17 11:30:33 2009 -0400

    Notify DRI2 asynchronously when page flip is finished
    
    This lets DRI2 suspend just the swapping client instead of the entire
    server.  When the swap is done, the drm fd becomes readable and we
    call back into DRI2 so it can resume the client.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 03b494d..f527c39 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -44,6 +44,10 @@ typedef struct {
     uint32_t fb_id;
     drmModeResPtr mode_res;
     int cpp;
+    
+    drmEventContext event_context;
+    void *swap_data;
+    int old_fb_id;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
@@ -1097,7 +1101,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 }
 
 Bool
-drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front, dri_bo *old_front)
+drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front, dri_bo *old_front,
+		    void *data)
 {
     ScreenPtr pScreen = pDraw->pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -1106,15 +1111,13 @@ drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front, dri_bo *old_front)
     drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
     drmmode_ptr drmmode = drmmode_crtc->drmmode;
     unsigned int pitch = pScrn->displayWidth * pI830->cpp;
-    int i, old_fb_id;
+    int i;
     unsigned int crtc_id;
-    struct pollfd drmpoll;
-    drmEventContext handler = { .page_flip_handler = NULL };
 
     /*
      * Create a new handle for the back buffer
      */
-    old_fb_id = drmmode->fb_id;
+    drmmode->old_fb_id = drmmode->fb_id;
     if (drmModeAddFB(drmmode->fd, pScrn->virtualX, pScrn->virtualY,
 		     pScrn->depth, pScrn->bitsPerPixel, pitch,
 		     new_front->handle, &drmmode->fb_id))
@@ -1137,40 +1140,23 @@ drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front, dri_bo *old_front)
 
 	    drmmode_crtc = crtc->driver_private;
 	    crtc_id = drmmode_crtc->mode_crtc->crtc_id;
-	    if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id, NULL)) {
+	    drmmode->swap_data = data;
+	    if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id, drmmode)) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			       "flip queue failed: %s\n", strerror(errno));
 		    goto error_undo;
 	    }
     }
 
-retry:
-    drmpoll.fd = drmmode->fd;
-    drmpoll.events = POLLIN;
-    if (poll(&drmpoll, 1, -1) < 0) {
-	    if (errno == EINTR)
-		    goto retry;
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "poll failed: %s\n",
-		       strerror(errno));
-	    goto error_undo;
-    }
-
-    drmHandleEvent(drmmode->fd, &handler);
-
-    dri_bo_pin(new_front, 0);
-    dri_bo_unpin(new_front);
-
     pScrn->fbOffset = new_front->offset;
     pI830->front_buffer->bo = new_front;
     pI830->front_buffer->offset = new_front->offset;
 
-    drmModeRmFB(drmmode->fd, old_fb_id);
-
     return TRUE;
 
 error_undo:
     drmModeRmFB(drmmode->fd, drmmode->fb_id);
-    drmmode->fb_id = old_fb_id;
+    drmmode->fb_id = drmmode->old_fb_id;
 
 error_out:
     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
@@ -1182,6 +1168,30 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 	drmmode_xf86crtc_resize
 };
 
+static void
+drmmode_page_flip_handler(int fd,
+			  unsigned int frame, 
+			  unsigned int tv_sec,
+			  unsigned int tv_usec,
+			  void *user_data)
+{
+    drmmode_ptr drmmode = user_data;
+
+    drmModeRmFB(drmmode->fd, drmmode->old_fb_id);
+
+    DRI2SwapComplete(drmmode->swap_data);
+}
+
+static void
+drm_wakeup_handler(pointer data, int err, pointer p)
+{
+    drmmode_ptr drmmode = data;
+    fd_set *read_mask = p;
+
+    if (err >= 0 && FD_ISSET(drmmode->fd, read_mask))
+	drmHandleEvent(drmmode->fd, &drmmode->event_context);
+}
+
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
 {
 	xf86CrtcConfigPtr   xf86_config;
@@ -1221,6 +1231,14 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "Kernel page flipping support detected, enabling\n");
 		pI830->use_swap_buffers = TRUE;
+
+		drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
+		drmmode->event_context.page_flip_handler =
+		    drmmode_page_flip_handler;
+		AddGeneralSocket(fd);
+		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+					       drm_wakeup_handler,
+					       drmmode);
 	}
 
 	return TRUE;
diff --git a/src/i830.h b/src/i830.h
index b4f5d7a..51a87cb 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -690,7 +690,7 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
 extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
 extern int drmmode_output_dpms_status(xf86OutputPtr output);
 extern Bool drmmode_do_pageflip(DrawablePtr pDraw, dri_bo *new_front,
-				dri_bo *old_front);
+				dri_bo *old_front, void *data);
 
 extern Bool i830_crtc_on(xf86CrtcPtr crtc);
 extern int i830_crtc_to_pipe(xf86CrtcPtr crtc);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 0f38d09..b34b9b7 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -357,25 +357,6 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
 }
 
 #if DRI2INFOREC_VERSION >= 4
-/* Check various flip constraints (drawable parameters vs screen params) */
-static Bool
-i830_flip_ok(DrawablePtr pDraw)
-{
-    ScreenPtr pScreen = pDraw->pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (pI830->shadow_present)
-	return FALSE;
-    if (pDraw->width != pScrn->virtualX)
-	return FALSE;
-    if (pDraw->height != pScrn->virtualY)
-	return FALSE;
-    if (pDraw->depth != pScrn->depth)
-	return FALSE;
-
-    return TRUE;
-}
 
 /*
  * DRI2SwapBuffers should try to do a buffer swap if possible, however:
@@ -385,9 +366,12 @@ i830_flip_ok(DrawablePtr pDraw)
  *     and back buffers
  */
 static Bool
-I830DRI2SwapBuffers(DrawablePtr pDraw, DRI2BufferPtr front, DRI2BufferPtr back)
+I830DRI2SwapBuffers(DrawablePtr pDraw,
+		    DRI2BufferPtr front, DRI2BufferPtr back, void *data)
 {
     ScreenPtr pScreen = pDraw->pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
     I830DRI2BufferPrivatePtr front_priv, back_priv;
     dri_bo *tmp_bo;
     int tmp;
@@ -395,7 +379,7 @@ I830DRI2SwapBuffers(DrawablePtr pDraw, DRI2BufferPtr front, DRI2BufferPtr back)
     front_priv = front->driverPrivate;
     back_priv = back->driverPrivate;
 
-    if (!i830_flip_ok(pDraw))
+    if (pI830->shadow_present)
 	return FALSE;
 
     /* Swap BO names so DRI works */
@@ -416,7 +400,7 @@ I830DRI2SwapBuffers(DrawablePtr pDraw, DRI2BufferPtr front, DRI2BufferPtr back)
 
     /* Page flip the full screen buffer */
     return drmmode_do_pageflip(pDraw, i830_get_pixmap_bo(front_priv->pPixmap),
-			       i830_get_pixmap_bo(back_priv->pPixmap));
+			       i830_get_pixmap_bo(back_priv->pPixmap), data);
 }
 #endif
 


More information about the xorg-commit mailing list