dri2: support glXWaitX & glXWaitGL by using fake front buffer.
This commit is contained in:
@@ -77,6 +77,9 @@ struct __GLXDRIdrawablePrivateRec {
|
|||||||
int bufferCount;
|
int bufferCount;
|
||||||
int width, height;
|
int width, height;
|
||||||
unsigned long configureSeqno;
|
unsigned long configureSeqno;
|
||||||
|
int have_back;
|
||||||
|
int have_front;
|
||||||
|
int have_fake_front;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dri2DestroyContext(__GLXDRIcontext *context,
|
static void dri2DestroyContext(__GLXDRIcontext *context,
|
||||||
@@ -196,6 +199,10 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
|
|||||||
XRectangle xrect;
|
XRectangle xrect;
|
||||||
XserverRegion region;
|
XserverRegion region;
|
||||||
|
|
||||||
|
/* Check we have the right attachments */
|
||||||
|
if (!(priv->have_front && priv->have_back))
|
||||||
|
return;
|
||||||
|
|
||||||
xrect.x = x;
|
xrect.x = x;
|
||||||
xrect.y = priv->height - y - height;
|
xrect.y = priv->height - y - height;
|
||||||
xrect.width = width;
|
xrect.width = width;
|
||||||
@@ -214,6 +221,47 @@ static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
|
|||||||
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
|
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dri2WaitX(__GLXDRIdrawable *pdraw)
|
||||||
|
{
|
||||||
|
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
|
||||||
|
XRectangle xrect;
|
||||||
|
XserverRegion region;
|
||||||
|
|
||||||
|
/* Check we have the right attachments */
|
||||||
|
if (!(priv->have_fake_front && priv->have_front))
|
||||||
|
return;
|
||||||
|
|
||||||
|
xrect.x = 0;
|
||||||
|
xrect.y = 0;
|
||||||
|
xrect.width = priv->width;
|
||||||
|
xrect.height = priv->height;
|
||||||
|
|
||||||
|
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
|
||||||
|
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
|
||||||
|
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
|
||||||
|
XFixesDestroyRegion(pdraw->psc->dpy, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dri2WaitGL(__GLXDRIdrawable *pdraw)
|
||||||
|
{
|
||||||
|
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
|
||||||
|
XRectangle xrect;
|
||||||
|
XserverRegion region;
|
||||||
|
|
||||||
|
if (!(priv->have_fake_front && priv->have_front))
|
||||||
|
return;
|
||||||
|
|
||||||
|
xrect.x = 0;
|
||||||
|
xrect.y = 0;
|
||||||
|
xrect.width = priv->width;
|
||||||
|
xrect.height = priv->height;
|
||||||
|
|
||||||
|
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
|
||||||
|
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
|
||||||
|
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
|
||||||
|
XFixesDestroyRegion(pdraw->psc->dpy, region);
|
||||||
|
}
|
||||||
|
|
||||||
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
|
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
|
||||||
{
|
{
|
||||||
/* Free the direct rendering per screen data */
|
/* Free the direct rendering per screen data */
|
||||||
@@ -261,6 +309,9 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
|
|||||||
pdraw->width = *width;
|
pdraw->width = *width;
|
||||||
pdraw->height = *height;
|
pdraw->height = *height;
|
||||||
pdraw->bufferCount = *out_count;
|
pdraw->bufferCount = *out_count;
|
||||||
|
pdraw->have_front = 0;
|
||||||
|
pdraw->have_fake_front = 0;
|
||||||
|
pdraw->have_back = 0;
|
||||||
|
|
||||||
/* This assumes the DRI2 buffer attachment tokens matches the
|
/* This assumes the DRI2 buffer attachment tokens matches the
|
||||||
* __DRIbuffer tokens. */
|
* __DRIbuffer tokens. */
|
||||||
@@ -270,6 +321,12 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
|
|||||||
pdraw->buffers[i].pitch = buffers[i].pitch;
|
pdraw->buffers[i].pitch = buffers[i].pitch;
|
||||||
pdraw->buffers[i].cpp = buffers[i].cpp;
|
pdraw->buffers[i].cpp = buffers[i].cpp;
|
||||||
pdraw->buffers[i].flags = buffers[i].flags;
|
pdraw->buffers[i].flags = buffers[i].flags;
|
||||||
|
if (pdraw->buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
|
||||||
|
pdraw->have_front = 1;
|
||||||
|
if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
|
||||||
|
pdraw->have_fake_front = 1;
|
||||||
|
if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
|
||||||
|
pdraw->have_back = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xfree(buffers);
|
Xfree(buffers);
|
||||||
@@ -366,6 +423,8 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
|
|||||||
psp->createContext = dri2CreateContext;
|
psp->createContext = dri2CreateContext;
|
||||||
psp->createDrawable = dri2CreateDrawable;
|
psp->createDrawable = dri2CreateDrawable;
|
||||||
psp->swapBuffers = dri2SwapBuffers;
|
psp->swapBuffers = dri2SwapBuffers;
|
||||||
|
psp->waitGL = dri2WaitGL;
|
||||||
|
psp->waitX = dri2WaitX;
|
||||||
|
|
||||||
/* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
|
/* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
|
||||||
* available.*/
|
* available.*/
|
||||||
|
@@ -655,6 +655,8 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
|||||||
psp->createContext = driCreateContext;
|
psp->createContext = driCreateContext;
|
||||||
psp->createDrawable = driCreateDrawable;
|
psp->createDrawable = driCreateDrawable;
|
||||||
psp->swapBuffers = driSwapBuffers;
|
psp->swapBuffers = driSwapBuffers;
|
||||||
|
psp->waitX = NULL;
|
||||||
|
psp->waitGL = NULL;
|
||||||
|
|
||||||
return psp;
|
return psp;
|
||||||
}
|
}
|
||||||
|
@@ -139,6 +139,8 @@ struct __GLXDRIscreenRec {
|
|||||||
void (*swapBuffers)(__GLXDRIdrawable *pdraw);
|
void (*swapBuffers)(__GLXDRIdrawable *pdraw);
|
||||||
void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
|
void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
|
||||||
int x, int y, int width, int height);
|
int x, int y, int width, int height);
|
||||||
|
void (*waitX)(__GLXDRIdrawable *pdraw);
|
||||||
|
void (*waitGL)(__GLXDRIdrawable *pdraw);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __GLXDRIcontextRec {
|
struct __GLXDRIcontextRec {
|
||||||
|
@@ -611,11 +611,15 @@ PUBLIC void glXWaitGL(void)
|
|||||||
|
|
||||||
#ifdef GLX_DIRECT_RENDERING
|
#ifdef GLX_DIRECT_RENDERING
|
||||||
if (gc->driContext) {
|
if (gc->driContext) {
|
||||||
/* This bit of ugliness unwraps the glFinish function */
|
int screen;
|
||||||
#ifdef glFinish
|
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
|
||||||
#undef glFinish
|
|
||||||
#endif
|
if ( pdraw != NULL ) {
|
||||||
glFinish();
|
__GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
|
||||||
|
glFlush();
|
||||||
|
if (psc->driScreen->waitGL != NULL)
|
||||||
|
(*psc->driScreen->waitGL)(pdraw);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -647,7 +651,15 @@ PUBLIC void glXWaitX(void)
|
|||||||
|
|
||||||
#ifdef GLX_DIRECT_RENDERING
|
#ifdef GLX_DIRECT_RENDERING
|
||||||
if (gc->driContext) {
|
if (gc->driContext) {
|
||||||
XSync(dpy, False);
|
int screen;
|
||||||
|
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
|
||||||
|
|
||||||
|
if ( pdraw != NULL ) {
|
||||||
|
__GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
|
||||||
|
if (psc->driScreen->waitX != NULL)
|
||||||
|
(*psc->driScreen->waitX)(pdraw);
|
||||||
|
} else
|
||||||
|
XSync(dpy, False);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user