mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
dri2: Avoid round-tripping on DRI2GetBuffers for the same set of buffers.
We only wanted to request when asked for the same set of buffers when a resize has happened. We can just watch the protocol stream for a ConfigureNotify and flag to do it then. This is about a 5% win from doing two glViewport()s per frame in openarena.
This commit is contained in:
parent
92ced46eaf
commit
dd1c68f151
2 changed files with 53 additions and 0 deletions
|
|
@ -60,6 +60,9 @@ struct __GLXDRIdisplayPrivateRec {
|
|||
int driMajor;
|
||||
int driMinor;
|
||||
int driPatch;
|
||||
|
||||
unsigned long configureSeqno;
|
||||
Bool (*oldConfigProc)(Display *, XEvent *, xEvent *);
|
||||
};
|
||||
|
||||
struct __GLXDRIcontextPrivateRec {
|
||||
|
|
@ -73,6 +76,7 @@ struct __GLXDRIdrawablePrivateRec {
|
|||
__DRIbuffer buffers[5];
|
||||
int bufferCount;
|
||||
int width, height;
|
||||
unsigned long configureSeqno;
|
||||
};
|
||||
|
||||
static void dri2DestroyContext(__GLXDRIcontext *context,
|
||||
|
|
@ -166,6 +170,7 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
|
|||
pdraw->base.xDrawable = xDrawable;
|
||||
pdraw->base.drawable = drawable;
|
||||
pdraw->base.psc = psc;
|
||||
pdraw->configureSeqno = ~0;
|
||||
|
||||
DRI2CreateDrawable(psc->dpy, xDrawable);
|
||||
|
||||
|
|
@ -223,9 +228,30 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
|
|||
int *out_count, void *loaderPrivate)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
|
||||
__GLXdisplayPrivate *dpyPriv = __glXInitialize(pdraw->base.psc->dpy);
|
||||
__GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
|
||||
DRI2Buffer *buffers;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* Check if a ConfigureNotify has come in since we last asked for the
|
||||
* buffers associated with this drawable. If not, we can assume that they're
|
||||
* the same set at glViewport time, and save a synchronous round-trip to the
|
||||
* X Server.
|
||||
*/
|
||||
if (pdraw->configureSeqno == pdp->configureSeqno &&
|
||||
count == pdraw->bufferCount) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (pdraw->buffers[i].attachment != attachments[i])
|
||||
break;
|
||||
}
|
||||
if (i == count) {
|
||||
*out_count = pdraw->bufferCount;
|
||||
return pdraw->buffers;
|
||||
}
|
||||
}
|
||||
pdraw->configureSeqno = pdp->configureSeqno;
|
||||
|
||||
buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
|
||||
width, height, attachments, count, out_count);
|
||||
if (buffers == NULL)
|
||||
|
|
@ -233,6 +259,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
|
|||
|
||||
pdraw->width = *width;
|
||||
pdraw->height = *height;
|
||||
pdraw->bufferCount = *out_count;
|
||||
|
||||
/* This assumes the DRI2 buffer attachment tokens matches the
|
||||
* __DRIbuffer tokens. */
|
||||
|
|
@ -365,6 +392,28 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy)
|
|||
Xfree(dpy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a note on receiving ConfigureNotify that we need to re-check the
|
||||
* DRI2 buffers, as window sizes may have resulted in reallocation.
|
||||
*/
|
||||
static Bool dri2ConfigureNotifyProc(Display *dpy, XEvent *re, xEvent *event)
|
||||
{
|
||||
__GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
|
||||
__GLXDRIdisplayPrivate *pdp;
|
||||
Bool ret;
|
||||
|
||||
/* We should always be able to find our pdp, as it only gets torn down
|
||||
* when the Display is torn down.
|
||||
*/
|
||||
pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
|
||||
|
||||
ret = pdp->oldConfigProc(dpy, re, event);
|
||||
|
||||
pdp->configureSeqno = re->xconfigure.serial;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate, initialize and return a __DRIdisplayPrivate object.
|
||||
* This is called from __glXInitialize() when we are given a new
|
||||
|
|
@ -387,6 +436,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pdp->oldConfigProc = XESetWireToEvent(dpy, ConfigureNotify,
|
||||
dri2ConfigureNotifyProc);
|
||||
|
||||
pdp->driPatch = 0;
|
||||
|
||||
pdp->base.destroyDisplay = dri2DestroyDisplay;
|
||||
|
|
|
|||
|
|
@ -602,6 +602,7 @@ extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint,
|
|||
const GLvoid *, GLint);
|
||||
|
||||
/* Initialize the GLX extension for dpy */
|
||||
extern __GLXdisplayPrivate * __glXGetPrivateFromDisplay(Display *dpy);
|
||||
extern __GLXdisplayPrivate *__glXInitialize(Display*);
|
||||
|
||||
/************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue