xfont
xrotfontdemo
yuvrect_client
+msctest
glxsnoop \
glxswapcontrol \
manywin \
+ msctest \
multictx \
offset \
overlay \
--- /dev/null
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jesse Barnes <jesse.barnes@intel.com>
+ *
+ */
+
+/** @file msctest.c
+ * Simple test for MSC functionality.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+void (*get_sync_values)(Display *dpy, Window winGL, int64_t *ust, int64_t *msc, int64_t *sbc);
+void (*wait_sync)(Display *dpy, Window winGL, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+
+static int GLXExtensionSupported(Display *dpy, const char *extension)
+{
+ const char *extensionsString, *client_extensions, *pos;
+
+ extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
+ client_extensions = glXGetClientString(dpy, GLX_EXTENSIONS);
+
+ pos = strstr(extensionsString, extension);
+
+ if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
+ (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
+ return 1;
+
+ pos = strstr(client_extensions, extension);
+
+ if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
+ (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
+ return 1;
+
+ return 0;
+}
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+static char optstr[] = "v";
+
+static void usage(char *name)
+{
+ printf("usage: %s\n", name);
+ exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+ Display *disp;
+ XVisualInfo *pvi;
+ XSetWindowAttributes swa;
+ int attrib[14];
+ Window winGL;
+ GLXContext context;
+ int dummy;
+ Atom wmDelete;
+ int verbose = 0, width = 200, height = 200;
+ int c, i = 1;
+ int64_t ust, msc, sbc;
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, optstr)) != -1) {
+ switch (c) {
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ disp = XOpenDisplay(NULL);
+ if (!disp) {
+ fprintf(stderr, "failed to open display\n");
+ return -1;
+ }
+
+ if (!glXQueryExtension(disp, &dummy, &dummy)) {
+ fprintf(stderr, "glXQueryExtension failed\n");
+ return -1;
+ }
+
+ if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) {
+ fprintf(stderr, "GLX_OML_sync_control not supported, exiting\n");
+ return -1;
+ }
+
+ attrib[0] = GLX_RGBA;
+ attrib[1] = 1;
+ attrib[2] = GLX_RED_SIZE;
+ attrib[3] = 1;
+ attrib[4] = GLX_GREEN_SIZE;
+ attrib[5] = 1;
+ attrib[6] = GLX_BLUE_SIZE;
+ attrib[7] = 1;
+ attrib[8] = GLX_DOUBLEBUFFER;
+ attrib[9] = 1;
+ attrib[10] = None;
+
+ pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib);
+ if (!pvi) {
+ fprintf(stderr, "failed to choose visual, exiting\n");
+ return -1;
+ }
+
+ context = glXCreateContext(disp, pvi, None, GL_TRUE);
+ if (!context) {
+ fprintf(stderr, "failed to create glx context\n");
+ return -1;
+ }
+
+ pvi->screen = DefaultScreen(disp);
+
+ swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
+ pvi->visual, AllocNone);
+ swa.border_pixel = 0;
+ swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+ StructureNotifyMask;
+ winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
+ 0, 0,
+ width, height,
+ 0, pvi->depth, InputOutput, pvi->visual,
+ CWBorderPixel | CWColormap | CWEventMask, &swa);
+ if (!winGL) {
+ fprintf(stderr, "window creation failed\n");
+ return -1;
+ }
+ wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
+ XSetWMProtocols(disp, winGL, &wmDelete, 1);
+
+ XSetStandardProperties(disp, winGL, "msc test", "msc text",
+ None, NULL, 0, NULL);
+
+ XMapRaised(disp, winGL);
+
+ glXMakeCurrent(disp, winGL, context);
+
+ get_sync_values = glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML");
+ wait_sync = glXGetProcAddress((unsigned char *)"glXWaitForMscOML");
+
+ if (!get_sync_values || !wait_sync) {
+ fprintf(stderr, "failed to get sync values function\n");
+ return -1;
+ }
+
+ while (i++) {
+ get_sync_values(disp, winGL, &ust, &msc, &sbc);
+ fprintf(stderr, "ust: %llu, msc: %llu, sbc: %llu\n", ust, msc,
+ sbc);
+
+ /* Alternate colors to make tearing obvious */
+ if (i & 1)
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ else
+ glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glXSwapBuffers(disp, winGL);
+ wait_sync(disp, winGL, 0, 60, 0, &ust, &msc, &sbc);
+ fprintf(stderr,
+ "wait returned ust: %llu, msc: %llu, sbc: %llu\n",
+ ust, msc, sbc);
+ sleep(1);
+ }
+
+ XDestroyWindow(disp, winGL);
+ glXDestroyContext(disp, context);
+ XCloseDisplay(disp);
+
+ return 0;
+}
#ifdef GLX_DIRECT_RENDERING
#define NEED_REPLIES
+#include <stdio.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
SyncHandle();
}
-void DRI2SwapBuffers(Display *dpy, XID drawable)
+static void
+load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
+ CARD64 remainder)
+{
+ req->target_msc_hi = target >> 32;
+ req->target_msc_lo = target & 0xffffffff;
+ req->divisor_hi = divisor >> 32;
+ req->divisor_lo = divisor & 0xffffffff;
+ req->remainder_hi = remainder >> 32;
+ req->remainder_lo = remainder & 0xffffffff;
+}
+
+static CARD64
+vals_to_card64(CARD32 lo, CARD32 hi)
+{
+ return (CARD64)hi << 32 | lo;
+}
+
+void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder, CARD64 *count)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2SwapBuffersReq *req;
+ xDRI2SwapBuffersReply rep;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2SwapBuffers;
req->drawable = drawable;
+ load_swap_req(req, target_msc, divisor, remainder);
+
+ _XReply(dpy, (xReply *)&rep, 0, xFalse);
+
+ *count = vals_to_card64(rep.swap_lo, rep.swap_hi);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc,
+ CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetMSCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2GetMSC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetMSC;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = vals_to_card64(rep.ust_lo, rep.ust_hi);
+ *msc = vals_to_card64(rep.msc_lo, rep.msc_hi);
+ *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
+}
+
+static void
+load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor,
+ CARD64 remainder)
+{
+ req->target_msc_hi = target >> 32;
+ req->target_msc_lo = target & 0xffffffff;
+ req->divisor_hi = divisor >> 32;
+ req->divisor_lo = divisor & 0xffffffff;
+ req->remainder_hi = remainder >> 32;
+ req->remainder_lo = remainder & 0xffffffff;
+}
+
+Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2WaitMSCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2WaitMSC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2WaitMSC;
+ req->drawable = drawable;
+ load_msc_req(req, target_msc, divisor, remainder);
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo;
+ *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo;
+ *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
+}
+
+static void
+load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target)
+{
+ req->target_sbc_hi = target >> 32;
+ req->target_sbc_lo = target & 0xffffffff;
+}
+
+Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+ CARD64 *msc, CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2WaitSBCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2WaitSBC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2WaitSBC;
+ req->drawable = drawable;
+ load_sbc_req(req, target_sbc);
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo;
+ *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo;
+ *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo;
+
UnlockDisplay(dpy);
SyncHandle();
+
+ return True;
}
#endif /* GLX_DIRECT_RENDERING */
CARD32 dest, CARD32 src);
extern void
-DRI2SwapBuffers(Display *dpy, XID drawable);
+DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *count);
+
+extern Bool
+DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+ CARD64 *msc, CARD64 *sbc);
#endif
return &pdraw->base;
}
+static int
+dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
+ int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+ return DRI2GetMSC(psc->dpy, pdraw->drawable, ust, msc, sbc);
+}
+
+static int
+dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
+ int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+ return DRI2WaitMSC(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor,
+ remainder, ust, msc, sbc);
+}
+
+static int
+dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
+ int64_t *msc, int64_t *sbc)
+{
+ return DRI2WaitSBC(pdraw->psc->dpy, pdraw->drawable, target_sbc, ust, msc,
+ sbc);
+}
+
static void
-dri2CopySubBuffer(__GLXDRIdrawable * pdraw,
- int x, int y, int width, int height)
+dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
XRectangle xrect;
dri2WaitX(pdraw);
}
-static void
-dri2SwapBuffers(__GLXDRIdrawable * pdraw)
-{
- __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
-
- dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
-}
-
static void
dri2WaitX(__GLXDRIdrawable *pdraw)
{
}
-static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
+static int64_t
+dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
+ int64_t remainder)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
__GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
__GLXDRIdisplayPrivate *pdp =
(__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
- __GLXscreenConfigs *psc = pdraw->psc;
+ int64_t ret;
#ifdef __DRI2_FLUSH
if (pdraw->psc->f)
#endif
/* Old servers can't handle swapbuffers */
- if (!pdp->swapAvailable)
- return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+ if (!pdp->swapAvailable) {
+ dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+ return 0;
+ }
- DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable);
+ DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor,
+ remainder, &ret);
#if __DRI2_FLUSH_VERSION >= 2
if (pdraw->psc->f)
(*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
#endif
+
+ return ret;
}
static __DRIbuffer *
psc->ext_list_first_time = GL_TRUE;
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
- &driverName, &deviceName))
+ &driverName, &deviceName))
return NULL;
psc->driver = driOpenDriver(driverName);
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
- psc->core = (__DRIcoreExtension *) extensions[i];
+ psc->core = (__DRIcoreExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
- psc->dri2 = (__DRIdri2Extension *) extensions[i];
+ psc->dri2 = (__DRIdri2Extension *) extensions[i];
}
if (psc->core == NULL || psc->dri2 == NULL) {
*/
psc->__driScreen =
psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
- ? loader_extensions_old
- : loader_extensions),
- &driver_configs, psc);
+ ? loader_extensions_old
+ : loader_extensions),
+ &driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
return NULL;
}
- driBindExtensions(psc, 1);
+ driBindCommonExtensions(psc);
+ dri2BindExtensions(psc);
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
psp->swapBuffers = dri2SwapBuffers;
psp->waitGL = dri2WaitGL;
psp->waitX = dri2WaitX;
+ psp->getDrawableMSC = dri2DrawableGetMSC;
+ psp->waitForMSC = dri2WaitForMSC;
+ psp->waitForSBC = dri2WaitForSBC;
/* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
* available.*/
return psp;
- handle_error:
+handle_error:
Xfree(driverName);
Xfree(deviceName);
return head.next;
}
+/* Bind DRI1 specific extensions */
_X_HIDDEN void
-driBindExtensions(__GLXscreenConfigs * psc, int dri2)
+driBindExtensions(__GLXscreenConfigs *psc)
{
const __DRIextension **extensions;
int i;
extensions = psc->core->getExtensions(psc->__driScreen);
for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_COPY_SUB_BUFFER
- if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
- psc->driCopySubBuffer =
- (__DRIcopySubBufferExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
- }
-#endif
-
#ifdef __DRI_SWAP_CONTROL
/* No DRI2 support for swap_control at the moment, since SwapBuffers
* is done by the X server */
- if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
- psc->swapControl = (__DRIswapControlExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
- __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
- }
-#endif
-
-#ifdef __DRI_ALLOCATE
- if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
- psc->allocate = (__DRIallocateExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
- }
-#endif
-
-#ifdef __DRI_FRAME_TRACKING
- if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
- psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+ psc->swapControl = (__DRIswapControlExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
+ __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
}
#endif
* GLX_OML_sync_control if implemented. */
#endif
-#ifdef __DRI_READ_DRAWABLE
- if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
- __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
+ /* Ignore unknown extensions */
+ }
+}
+
+/* Bind DRI2 specific extensions */
+_X_HIDDEN void
+dri2BindExtensions(__GLXscreenConfigs *psc)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = psc->core->getExtensions(psc->__driScreen);
+
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_TEX_BUFFER
+ if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
}
#endif
-#ifdef __DRI_TEX_BUFFER
- if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) {
- psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
+#ifdef __DRI2_MEDIA_STREAM_COUNTER
+ if (strcmp(extensions[i]->name, __DRI2_MEDIA_STREAM_COUNTER) == 0) {
+ psc->msc = (__DRI2mediaStreamCounterExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
}
#endif
#ifdef __DRI2_FLUSH
- if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
- psc->f = (__DRI2flushExtension *) extensions[i];
- /* internal driver extension, no GL extension exposed */
+ if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
+ psc->f = (__DRI2flushExtension *) extensions[i];
+ /* internal driver extension, no GL extension exposed */
+ }
+#endif
+ }
+}
+
+/* Bind extensions common to DRI1 and DRI2 */
+_X_HIDDEN void
+driBindCommonExtensions(__GLXscreenConfigs *psc)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = psc->core->getExtensions(psc->__driScreen);
+
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
+ }
+#endif
+
+#ifdef __DRI_ALLOCATE
+ if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
+ psc->allocate = (__DRIallocateExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
+ }
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+ if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
+ psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
+ }
+#endif
+
+#ifdef __DRI_READ_DRAWABLE
+ if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+ __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
}
#endif
extern void *driOpenDriver(const char *driverName);
-extern void driBindExtensions(__GLXscreenConfigs * psc, int dri2);
+extern void driBindExtensions(__GLXscreenConfigs * psc);
+extern void dri2BindExtensions(__GLXscreenConfigs * psc);
+extern void driBindCommonExtensions(__GLXscreenConfigs * psc);
#endif /* _DRI_COMMON_H */
return pdraw;
}
-static void
-driSwapBuffers(__GLXDRIdrawable * pdraw)
+static int64_t
+driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
+ int64_t unused3)
{
(*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
+ return 0;
}
static void
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
- psc->core = (__DRIcoreExtension *) extensions[i];
+ psc->core = (__DRIcoreExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
- psc->legacy = (__DRIlegacyExtension *) extensions[i];
+ psc->legacy = (__DRIlegacyExtension *) extensions[i];
}
if (psc->core == NULL || psc->legacy == NULL) {
return NULL;
}
- driBindExtensions(psc, 0);
+ driBindExtensions(psc);
+ driBindCommonExtensions(psc);
+
if (psc->driCopySubBuffer)
psp->copySubBuffer = driCopySubBuffer;
goto handle_error;
}
- driBindExtensions(psc, 0);
+ driBindExtensions(psc);
+ driBindCommonExtensions(psc);
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
__GLXdisplayPrivate * priv);
};
-struct __GLXDRIscreenRec
-{
-
- void (*destroyScreen) (__GLXscreenConfigs * psc);
-
- __GLXDRIcontext *(*createContext) (__GLXscreenConfigs * psc,
- const __GLcontextModes * mode,
- GLXContext gc,
- GLXContext shareList, int renderType);
-
- __GLXDRIdrawable *(*createDrawable) (__GLXscreenConfigs * psc,
- XID drawable,
- GLXDrawable glxDrawable,
- const __GLcontextModes * modes);
-
- void (*swapBuffers) (__GLXDRIdrawable * pdraw);
- void (*copySubBuffer) (__GLXDRIdrawable * pdraw,
- int x, int y, int width, int height);
- void (*waitX) (__GLXDRIdrawable * pdraw);
- void (*waitGL) (__GLXDRIdrawable * pdraw);
+struct __GLXDRIscreenRec {
+
+ void (*destroyScreen)(__GLXscreenConfigs *psc);
+
+ __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
+ const __GLcontextModes *mode,
+ GLXContext gc,
+ GLXContext shareList, int renderType);
+
+ __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
+ XID drawable,
+ GLXDrawable glxDrawable,
+ const __GLcontextModes *modes);
+
+ int64_t (*swapBuffers)(__GLXDRIdrawable *pdraw, int64_t target_msc,
+ int64_t divisor, int64_t remainder);
+ void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
+ int x, int y, int width, int height);
+ void (*waitX)(__GLXDRIdrawable *pdraw);
+ void (*waitGL)(__GLXDRIdrawable *pdraw);
+ int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
+ int64_t *ust, int64_t *msc, int64_t *sbc);
+ int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc,
+ int64_t divisor, int64_t remainder, int64_t *ust,
+ int64_t *msc, int64_t *sbc);
+ int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
+ int64_t *msc, int64_t *sbc);
};
struct __GLXDRIcontextRec
if (pdraw != NULL) {
glFlush();
- (*pdraw->psc->driScreen->swapBuffers) (pdraw);
+ (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0);
return;
}
#endif
#ifdef __DRI_SWAP_CONTROL
if (gc->driContext) {
- __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
- gc->screen);
+ __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
+ gc->screen );
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
- gc->currentDrawable,
- NULL);
+ gc->currentDrawable,
+ NULL);
if (psc->swapControl != NULL && pdraw != NULL) {
- psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
- return 0;
+ psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
+ return 0;
}
- else {
- return GLX_BAD_CONTEXT;
+ else if (pdraw == NULL) {
+ return GLX_BAD_CONTEXT;
}
}
#endif
static int
__glXGetVideoSyncSGI(unsigned int *count)
{
+ int64_t ust, msc, sbc;
+ int ret;
+ GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc;
+ __GLXDRIdrawable *pdraw;
+
+ if (!gc || !gc->driContext)
+ return GLX_BAD_CONTEXT;
+
+ psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
+ pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+
/* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
* FIXME: there should be a GLX encoding for this call. I can find no
* FIXME: documentation for the GLX encoding.
*/
#ifdef __DRI_MEDIA_STREAM_COUNTER
- GLXContext gc = __glXGetCurrentContext();
+ if ( psc->msc && psc->driScreen ) {
+ ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
+ pdraw->driDrawable, &msc);
+ *count = (unsigned) msc;
-
- if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
- gc->screen);
- if (psc->msc && psc->driScreen) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- int64_t temp;
- int ret;
-
- ret = (*psc->msc->getDrawableMSC) (psc->__driScreen,
- pdraw->driDrawable, &temp);
- *count = (unsigned) temp;
-
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
- }
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
-#else
- (void) count;
#endif
+ if (psc->driScreen && psc->driScreen->getDrawableMSC) {
+ ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
+ *count = (unsigned) msc;
+ return (ret == True) ? 0 : GLX_BAD_CONTEXT;
+ }
+
return GLX_BAD_CONTEXT;
}
static int
__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
-#ifdef __DRI_MEDIA_STREAM_COUNTER
GLXContext gc = __glXGetCurrentContext();
+ __GLXscreenConfigs *psc;
+ __GLXDRIdrawable *pdraw;
+ int64_t ust, msc, sbc;
+ int ret;
if (divisor <= 0 || remainder < 0)
return GLX_BAD_VALUE;
- if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
- gc->screen);
- if (psc->msc != NULL && psc->driScreen) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- int ret;
- int64_t msc;
- int64_t sbc;
-
- ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, 0,
- divisor, remainder, &msc, &sbc);
- *count = (unsigned) msc;
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
- }
+ if (!gc || !gc->driContext)
+ return GLX_BAD_CONTEXT;
+
+ psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+ pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+ if (psc->msc != NULL && psc->driScreen ) {
+ ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
+ divisor, remainder, &msc, &sbc);
+ *count = (unsigned) msc;
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
-#else
- (void) count;
#endif
+ if (psc->driScreen && psc->driScreen->waitForMSC) {
+ ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
+ &sbc);
+ *count = (unsigned) msc;
+ return (ret == True) ? 0 : GLX_BAD_CONTEXT;
+ }
+
return GLX_BAD_CONTEXT;
}
__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
int64_t * ust, int64_t * msc, int64_t * sbc)
{
-#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
- __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
+ __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+ int i, ret;
+ __GLXDRIdrawable *pdraw;
+ __GLXscreenConfigs *psc;
- if (priv != NULL) {
- int i;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
- __GLXscreenConfigs *const psc = &priv->screenConfigs[i];
+ if (!priv)
+ return False;
- assert((pdraw == NULL) || (i != -1));
- return ((pdraw && psc->sbc && psc->msc)
- && ((*psc->msc->getMSC) (psc->driScreen, msc) == 0)
- && ((*psc->sbc->getSBC) (pdraw->driDrawable, sbc) == 0)
- && (__glXGetUST(ust) == 0));
- }
-#else
- (void) dpy;
- (void) drawable;
- (void) ust;
- (void) msc;
- (void) sbc;
+ pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
+ psc = &priv->screenConfigs[i];
+
+#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
+ if (pdraw && psc->sbc && psc->sbc)
+ return ( (pdraw && psc->sbc && psc->msc)
+ && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
+ && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
+ && (__glXGetUST(ust) == 0) );
#endif
+ if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
+ ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
+ return ret;
+ }
+
return False;
}
__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
int64_t target_msc, int64_t divisor, int64_t remainder)
{
-#ifdef __DRI_SWAP_BUFFER_COUNTER
+ GLXContext gc = __glXGetCurrentContext();
int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ if (!pdraw || !gc->driContext) /* no GLX for this */
+ return -1;
+
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
* error", but it also says "It [glXSwapBuffersMscOML] will return a value
* of -1 if the function failed because of errors detected in the input
if (divisor > 0 && remainder >= divisor)
return -1;
- if (pdraw != NULL && psc->counters != NULL)
- return (*psc->sbc->swapBuffersMSC) (pdraw->driDrawable, target_msc,
- divisor, remainder);
+#ifdef __DRI_SWAP_BUFFER_COUNTER
+ if (psc->counters != NULL)
+ return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
+ divisor, remainder);
+#endif
-#else
- (void) dpy;
- (void) drawable;
- (void) target_msc;
- (void) divisor;
- (void) remainder;
+#ifdef GLX_DIRECT_RENDERING
+ if (psc->driScreen && psc->driScreen->swapBuffers)
+ return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
+ remainder);
#endif
- return 0;
+
+ return -1;
}
int64_t remainder, int64_t * ust,
int64_t * msc, int64_t * sbc)
{
-#ifdef __DRI_MEDIA_STREAM_COUNTER
- int screen = 0;
+ int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
int ret;
+ fprintf(stderr, "waitmsc: %lld, %lld, %lld\n", target_msc, divisor,
+ remainder);
+
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
* error", but the return type in the spec is Bool.
*/
if (divisor > 0 && remainder >= divisor)
return False;
+#ifdef __DRI_MEDIA_STREAM_COUNTER
if (pdraw != NULL && psc->msc != NULL) {
+ fprintf(stderr, "dri1 msc\n");
ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc,
divisor, remainder, msc, sbc);
*/
return ((ret == 0) && (__glXGetUST(ust) == 0));
}
-#else
- (void) dpy;
- (void) drawable;
- (void) target_msc;
- (void) divisor;
- (void) remainder;
- (void) ust;
- (void) msc;
- (void) sbc;
#endif
+ if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
+ ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
+ ust, msc, sbc);
+ return ret;
+ }
+
+ fprintf(stderr, "no drawable??\n");
return False;
}
int64_t target_sbc, int64_t * ust,
int64_t * msc, int64_t * sbc)
{
-#ifdef __DRI_SWAP_BUFFER_COUNTER
int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
*/
if (target_sbc < 0)
return False;
-
+#ifdef __DRI_SWAP_BUFFER_COUNTER
if (pdraw != NULL && psc->sbc != NULL) {
ret =
(*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc);
*/
return ((ret == 0) && (__glXGetUST(ust) == 0));
}
-#else
- (void) dpy;
- (void) drawable;
- (void) target_sbc;
- (void) ust;
- (void) msc;
- (void) sbc;
#endif
+ if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
+ ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
+ return ret;
+ }
return False;
}