[Mesa-dev] [PATCH 3/4] st/egl/drm: Rework swapbuffers

Thomas Hellstrom thellstrom at vmware.com
Fri Feb 25 06:05:10 PST 2011


Use the pageflip ioctl when available.
Otherwise, or when the backbuffer contents need to be preserved,
fall back to a copy operation.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
 src/gallium/state_trackers/egl/drm/modeset.c    |   37 ++++++++++++++++++----
 src/gallium/state_trackers/egl/drm/native_drm.h |    2 +
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c
index 0cc06ca..6eaa42f 100644
--- a/src/gallium/state_trackers/egl/drm/modeset.c
+++ b/src/gallium/state_trackers/egl/drm/modeset.c
@@ -131,6 +131,21 @@ drm_surface_flush_frontbuffer(struct native_surface *nsurf)
 }
 
 static boolean
+drm_surface_copy_swap(struct native_surface *nsurf)
+{
+   struct drm_surface *drmsurf = drm_surface(nsurf);
+   struct drm_display *drmdpy = drmsurf->drmdpy;
+
+   if (!resource_surface_copy_swap(drmsurf->rsurf, &drmdpy->base) ||
+       !drm_surface_flush_frontbuffer(nsurf))
+      return FALSE;
+
+   drmsurf->sequence_number++;
+
+   return TRUE;
+}
+
+static boolean
 drm_surface_swap_buffers(struct native_surface *nsurf)
 {
    struct drm_surface *drmsurf = drm_surface(nsurf);
@@ -139,17 +154,21 @@ drm_surface_swap_buffers(struct native_surface *nsurf)
    struct drm_framebuffer tmp_fb;
    int err;
 
+   if (!drmsurf->have_pageflip)
+      return drm_surface_copy_swap(nsurf);
+
    if (!drmsurf->back_fb.buffer_id) {
       if (!drm_surface_init_framebuffers(&drmsurf->base, TRUE))
          return FALSE;
    }
 
    if (drmsurf->is_shown && drmcrtc->crtc) {
-      err = drmModeSetCrtc(drmdpy->fd, drmcrtc->crtc->crtc_id,
-            drmsurf->back_fb.buffer_id, drmcrtc->crtc->x, drmcrtc->crtc->y,
-            drmcrtc->connectors, drmcrtc->num_connectors, &drmcrtc->crtc->mode);
-      if (err)
-         return FALSE;
+      err = drmModePageFlip(drmdpy->fd, drmcrtc->crtc->crtc_id,
+			    drmsurf->back_fb.buffer_id, 0, NULL);
+      if (err) {
+	 drmsurf->have_pageflip = FALSE;
+         return drm_surface_copy_swap(nsurf);
+      }
    }
 
    /* swap the buffers */
@@ -175,7 +194,7 @@ drm_surface_present(struct native_surface *nsurf,
 {
    boolean ret;
 
-   if (preserve || swap_interval)
+   if (swap_interval)
       return FALSE;
 
    switch (natt) {
@@ -183,7 +202,10 @@ drm_surface_present(struct native_surface *nsurf,
       ret = drm_surface_flush_frontbuffer(nsurf);
       break;
    case NATIVE_ATTACHMENT_BACK_LEFT:
-      ret = drm_surface_swap_buffers(nsurf);
+      if (preserve)
+	 ret = drm_surface_copy_swap(nsurf);
+      else
+	 ret = drm_surface_swap_buffers(nsurf);
       break;
    default:
       ret = FALSE;
@@ -236,6 +258,7 @@ drm_display_create_surface(struct native_display *ndpy,
    drmsurf->color_format = drmconf->base.color_format;
    drmsurf->width = width;
    drmsurf->height = height;
+   drmsurf->have_pageflip = TRUE;
 
    drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
          drmsurf->color_format,
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 03c4fe0..7da9b45 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -91,6 +91,8 @@ struct drm_surface {
 
    boolean is_shown;
    struct drm_crtc current_crtc;
+
+   boolean have_pageflip;
 };
 
 struct drm_connector {
-- 
1.6.2.5



More information about the mesa-dev mailing list