summaryrefslogtreecommitdiff
path: root/src/amdgpu_present.c
diff options
context:
space:
mode:
authorTom St Denis <tom.stdenis@amd.com>2015-10-05 10:41:22 -0400
committerMichel Dänzer <michel@daenzer.net>2015-10-06 16:50:44 +0900
commita1e47e76322619ed037ebce27974a4e3792940c2 (patch)
tree7fe10a9f3b90281f9031d946437c364a04fb1834 /src/amdgpu_present.c
parentbac21dfc8e60a07f08158b13fab1f3a9b9d27d1b (diff)
present: Fall back to modeset for unflip operation
Based on radeon commit: 802d33e474a82262d9cdf11b03568b0c4929cd0d It's not always possible to use the page flip ioctl for this, e.g. during DPMS off. We were previously just skipping the unflip in that case, which could result in hangs when setting DPMS off while a fullscreen Present app is running, e.g. at the GNOME3 lock screen. Signed-off-by: Tom St Denis <tom.stdenis@amd.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Diffstat (limited to 'src/amdgpu_present.c')
-rw-r--r--src/amdgpu_present.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index 3db8cad..cbf733a 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -318,31 +318,51 @@ amdgpu_present_unflip(ScreenPtr screen, uint64_t event_id)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
struct amdgpu_present_vblank_event *event;
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
struct amdgpu_buffer *bo;
- Bool ret;
+ int i;
if (!amdgpu_present_check_flip(NULL, screen->root, pixmap, TRUE))
- return;
+ goto modeset;
bo = amdgpu_get_pixmap_bo(pixmap);
- if (!bo)
- return;
+ if (!bo) {
+ ErrorF("%s: amdgpu_get_pixmap_bo failed, display might freeze\n", __func__);
+ goto modeset;
+ }
event = calloc(1, sizeof(struct amdgpu_present_vblank_event));
- if (!event)
- return;
+ if (!event) {
+ ErrorF("%s: calloc failed, display might freeze\n", __func__);
+ goto modeset;
+ }
event->event_id = event_id;
- ret = amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, bo,
- event_id, event, -1, amdgpu_present_flip_event,
- amdgpu_present_flip_abort);
- if (!ret) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n");
- info->drmmode.present_flipping = FALSE;
+ if (amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, bo,
+ event_id, event, -1, amdgpu_present_flip_event,
+ amdgpu_present_flip_abort))
+ return;
+
+modeset:
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ if (!crtc->enabled)
+ continue;
+
+ if (drmmode_crtc->dpms_mode == DPMSModeOn)
+ crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ else
+ drmmode_crtc->need_modeset = TRUE;
}
+
+ present_event_notify(event_id, 0, 0);
+ info->drmmode.present_flipping = FALSE;
}
static present_screen_info_rec amdgpu_present_screen_info = {