AIGLX: Zero-copy texture-from-pixmap.
When available, use the 2D driver texOffsetStart hook and the 3D driver setTexOffset hook to save the overhead of passing the pixmap data to glTex(Sub)Image. The basic idea is to update the driver specific 'offset' for bound pixmaps before dispatching a GLX render request and to flush immediately afterwards if there are any pixmaps bound. This should ensure that the 3D driver can use pixmaps for texturing directly regardless of the X server moving them around.
This commit is contained in:
parent
5006d08d7f
commit
6324bfc468
|
@ -42,6 +42,10 @@
|
||||||
|
|
||||||
#include <damage.h>
|
#include <damage.h>
|
||||||
|
|
||||||
|
#ifdef XF86DRI
|
||||||
|
#include <GL/internal/dri_interface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
DrawablePtr pDraw;
|
DrawablePtr pDraw;
|
||||||
|
@ -50,7 +54,12 @@ typedef struct {
|
||||||
ScreenPtr pScreen;
|
ScreenPtr pScreen;
|
||||||
Bool idExists;
|
Bool idExists;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
#ifdef XF86DRI
|
||||||
DamagePtr pDamage;
|
DamagePtr pDamage;
|
||||||
|
__DRIcontext *pDRICtx;
|
||||||
|
GLint texname;
|
||||||
|
unsigned long offset;
|
||||||
|
#endif
|
||||||
} __GLXpixmap;
|
} __GLXpixmap;
|
||||||
|
|
||||||
struct __GLXdrawable {
|
struct __GLXdrawable {
|
||||||
|
|
253
GL/glx/glxdri.c
253
GL/glx/glxdri.c
|
@ -76,6 +76,11 @@ struct __GLXDRIscreen {
|
||||||
xf86EnterVTProc *enterVT;
|
xf86EnterVTProc *enterVT;
|
||||||
xf86LeaveVTProc *leaveVT;
|
xf86LeaveVTProc *leaveVT;
|
||||||
|
|
||||||
|
DRITexOffsetStartProcPtr texOffsetStart;
|
||||||
|
DRITexOffsetFinishProcPtr texOffsetFinish;
|
||||||
|
__GLXpixmap* texOffsetOverride[16];
|
||||||
|
GLuint lastTexOffsetOverride;
|
||||||
|
|
||||||
unsigned char glx_enable_bits[__GLX_EXT_BYTES];
|
unsigned char glx_enable_bits[__GLX_EXT_BYTES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,30 +130,75 @@ struct __GLXDRIdrawable {
|
||||||
static const char CREATE_NEW_SCREEN_FUNC[] =
|
static const char CREATE_NEW_SCREEN_FUNC[] =
|
||||||
"__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
|
"__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
|
||||||
|
|
||||||
/* The DRI driver entry point version wasn't bumped when the
|
|
||||||
* copySubBuffer functionality was added to the DRI drivers, but the
|
|
||||||
* functionality is still conditional on the value of the
|
|
||||||
* internal_api_version passed to __driCreateNewScreen. However, the
|
|
||||||
* screen constructor doesn't fail for a DRI driver that's older than
|
|
||||||
* the passed in version number, so there's no way we can know for
|
|
||||||
* sure that we can actually use the copySubBuffer functionality. But
|
|
||||||
* since the earliest (and at this point only) released mesa version
|
|
||||||
* (6.5) that uses the 20050727 entry point does have copySubBuffer,
|
|
||||||
* we'll just settle for that. We still have to pass in a higher to
|
|
||||||
* the screen constructor to enable the functionality.
|
|
||||||
*/
|
|
||||||
#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__glXDRIleaveServer(void)
|
__glXDRIleaveServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
DRIBlockHandler(NULL, NULL, NULL);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||||
|
__GLXDRIscreen * const screen =
|
||||||
|
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||||
|
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||||
|
|
||||||
|
if (lastOverride) {
|
||||||
|
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < lastOverride; j++) {
|
||||||
|
__GLXpixmap *pGlxPix = texOffsetOverride[j];
|
||||||
|
|
||||||
|
if (pGlxPix && pGlxPix->texname) {
|
||||||
|
pGlxPix->offset =
|
||||||
|
screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRIBlockHandler(NULL, NULL, NULL);
|
||||||
|
|
||||||
|
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||||
|
__GLXDRIscreen * const screen =
|
||||||
|
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||||
|
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||||
|
|
||||||
|
if (lastOverride) {
|
||||||
|
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < lastOverride; j++) {
|
||||||
|
__GLXpixmap *pGlxPix = texOffsetOverride[j];
|
||||||
|
|
||||||
|
if (pGlxPix && pGlxPix->texname) {
|
||||||
|
screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
|
||||||
|
pGlxPix->texname,
|
||||||
|
pGlxPix->offset,
|
||||||
|
pGlxPix->pDraw->depth,
|
||||||
|
((PixmapPtr)pGlxPix->pDraw)->
|
||||||
|
devKind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__glXDRIenterServer(void)
|
__glXDRIenterServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
DRIWakeupHandler(NULL, 0, NULL);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||||
|
__GLXDRIscreen * const screen =
|
||||||
|
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||||
|
|
||||||
|
if (screen->lastTexOffsetOverride) {
|
||||||
|
CALL_Flush(GET_DISPATCH(), ());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRIWakeupHandler(NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,19 +339,6 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
|
||||||
&context->driContext);
|
&context->driContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
glxCountBits(int word)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
while (word) {
|
|
||||||
ret += (word & 1);
|
|
||||||
word >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
|
glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -335,19 +372,75 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
||||||
int buffer,
|
int buffer,
|
||||||
__GLXpixmap *glxPixmap)
|
__GLXpixmap *glxPixmap)
|
||||||
{
|
{
|
||||||
RegionPtr pRegion;
|
RegionPtr pRegion = NULL;
|
||||||
PixmapPtr pixmap;
|
PixmapPtr pixmap;
|
||||||
int bpp;
|
int w, h, bpp, override = 0;
|
||||||
GLenum target, format, type;
|
GLenum target, format, type;
|
||||||
|
ScreenPtr pScreen = glxPixmap->pScreen;
|
||||||
|
__GLXDRIscreen * const screen =
|
||||||
|
(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
|
||||||
|
|
||||||
pixmap = (PixmapPtr) glxPixmap->pDraw;
|
pixmap = (PixmapPtr) glxPixmap->pDraw;
|
||||||
if (!glxPixmap->pDamage) {
|
w = pixmap->drawable.width;
|
||||||
glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
|
h = pixmap->drawable.height;
|
||||||
TRUE, glxPixmap->pScreen, NULL);
|
|
||||||
if (!glxPixmap->pDamage)
|
if (h & (h - 1) || w & (w - 1))
|
||||||
return BadAlloc;
|
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||||
|
else
|
||||||
|
target = GL_TEXTURE_2D;
|
||||||
|
|
||||||
|
if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
|
||||||
|
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||||
|
int i, firstEmpty = 16, texname;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
if (texOffsetOverride[i] == glxPixmap)
|
||||||
|
goto alreadyin;
|
||||||
|
|
||||||
|
if (firstEmpty == 16 && !texOffsetOverride[i])
|
||||||
|
firstEmpty = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstEmpty == 16) {
|
||||||
|
ErrorF("%s: Failed to register texture offset override\n", __func__);
|
||||||
|
goto nooverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstEmpty >= screen->lastTexOffsetOverride)
|
||||||
|
screen->lastTexOffsetOverride = firstEmpty + 1;
|
||||||
|
|
||||||
|
texOffsetOverride[firstEmpty] = glxPixmap;
|
||||||
|
|
||||||
|
alreadyin:
|
||||||
|
override = 1;
|
||||||
|
|
||||||
|
glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
|
||||||
|
|
||||||
|
CALL_GetIntegerv(GET_DISPATCH(), (target == GL_TEXTURE_2D ?
|
||||||
|
GL_TEXTURE_BINDING_2D :
|
||||||
|
GL_TEXTURE_BINDING_RECTANGLE_NV,
|
||||||
|
&texname));
|
||||||
|
|
||||||
|
if (texname == glxPixmap->texname)
|
||||||
|
return Success;
|
||||||
|
|
||||||
|
glxPixmap->texname = texname;
|
||||||
|
|
||||||
|
screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
|
||||||
|
pixmap->drawable.depth, pixmap->devKind);
|
||||||
|
}
|
||||||
|
nooverride:
|
||||||
|
|
||||||
|
if (!glxPixmap->pDamage) {
|
||||||
|
if (!override) {
|
||||||
|
glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
|
||||||
|
TRUE, pScreen, NULL);
|
||||||
|
if (!glxPixmap->pDamage)
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
|
||||||
|
}
|
||||||
|
|
||||||
DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
|
|
||||||
pRegion = NULL;
|
pRegion = NULL;
|
||||||
} else {
|
} else {
|
||||||
pRegion = DamageRegion(glxPixmap->pDamage);
|
pRegion = DamageRegion(glxPixmap->pDamage);
|
||||||
|
@ -360,30 +453,22 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
||||||
bpp = 4;
|
bpp = 4;
|
||||||
format = GL_BGRA;
|
format = GL_BGRA;
|
||||||
type =
|
type =
|
||||||
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
|
#if X_BYTE_ORDER == X_BIG_ENDIAN
|
||||||
GL_UNSIGNED_BYTE;
|
!override ? GL_UNSIGNED_INT_8_8_8_8_REV :
|
||||||
#else
|
|
||||||
GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
||||||
#endif
|
#endif
|
||||||
|
GL_UNSIGNED_BYTE;
|
||||||
} else {
|
} else {
|
||||||
bpp = 2;
|
bpp = 2;
|
||||||
format = GL_RGB;
|
format = GL_RGB;
|
||||||
type = GL_UNSIGNED_SHORT_5_6_5;
|
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(glxCountBits(pixmap->drawable.width) == 1 &&
|
|
||||||
glxCountBits(pixmap->drawable.height) == 1)
|
|
||||||
/* || strstr(CALL_GetString(GL_EXTENSIONS,
|
|
||||||
"GL_ARB_texture_non_power_of_two")) */)
|
|
||||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
|
||||||
else
|
|
||||||
target = GL_TEXTURE_2D;
|
|
||||||
|
|
||||||
CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
|
CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
|
||||||
pixmap->devKind / bpp) );
|
pixmap->devKind / bpp) );
|
||||||
|
|
||||||
if (pRegion == NULL)
|
if (pRegion == NULL)
|
||||||
{
|
{
|
||||||
if (pixmap->drawable.depth == 24)
|
if (!override && pixmap->drawable.depth == 24)
|
||||||
glxFillAlphaChannel(pixmap,
|
glxFillAlphaChannel(pixmap,
|
||||||
pixmap->drawable.x,
|
pixmap->drawable.x,
|
||||||
pixmap->drawable.y,
|
pixmap->drawable.y,
|
||||||
|
@ -404,8 +489,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
||||||
0,
|
0,
|
||||||
format,
|
format,
|
||||||
type,
|
type,
|
||||||
pixmap->devPrivate.ptr) );
|
override ? NULL : pixmap->devPrivate.ptr) );
|
||||||
} else {
|
} else if (!override) {
|
||||||
int i, numRects;
|
int i, numRects;
|
||||||
BoxPtr p;
|
BoxPtr p;
|
||||||
|
|
||||||
|
@ -436,7 +521,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DamageEmpty(glxPixmap->pDamage);
|
if (!override)
|
||||||
|
DamageEmpty(glxPixmap->pDamage);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
@ -446,6 +532,40 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext,
|
||||||
int buffer,
|
int buffer,
|
||||||
__GLXpixmap *pixmap)
|
__GLXpixmap *pixmap)
|
||||||
{
|
{
|
||||||
|
ScreenPtr pScreen = pixmap->pScreen;
|
||||||
|
__GLXDRIscreen * const screen =
|
||||||
|
(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
|
||||||
|
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||||
|
|
||||||
|
if (lastOverride) {
|
||||||
|
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < lastOverride; i++) {
|
||||||
|
if (texOffsetOverride[i] == pixmap) {
|
||||||
|
if (screen->texOffsetFinish)
|
||||||
|
screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
|
||||||
|
|
||||||
|
texOffsetOverride[i] = NULL;
|
||||||
|
|
||||||
|
if (i + 1 == lastOverride) {
|
||||||
|
lastOverride = 0;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
if (texOffsetOverride[i]) {
|
||||||
|
lastOverride = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->lastTexOffsetOverride = lastOverride;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,9 +786,9 @@ static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
|
||||||
fakeID = FakeClientID(0);
|
fakeID = FakeClientID(0);
|
||||||
*(XID *) contextID = fakeID;
|
*(XID *) contextID = fakeID;
|
||||||
|
|
||||||
__glXDRIenterServer();
|
__glXDRIenterServer(GL_FALSE);
|
||||||
retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
|
retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
|
||||||
__glXDRIleaveServer();
|
__glXDRIleaveServer(GL_FALSE);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,9 +797,9 @@ static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen,
|
||||||
{
|
{
|
||||||
GLboolean retval;
|
GLboolean retval;
|
||||||
|
|
||||||
__glXDRIenterServer();
|
__glXDRIenterServer(GL_FALSE);
|
||||||
retval = DRIDestroyContext(screenInfo.screens[screen], context);
|
retval = DRIDestroyContext(screenInfo.screens[screen], context);
|
||||||
__glXDRIleaveServer();
|
__glXDRIleaveServer(GL_FALSE);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,12 +814,12 @@ createDrawable(__DRInativeDisplay *dpy, int screen,
|
||||||
if (!pDrawable)
|
if (!pDrawable)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
__glXDRIenterServer();
|
__glXDRIenterServer(GL_FALSE);
|
||||||
retval = DRICreateDrawable(screenInfo.screens[screen],
|
retval = DRICreateDrawable(screenInfo.screens[screen],
|
||||||
drawable,
|
drawable,
|
||||||
pDrawable,
|
pDrawable,
|
||||||
hHWDrawable);
|
hHWDrawable);
|
||||||
__glXDRIleaveServer();
|
__glXDRIleaveServer(GL_FALSE);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,11 +833,11 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
|
||||||
if (!pDrawable)
|
if (!pDrawable)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
__glXDRIenterServer();
|
__glXDRIenterServer(GL_FALSE);
|
||||||
retval = DRIDestroyDrawable(screenInfo.screens[screen],
|
retval = DRIDestroyDrawable(screenInfo.screens[screen],
|
||||||
drawable,
|
drawable,
|
||||||
pDrawable);
|
pDrawable);
|
||||||
__glXDRIleaveServer();
|
__glXDRIleaveServer(GL_FALSE);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,14 +874,14 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
__glXDRIenterServer();
|
__glXDRIenterServer(GL_FALSE);
|
||||||
retval = DRIGetDrawableInfo(screenInfo.screens[screen],
|
retval = DRIGetDrawableInfo(screenInfo.screens[screen],
|
||||||
pDrawable, index, stamp,
|
pDrawable, index, stamp,
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
numClipRects, &pClipRects,
|
numClipRects, &pClipRects,
|
||||||
backX, backY,
|
backX, backY,
|
||||||
numBackClipRects, &pBackClipRects);
|
numBackClipRects, &pBackClipRects);
|
||||||
__glXDRIleaveServer();
|
__glXDRIleaveServer(GL_FALSE);
|
||||||
|
|
||||||
if (*numClipRects > 0) {
|
if (*numClipRects > 0) {
|
||||||
size = sizeof (drm_clip_rect_t) * *numClipRects;
|
size = sizeof (drm_clip_rect_t) * *numClipRects;
|
||||||
|
@ -866,7 +986,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
||||||
__DRIframebuffer framebuffer;
|
__DRIframebuffer framebuffer;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int status;
|
int status;
|
||||||
int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION;
|
int api_ver = 20070121;
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
drmVersionPtr version;
|
drmVersionPtr version;
|
||||||
int newlyopened;
|
int newlyopened;
|
||||||
|
@ -1048,6 +1168,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
||||||
goto handle_error;
|
goto handle_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
|
||||||
|
&screen->texOffsetFinish);
|
||||||
|
|
||||||
__glXScreenInit(&screen->base, pScreen);
|
__glXScreenInit(&screen->base, pScreen);
|
||||||
|
|
||||||
buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
|
buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
|
||||||
|
|
|
@ -238,9 +238,9 @@ GLboolean __glXFreeContext(__GLXcontext *cx)
|
||||||
* the latter case we need to lift the DRI lock manually. */
|
* the latter case we need to lift the DRI lock manually. */
|
||||||
|
|
||||||
if (!glxBlockClients) {
|
if (!glxBlockClients) {
|
||||||
__glXleaveServer();
|
__glXleaveServer(GL_FALSE);
|
||||||
cx->destroy(cx);
|
cx->destroy(cx);
|
||||||
__glXenterServer();
|
__glXenterServer(GL_FALSE);
|
||||||
} else {
|
} else {
|
||||||
cx->next = glxPendingDestroyContexts;
|
cx->next = glxPendingDestroyContexts;
|
||||||
glxPendingDestroyContexts = cx;
|
glxPendingDestroyContexts = cx;
|
||||||
|
@ -439,49 +439,49 @@ void glxResumeClients(void)
|
||||||
AttendClient(__glXClients[i]->client);
|
AttendClient(__glXClients[i]->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
__glXleaveServer();
|
__glXleaveServer(GL_FALSE);
|
||||||
for (cx = glxPendingDestroyContexts; cx != NULL; cx = next) {
|
for (cx = glxPendingDestroyContexts; cx != NULL; cx = next) {
|
||||||
next = cx->next;
|
next = cx->next;
|
||||||
|
|
||||||
cx->destroy(cx);
|
cx->destroy(cx);
|
||||||
}
|
}
|
||||||
glxPendingDestroyContexts = NULL;
|
glxPendingDestroyContexts = NULL;
|
||||||
__glXenterServer();
|
__glXenterServer(GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__glXnopEnterServer(void)
|
__glXnopEnterServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__glXnopLeaveServer(void)
|
__glXnopLeaveServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*__glXenterServerFunc)(void) = __glXnopEnterServer;
|
static void (*__glXenterServerFunc)(GLboolean) = __glXnopEnterServer;
|
||||||
static void (*__glXleaveServerFunc)(void) = __glXnopLeaveServer;
|
static void (*__glXleaveServerFunc)(GLboolean) = __glXnopLeaveServer;
|
||||||
|
|
||||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
|
void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
|
||||||
void (*leave)(void))
|
void (*leave)(GLboolean))
|
||||||
{
|
{
|
||||||
__glXenterServerFunc = enter;
|
__glXenterServerFunc = enter;
|
||||||
__glXleaveServerFunc = leave;
|
__glXleaveServerFunc = leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void __glXenterServer(void)
|
void __glXenterServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
glxServerLeaveCount--;
|
glxServerLeaveCount--;
|
||||||
|
|
||||||
if (glxServerLeaveCount == 0)
|
if (glxServerLeaveCount == 0)
|
||||||
(*__glXenterServerFunc)();
|
(*__glXenterServerFunc)(rendering);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __glXleaveServer(void)
|
void __glXleaveServer(GLboolean rendering)
|
||||||
{
|
{
|
||||||
if (glxServerLeaveCount == 0)
|
if (glxServerLeaveCount == 0)
|
||||||
(*__glXleaveServerFunc)();
|
(*__glXleaveServerFunc)(rendering);
|
||||||
|
|
||||||
glxServerLeaveCount++;
|
glxServerLeaveCount++;
|
||||||
}
|
}
|
||||||
|
@ -546,11 +546,12 @@ static int __glXDispatch(ClientPtr client)
|
||||||
opcode,
|
opcode,
|
||||||
client->swapped);
|
client->swapped);
|
||||||
if (proc != NULL) {
|
if (proc != NULL) {
|
||||||
__glXleaveServer();
|
GLboolean rendering = opcode <= X_GLXRenderLarge;
|
||||||
|
__glXleaveServer(rendering);
|
||||||
|
|
||||||
retval = (*proc)(cl, (GLbyte *) stuff);
|
retval = (*proc)(cl, (GLbyte *) stuff);
|
||||||
|
|
||||||
__glXenterServer();
|
__glXenterServer(rendering);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retval = BadRequest;
|
retval = BadRequest;
|
||||||
|
|
|
@ -106,11 +106,11 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
|
||||||
* why we need to re-take the lock and swap in the server context
|
* why we need to re-take the lock and swap in the server context
|
||||||
* before calling XMesaSwapBuffers() here. /me shakes head. */
|
* before calling XMesaSwapBuffers() here. /me shakes head. */
|
||||||
|
|
||||||
__glXenterServer();
|
__glXenterServer(GL_FALSE);
|
||||||
|
|
||||||
XMesaSwapBuffers(glxPriv->xm_buf);
|
XMesaSwapBuffers(glxPriv->xm_buf);
|
||||||
|
|
||||||
__glXleaveServer();
|
__glXleaveServer(GL_FALSE);
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,10 +131,10 @@ struct __GLXprovider {
|
||||||
|
|
||||||
void GlxPushProvider(__GLXprovider *provider);
|
void GlxPushProvider(__GLXprovider *provider);
|
||||||
|
|
||||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
|
void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
|
||||||
void (*leave)(void));
|
void (*leave)(GLboolean));
|
||||||
void __glXenterServer(void);
|
void __glXenterServer(GLboolean rendering);
|
||||||
void __glXleaveServer(void);
|
void __glXleaveServer(GLboolean rendering);
|
||||||
|
|
||||||
void glxSuspendClients(void);
|
void glxSuspendClients(void);
|
||||||
void glxResumeClients(void);
|
void glxResumeClients(void);
|
||||||
|
|
Loading…
Reference in New Issue