diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2007-06-11 09:23:19 +0200 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2007-06-11 09:23:19 +0200 |
commit | 1aceec61ff203848576c47a1eab13f90a67d7176 (patch) | |
tree | 7a5d0d37f92898ffb5234ea03eebecce835a7d1a /hw | |
parent | 5d896e43fd056d935935b4eb66562791edc247a1 (diff) |
DRI: Clip cliprects obtained from DRIGetDrawableInfo to screen dimensions.
This is to avoid issues with redirected windows which are located partly or
fully outside of a screen edge, resulting in unusual cliprects which the 3D
drivers generally can't handle. The symptoms in such cases would be incorrect
rendering or even crashes or hangs.
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/dri/dri.c | 19 | ||||
-rw-r--r-- | hw/xfree86/dri/xf86dri.c | 34 |
2 files changed, 43 insertions, 10 deletions
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index d153c090b..dbc1690f0 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -1518,13 +1518,18 @@ DRIGetDrawableInfo(ScreenPtr pScreen, if (x1 > pScreen->width) x1 = pScreen->width; if (y1 > pScreen->height) y1 = pScreen->height; - pDRIPriv->private_buffer_rect.x1 = x0; - pDRIPriv->private_buffer_rect.y1 = y0; - pDRIPriv->private_buffer_rect.x2 = x1; - pDRIPriv->private_buffer_rect.y2 = y1; - - *numBackClipRects = 1; - *pBackClipRects = &(pDRIPriv->private_buffer_rect); + if (y0 >= y1 || x0 >= x1) { + *numBackClipRects = 0; + *pBackClipRects = NULL; + } else { + pDRIPriv->private_buffer_rect.x1 = x0; + pDRIPriv->private_buffer_rect.y1 = y0; + pDRIPriv->private_buffer_rect.x2 = x1; + pDRIPriv->private_buffer_rect.y2 = y1; + + *numBackClipRects = 1; + *pBackClipRects = &(pDRIPriv->private_buffer_rect); + } } else { /* Use the frontbuffer cliprects for back buffers. */ *numBackClipRects = 0; diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c index 933cd3e18..9690e8895 100644 --- a/hw/xfree86/dri/xf86dri.c +++ b/hw/xfree86/dri/xf86dri.c @@ -452,7 +452,7 @@ ProcXF86DRIGetDrawableInfo( xXF86DRIGetDrawableInfoReply rep; DrawablePtr pDrawable; int X, Y, W, H; - drm_clip_rect_t * pClipRects; + drm_clip_rect_t * pClipRects, *pClippedRects; drm_clip_rect_t * pBackClipRects; int backX, backY, rc; @@ -502,8 +502,35 @@ ProcXF86DRIGetDrawableInfo( if (rep.numBackClipRects) rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; - if (rep.numClipRects) + pClippedRects = pClipRects; + + if (rep.numClipRects) { + /* Clip cliprects to screen dimensions (redirected windows) */ + pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t)); + + if (pClippedRects) { + ScreenPtr pScreen = screenInfo.screens[stuff->screen]; + int i, j; + + for (i = 0, j = 0; i < rep.numClipRects; i++) { + pClippedRects[j].x1 = max(pClipRects[i].x1, 0); + pClippedRects[j].y1 = max(pClipRects[i].y1, 0); + pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width); + pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height); + + if (pClippedRects[j].x1 < pClippedRects[j].x2 && + pClippedRects[j].y1 < pClippedRects[j].y2) { + j++; + } + } + + rep.numClipRects = j; + } else { + rep.numClipRects = 0; + } + rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; + } rep.length = ((rep.length + 3) & ~3) >> 2; @@ -512,7 +539,8 @@ ProcXF86DRIGetDrawableInfo( if (rep.numClipRects) { WriteToClient(client, sizeof(drm_clip_rect_t) * rep.numClipRects, - (char *)pClipRects); + (char *)pClippedRects); + xfree(pClippedRects); } if (rep.numBackClipRects) { |