-
-
Save dsd/6f2984f87f972f62d53e to your computer and use it in GitHub Desktop.
xserver patch to handle Mali's incorrect spew of DRI2CreateDrawable requests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The state of the DRI2CreateDrawable request is a little unclear. | |
dri2proto.txt states that it was dropped in version 1.99.2, but | |
actually this must still be called exactly once for each drawable | |
before GetBuffers and friends can be called, because it is the only | |
way that the internal DRI2DrawableRec structure will be allocated. | |
Mali fails to obey this unwritten rule and instead calls CreateDrawable | |
before each and every GetBuffers request. That causes a new dri2_id and | |
internal reference to be created every time. When we then come to | |
invalidate the drawable after GetBuffers+SwapBuffers for frame N, we end | |
up generating N invalidate events from DRI2InvalidateDrawable. Things | |
quickly get out of hand. | |
Fix this by detecting the fact that we're being called from | |
the DRI2CreateDrawable request context (i.e. caller does not get to | |
learn about the assigned dri2_id). In that case, just ensure that | |
we have allocated the relevant internal DRI2 private data, and return. | |
Signed-off-by: Daniel Drake <drake@endlessm.com> | |
--- | |
hw/xfree86/dri2/dri2.c | 7 +++++++ | |
1 file changed, 7 insertions(+) | |
Index: xorg-server-1.13.3/hw/xfree86/dri2/dri2.c | |
=================================================================== | |
--- xorg-server-1.13.3.orig/hw/xfree86/dri2/dri2.c 2014-02-25 10:37:59.002464709 -0600 | |
+++ xorg-server-1.13.3/hw/xfree86/dri2/dri2.c 2014-02-25 11:38:29.229158820 -0600 | |
@@ -101,6 +101,7 @@ | |
int swap_limit; /* for N-buffering */ | |
unsigned long serialNumber; | |
Bool needInvalidate; | |
+ Bool client_created; | |
int prime_id; | |
PixmapPtr prime_slave_pixmap; | |
PixmapPtr redirectpixmap; | |
@@ -215,6 +216,7 @@ | |
if (pPriv == NULL) | |
return NULL; | |
+ pPriv->client_created = FALSE; | |
pPriv->dri2_screen = ds; | |
pPriv->drawable = pDraw; | |
pPriv->width = pDraw->width; | |
@@ -343,6 +345,15 @@ | |
int rc; | |
pPriv = DRI2GetDrawable(pDraw); | |
+ if (pPriv && dri2_id_out == NULL && pPriv->client_created) { | |
+ /* We already allocated a DRI2Drawable for this drawable, the client | |
+ * has called into this function (so will receive invalidate events) | |
+ * and now we're being called by the client again (we know this because | |
+ * the caller doesn't care about the dri2_id). This means we don't need | |
+ * to allocate another one, we have nothing else to do. */ | |
+ pPriv->prime_id = dri2_client->prime_id; | |
+ return Success; | |
+ } | |
if (pPriv == NULL) | |
pPriv = DRI2AllocateDrawable(pDraw); | |
if (pPriv == NULL) | |
@@ -357,6 +368,11 @@ | |
if (dri2_id_out) | |
*dri2_id_out = dri2_id; | |
+ else { | |
+ /* The client has called in for the first time, it will now receive | |
+ * invalidate events. Record this for later. */ | |
+ pPriv->client_created = TRUE; | |
+ } | |
return Success; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment