[PATCH 3/5] glx: Implement GLX_EXT_swap_control
Adam Jackson
ajax at redhat.com
Tue Jun 2 10:41:06 PDT 2015
This is incomplete, as it does not update the generated code to include
the dispatch code.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
glx/extension_string.c | 1 +
glx/extension_string.h | 1 +
glx/glxcmds.c | 21 +++++++++++++--
glx/glxdrawable.h | 4 +--
glx/glxdri2.c | 5 +---
glx/glxdricommon.c | 2 ++
glx/glxscreens.h | 4 +++
glx/glxserver.h | 4 +++
glx/indirect_dispatch.h | 7 +++++
glx/swap_interval.c | 69 ++++++++++++++++++++++++++++++++++++-------------
10 files changed, 91 insertions(+), 27 deletions(-)
diff --git a/glx/extension_string.c b/glx/extension_string.c
index e881d21..d2c942b 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -83,6 +83,7 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(EXT_create_context_es2_profile), VER(0,0), N, },
{ GLX(EXT_framebuffer_sRGB), VER(0,0), N, },
{ GLX(EXT_import_context), VER(0,0), Y, },
+ { GLX(EXT_swap_control), VER(0,0), N, },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, },
{ GLX(EXT_visual_info), VER(0,0), Y, },
{ GLX(EXT_visual_rating), VER(0,0), Y, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index bac7b06..99eb2f7 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -45,6 +45,7 @@ enum {
ARB_multisample_bit,
EXT_create_context_es2_profile_bit,
EXT_import_context_bit,
+ EXT_swap_control_bit,
EXT_texture_from_pixmap_bit,
EXT_visual_info_bit,
EXT_visual_rating_bit,
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index cbd4ede..8139149 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -486,7 +486,7 @@ StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
* resource ID, look up the GLX drawable if available, otherwise, make
* sure it's an X window and create a GLX drawable one the fly.
*/
-static __GLXdrawable *
+__GLXdrawable *
__glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
int *error)
{
@@ -1214,6 +1214,7 @@ __glXDrawableInit(__GLXdrawable * drawable,
drawable->drawId = drawId;
drawable->config = config;
drawable->eventMask = 0;
+ drawable->swap_interval = 0;
return GL_TRUE;
}
@@ -1926,6 +1927,14 @@ __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
return Success;
}
+/* hack for old glxext.h */
+#ifndef GLX_SWAP_INTERVAL_EXT
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#endif
+#ifndef GLX_MAX_SWAP_INTERVAL_EXT
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+#endif
+
/*
** Get drawable attributes
*/
@@ -1936,7 +1945,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
xGLXGetDrawableAttributesReply reply;
__GLXdrawable *pGlxDraw = NULL;
DrawablePtr pDraw;
- CARD32 attributes[14];
+ CARD32 attributes[16];
int num = 0, error;
if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
@@ -1976,6 +1985,14 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
attributes[2*num+1] = GL_TRUE;
num++;
}
+ if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
+ attributes[2*num] = GLX_SWAP_INTERVAL_EXT;
+ attributes[2*num+1] = pGlxDraw->swap_interval;
+ num++;
+ attributes[2*num] = GLX_MAX_SWAP_INTERVAL_EXT;
+ attributes[2*num+1] = pGlxDraw->config->maxSwapInterval;
+ num++;
+ }
}
reply = (xGLXGetDrawableAttributesReply) {
diff --git a/glx/glxdrawable.h b/glx/glxdrawable.h
index 0076589..3947658 100644
--- a/glx/glxdrawable.h
+++ b/glx/glxdrawable.h
@@ -68,10 +68,8 @@ struct __GLXdrawable {
GLenum target;
GLenum format;
- /*
- ** Event mask
- */
unsigned long eventMask;
+ uint32_t swap_interval;
};
#endif /* !__GLX_drawable_h__ */
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 6fb3d92..d5f47ab 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -226,16 +226,13 @@ __glXDRIdrawableSwapInterval(__GLXdrawable * drawable, int interval)
{
__GLXcontext *cx = lastGLContext;
- if (interval <= 0) /* || interval > BIGNUM? */
- return GLX_BAD_VALUE;
-
DRI2SwapInterval(drawable->pDraw, interval);
if (cx != lastGLContext) {
lastGLContext = cx;
cx->makeCurrent(cx);
}
- return 0;
+ return Success;
}
static void
diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
index 62cce13..a14fdef 100644
--- a/glx/glxdricommon.c
+++ b/glx/glxdricommon.c
@@ -103,6 +103,8 @@ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
__ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
__ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_MAX_SWAP_INTERVAL, maxSwapInterval),
+ __ATTRIB(__DRI_ATTRIB_MIN_SWAP_INTERVAL, minSwapInterval),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index a905877..bfd862d 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -92,6 +92,10 @@ struct __GLXconfig {
/* OML_swap_method */
GLint swapMethod;
+ /* EXT_swap_control */
+ GLint maxSwapInterval;
+ GLint minSwapInterval;
+
/* EXT_texture_from_pixmap */
GLint bindToTextureRgb;
GLint bindToTextureRgba;
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 9088ec4..753805b 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -280,4 +280,8 @@ extern unsigned glxMinorVersion;
extern int __glXEventBase;
+extern __GLXdrawable *
+__glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
+ int *error);
+
#endif /* !__GLX_server_h__ */
diff --git a/glx/indirect_dispatch.h b/glx/indirect_dispatch.h
index 536be60..72c48f6 100644
--- a/glx/indirect_dispatch.h
+++ b/glx/indirect_dispatch.h
@@ -1356,4 +1356,11 @@ extern _X_HIDDEN void __glXDispSwap_SecondaryColor3sv(GLbyte * pc);
extern _X_HIDDEN void __glXDisp_MultiTexCoord2sv(GLbyte * pc);
extern _X_HIDDEN void __glXDispSwap_MultiTexCoord2sv(GLbyte * pc);
+/* XXX should be autogenerated */
+
+extern _X_HIDDEN int __glXDisp_SwapIntervalEXT(struct __GLXclientStateRec *,
+ GLbyte *);
+extern _X_HIDDEN int __glXDispSwap_SwapIntervalEXT(struct __GLXclientStateRec *,
+ GLbyte *);
+
#endif /* !defined( _INDIRECT_DISPATCH_H_ ) */
diff --git a/glx/swap_interval.c b/glx/swap_interval.c
index 2320550..c59840d 100644
--- a/glx/swap_interval.c
+++ b/glx/swap_interval.c
@@ -35,18 +35,18 @@
#include "indirect_dispatch.h"
#include "glxbyteorder.h"
-static int DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap);
-
-int
-DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap)
+static int
+DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap, int ext)
{
xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client;
const GLXContextTag tag = req->contextTag;
__GLXcontext *cx;
+ __GLXdrawable *draw;
GLint interval;
+ int ret;
- REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4);
+ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4 + (ext * 4));
cx = __glXLookupContextByTag(cl, tag);
@@ -61,31 +61,64 @@ DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap)
return __glXError(GLXUnsupportedPrivateRequest);
}
- if (cx->drawPriv == NULL) {
- client->errorValue = tag;
- return BadValue;
- }
-
pc += __GLX_VENDPRIV_HDR_SIZE;
- interval = (do_swap)
- ? bswap_32(*(int *) (pc + 0))
- : *(int *) (pc + 0);
- if (interval <= 0)
+ if (ext) {
+ int error;
+ XID drawable = (do_swap)
+ ? bswap_32(*(int *) (pc + 0))
+ : *(int *) (pc + 0);
+
+ interval = (do_swap)
+ ? bswap_32(*(int *) (pc + 4))
+ : *(int *) (pc + 4);
+
+ draw = __glXGetDrawable(cx, drawable, cl->client, &error);
+ if (!draw || draw->type != GLX_DRAWABLE_WINDOW)
+ return BadWindow;
+
+ } else {
+ interval = (do_swap)
+ ? bswap_32(*(int *) (pc + 0))
+ : *(int *) (pc + 0);
+ draw = cx->drawPriv;
+ }
+
+ if (draw == NULL) {
+ client->errorValue = tag;
return BadValue;
+ }
+
+ if (interval < 0 || (!ext && !interval))
+ return BadValue;
+
+ ret = (*cx->pGlxScreen->swapInterval) (draw, interval);
+ if (ret == Success)
+ draw->swap_interval = interval;
- (void) (*cx->pGlxScreen->swapInterval) (cx->drawPriv, interval);
- return Success;
+ return ret;
}
int
__glXDisp_SwapIntervalSGI(__GLXclientState * cl, GLbyte * pc)
{
- return DoSwapInterval(cl, pc, 0);
+ return DoSwapInterval(cl, pc, 0, 0);
}
int
__glXDispSwap_SwapIntervalSGI(__GLXclientState * cl, GLbyte * pc)
{
- return DoSwapInterval(cl, pc, 1);
+ return DoSwapInterval(cl, pc, 1, 0);
+}
+
+int
+__glXDisp_SwapIntervalEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ return DoSwapInterval(cl, pc, 0, 1);
+}
+
+int
+__glXDispSwap_SwapIntervalEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ return DoSwapInterval(cl, pc, 1, 1);
}
--
2.4.1
More information about the xorg-devel
mailing list