From: Thomas Hellstrom Date: Thu, 24 Feb 2011 14:09:45 +0000 (+0100) Subject: st/egl/drm: Rework swapbuffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c9febff31f1032065f96ad76fd31f31ac330fef9;p=mesa.git st/egl/drm: Rework swapbuffers 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 --- diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c index 0cc06caa2a1..6eaa42fafb1 100644 --- a/src/gallium/state_trackers/egl/drm/modeset.c +++ b/src/gallium/state_trackers/egl/drm/modeset.c @@ -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, diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h index 03c4fe01dc1..7da9b45f23e 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 {