xf86-video-intel: src/i830_dri.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri May 14 02:38:32 PDT 2010
src/i830_dri.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
New commits:
commit 0d2392d44aae95d6b571d98f7ec323cf672a687f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 14 10:32:12 2010 +0100
dri: Hold reference to buffers across swap
As we schedule swaps for some time in the future and may process a
detachment prior to receiving the vblank notification from the kernel,
we need to hold a reference to the buffers for our swap event handler.
Fixes:
Bug 28080 - "glresize" causes X server segfault with indirect rendering.
https://bugs.freedesktop.org/show_bug.cgi?id=28080
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 9500dad..21871c5 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -75,6 +75,7 @@ extern XF86ModuleData dri2ModuleData;
#endif
typedef struct {
+ int refcnt;
PixmapPtr pixmap;
unsigned int attachment;
} I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
@@ -147,6 +148,7 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
buffers[i].cpp = pixmap->drawable.bitsPerPixel / 8;
buffers[i].driverPrivate = &privates[i];
buffers[i].flags = 0; /* not tiled */
+ privates[i].refcnt = 1;
privates[i].pixmap = pixmap;
privates[i].attachment = attachments[i];
@@ -223,6 +225,7 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
buffer->driverPrivate = privates;
buffer->format = format;
buffer->flags = 0; /* not tiled */
+ privates->refcnt = 1;
privates->pixmap = pixmap;
privates->attachment = attachment;
@@ -262,17 +265,27 @@ static void I830DRI2DestroyBuffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
{
if (buffer) {
I830DRI2BufferPrivatePtr private = buffer->driverPrivate;
- ScreenPtr screen = drawable->pScreen;
+ if (--private->refcnt == 0) {
+ ScreenPtr screen = private->pixmap->drawable.pScreen;
- screen->DestroyPixmap(private->pixmap);
+ screen->DestroyPixmap(private->pixmap);
- xfree(private);
- xfree(buffer);
+ xfree(private);
+ xfree(buffer);
+ }
}
}
#endif
+static void I830DRI2ReferenceBuffer(DRI2Buffer2Ptr buffer)
+{
+ if (buffer) {
+ I830DRI2BufferPrivatePtr private = buffer->driverPrivate;
+ private->refcnt++;
+ }
+}
+
static void
I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
@@ -510,6 +523,8 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
M_ANY, DixWriteAccess);
if (status != Success) {
+ I830DRI2DestroyBuffer(NULL, event->front);
+ I830DRI2DestroyBuffer(NULL, event->back);
xfree(event);
return;
}
@@ -568,6 +583,8 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
break;
}
+ I830DRI2DestroyBuffer(drawable, event->front);
+ I830DRI2DestroyBuffer(drawable, event->back);
xfree(event);
}
@@ -661,6 +678,8 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
swap_info->event_data = data;
swap_info->front = front;
swap_info->back = back;
+ I830DRI2ReferenceBuffer(front);
+ I830DRI2ReferenceBuffer(back);
/* Get current count */
vbl.request.type = DRM_VBLANK_RELATIVE;
@@ -791,8 +810,11 @@ blit_fallback:
I830DRI2CopyRegion(draw, ®ion, front, back);
DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
- if (swap_info)
+ if (swap_info) {
+ I830DRI2DestroyBuffer(draw, swap_info->front);
+ I830DRI2DestroyBuffer(draw, swap_info->back);
xfree(swap_info);
+ }
*target_msc = 0; /* offscreen, so zero out target vblank count */
return TRUE;
}
More information about the xorg-commit
mailing list