summaryrefslogtreecommitdiff
path: root/GL
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2006-07-06 21:22:34 -0400
committerKristian Høgsberg <krh@redhat.com>2006-07-06 21:25:29 -0400
commit5416f90e9c939027005fc01fa3ce3df56919ae0d (patch)
treedabed6a7c920e6784530da99220833841ebbf38d /GL
parentb84374b2917a91a7732e780ffab6a29c807a3ecc (diff)
Implement GLX_MESA_copy_sub_buffer.
Diffstat (limited to 'GL')
-rw-r--r--GL/glx/glxcmds.c40
-rw-r--r--GL/glx/glxdrawable.h2
-rw-r--r--GL/glx/glxdri.c48
3 files changed, 84 insertions, 6 deletions
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 3ec796c0f..e2aaf3a71 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1605,8 +1605,13 @@ int __glXReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ GLXContextTag tag = req->contextTag;
+ __GLXcontext *glxc = NULL;
+ __GLXdrawable *pGlxDraw;
+ __GLXpixmap *pPixmap;
ClientPtr client = cl->client;
GLXDrawable drawId;
+ int error;
int x, y, width, height;
(void) client;
@@ -1620,7 +1625,40 @@ int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
width = *((INT32 *) (pc + 12));
height = *((INT32 *) (pc + 16));
- return BadRequest;
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXError(GLXBadContextTag);
+ }
+ /*
+ ** The calling thread is swapping its current drawable. In this case,
+ ** glxSwapBuffers is in both GL and X streams, in terms of
+ ** sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the swap is executed.
+ */
+ CALL_Finish( GET_DISPATCH(), () );
+ __GLX_NOTE_FLUSHED_CMDS(glxc);
+ } else {
+ return error;
+ }
+ }
+
+ error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
+ if (error != Success)
+ return error;
+
+ if (pGlxDraw == NULL ||
+ pGlxDraw->type != DRAWABLE_WINDOW ||
+ pGlxDraw->copySubBuffer == NULL)
+ return __glXError(GLXBadDrawable);
+
+ (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height);
+
+ return Success;
}
/*
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 4514e263e..e6d2cd686 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -58,6 +58,8 @@ struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private);
GLboolean (*resize)(__GLXdrawable *private);
GLboolean (*swapBuffers)(__GLXdrawable *);
+ void (*copySubBuffer)(__GLXdrawable *drawable,
+ int x, int y, int w, int h);
/*
** list of drawable private structs
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 423922966..6a1055439 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -112,12 +112,28 @@ struct __GLXDRIdrawable {
* months ago. :(
* 20050727 - Gut all the old interfaces. This breaks compatability with
* any DRI driver built to any previous version.
+ * 20060314 - Added support for GLX_MESA_copy_sub_buffer.
*/
+
#define INTERNAL_VERSION 20050727
static const char CREATE_NEW_SCREEN_FUNC[] =
"__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
__glXDRIleaveServer(void)
{
@@ -178,6 +194,27 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
}
static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
+ int x, int y, int w, int h)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+ __GLXDRIscreen *screen;
+
+ /* FIXME: We're jumping through hoops here to get the DRIdrawable
+ * which the dri driver tries to keep to it self... cf. FIXME in
+ * createDrawable. */
+
+ screen = (__GLXDRIscreen *) __glXgetActiveScreen(private->base.pDraw->pScreen->myNum);
+ private->driDrawable = (screen->driScreen.getDrawable)(NULL,
+ private->base.drawId,
+ screen->driScreen.private);
+
+ (*private->driDrawable->copySubBuffer)(NULL,
+ private->driDrawable->private,
+ x, y, w, h);
+}
+
+static void
__glXDRIcontextDestroy(__GLXcontext *baseContext)
{
__GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
@@ -474,10 +511,11 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
return NULL;
}
- private->base.destroy = __glXDRIdrawableDestroy;
- private->base.resize = __glXDRIdrawableResize;
- private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
-
+ private->base.destroy = __glXDRIdrawableDestroy;
+ private->base.resize = __glXDRIdrawableResize;
+ private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
+ private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+
#if 0
/* FIXME: It would only be natural that we called
* driScreen->createNewDrawable here but the DRI drivers manage
@@ -770,7 +808,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
__DRIframebuffer framebuffer;
int fd = -1;
int status;
- int api_ver = INTERNAL_VERSION;
+ int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION;
drm_magic_t magic;
drmVersionPtr version;
char *driverName;