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 <[email protected]> --- hw/xfree86/dri2/dri2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 729a323..4eba896 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -328,6 +328,13 @@ DRI2CreateDrawable2(ClientPtr client, DrawablePtr pDraw, XID id, int rc; pPriv = DRI2GetDrawable(pDraw); + if (pPriv && dri2_id_out == NULL) { + /* We already allocated a DRI2Drawable for this drawable, and 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) -- 1.8.3.2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
