From b8e360bf2b77d28559d15a7c0f9c766848eb6ced Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 3 Jun 2009 10:12:25 +0000 Subject: [PATCH] Fix segfault in DRI2 vblank syncing if the region isn't onscreen. Also, fix some weirdness in the checking for whether the target was the screen. --- src/i830_dri.c | 57 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 667f687e..9da1d40d 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -289,7 +289,6 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, ? pDraw : &srcPrivate->pPixmap->drawable; DrawablePtr dst = (dstPrivate->attachment == DRI2BufferFrontLeft) ? pDraw : &dstPrivate->pPixmap->drawable; - PixmapPtr dst_pixmap = get_drawable_pixmap(dst); RegionPtr pCopyClip; GCPtr pGC; @@ -300,7 +299,7 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, ValidateGC(dst, pGC); /* Wait for the scanline to be outside the region to be copied */ - if (dstPrivate->attachment == DRI2BufferFrontLeft) { + if (pixmap_is_scanout(get_drawable_pixmap(dst))) { BoxPtr box; BoxRec crtcbox; int y1, y2; @@ -310,33 +309,35 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, box = REGION_EXTENTS(unused, pGC->pCompositeClip); crtc = i830_covering_crtc(pScrn, box, NULL, &crtcbox); - if (pI830->use_drm_mode) - pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc); - else { - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - pipe = intel_crtc->pipe; + if (crtc != NULL) { + if (pI830->use_drm_mode) + pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc); + else { + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + pipe = intel_crtc->pipe; + } + + if (pipe == 0) { + event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; + load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; + } else { + event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; + load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; + } + + y1 = box->y1 - crtc->y; + y2 = box->y2 - crtc->y; + + BEGIN_BATCH(5); + /* The documentation says that the LOAD_SCAN_LINES command + * always comes in pairs. Don't ask me why. */ + OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); + OUT_BATCH((y1 << 16) | y2); + OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); + OUT_BATCH((y1 << 16) | y2); + OUT_BATCH(MI_WAIT_FOR_EVENT | event); + ADVANCE_BATCH(); } - - if (pipe == 0) { - event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; - load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; - } else { - event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; - load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; - } - - y1 = box->y1 - crtc->y; - y2 = box->y2 - crtc->y; - - BEGIN_BATCH(5); - /* The documentation says that the LOAD_SCAN_LINES command - * always comes in pairs. Don't ask me why. */ - OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); - OUT_BATCH((y1 << 16) | y2); - OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); - OUT_BATCH((y1 << 16) | y2); - OUT_BATCH(MI_WAIT_FOR_EVENT | event); - ADVANCE_BATCH(); } (*pGC->ops->CopyArea)(src, dst,