st/egl/drm: Rework swapbuffers
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 24 Feb 2011 14:09:45 +0000 (15:09 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Tue, 1 Mar 2011 09:36:19 +0000 (10:36 +0100)
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@vmware.com>
src/gallium/state_trackers/egl/drm/modeset.c
src/gallium/state_trackers/egl/drm/native_drm.h

index 0cc06caa2a199617d9ca5d6262acb5b061fe7ec8..6eaa42fafb1d129727c241f9474e57fca39e2f41 100644 (file)
@@ -130,6 +130,21 @@ drm_surface_flush_frontbuffer(struct native_surface *nsurf)
    return TRUE;
 }
 
+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)
 {
@@ -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,
index 03c4fe01dc10897928980461d32a9732acdeadb7..7da9b45f23e269b7e1a647c3035d2e580dc8043b 100644 (file)
@@ -91,6 +91,8 @@ struct drm_surface {
 
    boolean is_shown;
    struct drm_crtc current_crtc;
+
+   boolean have_pageflip;
 };
 
 struct drm_connector {