mirror of
https://github.com/X11Libre/xserver.git
synced 2026-04-14 17:18:09 +00:00
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.
This commit is contained in:
@@ -886,8 +886,32 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
|
||||
if (*numClipRects > 0) {
|
||||
size = sizeof (drm_clip_rect_t) * *numClipRects;
|
||||
*ppClipRects = xalloc (size);
|
||||
if (*ppClipRects != NULL)
|
||||
memcpy (*ppClipRects, pClipRects, size);
|
||||
|
||||
/* Clip cliprects to screen dimensions (redirected windows) */
|
||||
if (*ppClipRects != NULL) {
|
||||
ScreenPtr pScreen = screenInfo.screens[screen];
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < *numClipRects; i++) {
|
||||
(*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
|
||||
(*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
|
||||
(*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
|
||||
(*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
|
||||
|
||||
if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
|
||||
(*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*numClipRects != j) {
|
||||
*numClipRects = j;
|
||||
*ppClipRects = xrealloc (*ppClipRects,
|
||||
sizeof (drm_clip_rect_t) *
|
||||
*numClipRects);
|
||||
}
|
||||
} else
|
||||
*numClipRects = 0;
|
||||
}
|
||||
else {
|
||||
*ppClipRects = NULL;
|
||||
|
||||
@@ -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;
|
||||
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);
|
||||
*numBackClipRects = 1;
|
||||
*pBackClipRects = &(pDRIPriv->private_buffer_rect);
|
||||
}
|
||||
} else {
|
||||
/* Use the frontbuffer cliprects for back buffers. */
|
||||
*numBackClipRects = 0;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user