diff options
Diffstat (limited to 'xorg-server/glx')
-rw-r--r-- | xorg-server/glx/glxdri.c | 15 | ||||
-rw-r--r-- | xorg-server/glx/glxdri2.c | 14 | ||||
-rw-r--r-- | xorg-server/glx/glxdriswrast.c | 996 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.c | 10 | ||||
-rw-r--r-- | xorg-server/glx/single2.c | 770 |
5 files changed, 919 insertions, 886 deletions
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c index 244eac6c2..326f53915 100644 --- a/xorg-server/glx/glxdri.c +++ b/xorg-server/glx/glxdri.c @@ -78,6 +78,7 @@ struct __GLXDRIscreen { const __DRIlegacyExtension *legacy; const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; + const __DRIconfig **driConfigs; #ifdef __DRI_TEX_OFFSET const __DRItexOffsetExtension *texOffset; @@ -585,6 +586,8 @@ static __GLXtextureFromPixmap __glXDRItextureFromPixmap = { static void __glXDRIscreenDestroy(__GLXscreen *baseScreen) { + int i; + __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; screen->core->destroyScreen(screen->driScreen); @@ -593,6 +596,12 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) __glXScreenDestroy(baseScreen); + if (screen->driConfigs) { + for (i = 0; screen->driConfigs[i] != NULL; i++) + free((__DRIconfig **)screen->driConfigs[i]); + free(screen->driConfigs); + } + free(screen); } @@ -967,7 +976,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) Bool isCapable; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - const __DRIconfig **driConfigs; if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || @@ -1095,7 +1103,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) pSAREA, fd, loader_extensions, - &driConfigs, + &screen->driConfigs, screen); if (screen->driScreen == NULL) { @@ -1105,7 +1113,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen) } screen->base.fbconfigs = glxConvertConfigs(screen->core, - driConfigs, GLX_WINDOW_BIT); + screen->driConfigs, + GLX_WINDOW_BIT); initializeExtensions(screen); diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c index e8722585b..8187a3edd 100644 --- a/xorg-server/glx/glxdri2.c +++ b/xorg-server/glx/glxdri2.c @@ -73,6 +73,7 @@ struct __GLXDRIscreen { const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; const __DRItexBufferExtension *texBuffer; + const __DRIconfig **driConfigs; unsigned char glx_enable_bits[__GLX_EXT_BYTES]; }; @@ -363,6 +364,8 @@ static __GLXtextureFromPixmap __glXDRItextureFromPixmap = { static void __glXDRIscreenDestroy(__GLXscreen *baseScreen) { + int i; + __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; (*screen->core->destroyScreen)(screen->driScreen); @@ -371,6 +374,12 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) __glXScreenDestroy(baseScreen); + if (screen->driConfigs) { + for (i = 0; screen->driConfigs[i] != NULL; i++) + free((__DRIconfig **)screen->driConfigs[i]); + free(screen->driConfigs); + } + free(screen); } @@ -688,7 +697,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __GLXDRIscreen *screen; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - const __DRIconfig **driConfigs; screen = calloc(1, sizeof *screen); if (screen == NULL) @@ -720,7 +728,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) (*screen->dri2->createNewScreen)(pScreen->myNum, screen->fd, loader_extensions, - &driConfigs, + &screen->driConfigs, screen); if (screen->driScreen == NULL) { @@ -731,7 +739,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) initializeExtensions(screen); - screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs, + screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs, GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT); diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c index 9b65f3662..d064a0536 100644 --- a/xorg-server/glx/glxdriswrast.c +++ b/xorg-server/glx/glxdriswrast.c @@ -1,494 +1,502 @@ -/*
- * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
- * Copyright © 2008 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * copyright holders not be used in advertising or publicity
- * pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <dlfcn.h>
-
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include <GL/glxtokens.h>
-
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "os.h"
-
-#include "glxserver.h"
-#include "glxutil.h"
-#include "glxdricommon.h"
-
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "extension_string.h"
-
-/* RTLD_LOCAL is not defined on Cygwin */
-#ifdef __CYGWIN__
-#ifndef RTLD_LOCAL
-#define RTLD_LOCAL 0
-#endif
-#endif
-
-typedef struct __GLXDRIscreen __GLXDRIscreen;
-typedef struct __GLXDRIcontext __GLXDRIcontext;
-typedef struct __GLXDRIdrawable __GLXDRIdrawable;
-
-struct __GLXDRIscreen {
- __GLXscreen base;
- __DRIscreen *driScreen;
- void *driver;
-
- const __DRIcoreExtension *core;
- const __DRIswrastExtension *swrast;
- const __DRIcopySubBufferExtension *copySubBuffer;
- const __DRItexBufferExtension *texBuffer;
-};
-
-struct __GLXDRIcontext {
- __GLXcontext base;
- __DRIcontext *driContext;
-};
-
-struct __GLXDRIdrawable {
- __GLXdrawable base;
- __DRIdrawable *driDrawable;
- __GLXDRIscreen *screen;
-
- GCPtr gc; /* scratch GC for span drawing */
- GCPtr swapgc; /* GC for swapping the color buffers */
-};
-
-static void
-__glXDRIdrawableDestroy(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- const __DRIcoreExtension *core = private->screen->core;
-
- (*core->destroyDrawable)(private->driDrawable);
-
- FreeGC(private->gc, (GContext)0);
- FreeGC(private->swapgc, (GContext)0);
-
- __glXDrawableRelease(drawable);
-
- free(private);
-}
-
-static GLboolean
-__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- const __DRIcoreExtension *core = private->screen->core;
-
- (*core->swapBuffers)(private->driDrawable);
-
- return TRUE;
-}
-
-static void
-__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
- int x, int y, int w, int h)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
- const __DRIcopySubBufferExtension *copySubBuffer =
- private->screen->copySubBuffer;
-
- if (copySubBuffer)
- (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h);
-}
-
-static void
-__glXDRIcontextDestroy(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- (*screen->core->destroyContext)(context->driContext);
- __glXContextDestroy(&context->base);
- free(context);
-}
-
-static int
-__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
- __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- return (*screen->core->bindContext)(context->driContext,
- draw->driDrawable,
- read->driDrawable);
-}
-
-static int
-__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- return (*screen->core->unbindContext)(context->driContext);
-}
-
-static int
-__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
- unsigned long mask)
-{
- __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
- __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
-
- return (*screen->core->copyContext)(dst->driContext,
- src->driContext, mask);
-}
-
-#ifdef __DRI_TEX_BUFFER
-
-static int
-__glXDRIbindTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *glxPixmap)
-{
- __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
- const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-
- if (texBuffer == NULL)
- return Success;
-
-#if __DRI_TEX_BUFFER_VERSION >= 2
- if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
- (*texBuffer->setTexBuffer2)(context->driContext,
- glxPixmap->target,
- glxPixmap->format,
- drawable->driDrawable);
- } else
-#endif
- texBuffer->setTexBuffer(context->driContext,
- glxPixmap->target,
- drawable->driDrawable);
-
- return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- /* FIXME: Just unbind the texture? */
- return Success;
-}
-
-#else
-
-static int
-__glXDRIbindTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *glxPixmap)
-{
- return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- return Success;
-}
-
-#endif
-
-static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
- __glXDRIbindTexImage,
- __glXDRIreleaseTexImage
-};
-
-static void
-__glXDRIscreenDestroy(__GLXscreen *baseScreen)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
-
- (*screen->core->destroyScreen)(screen->driScreen);
-
- dlclose(screen->driver);
-
- __glXScreenDestroy(baseScreen);
-
- free(screen);
-}
-
-static __GLXcontext *
-__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
- __GLXconfig *glxConfig,
- __GLXcontext *baseShareContext)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
- __GLXDRIcontext *context, *shareContext;
- __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
- const __DRIcoreExtension *core = screen->core;
- __DRIcontext *driShare;
-
- shareContext = (__GLXDRIcontext *) baseShareContext;
- if (shareContext)
- driShare = shareContext->driContext;
- else
- driShare = NULL;
-
- context = calloc(1, sizeof *context);
- if (context == NULL)
- return NULL;
-
- context->base.destroy = __glXDRIcontextDestroy;
- context->base.makeCurrent = __glXDRIcontextMakeCurrent;
- context->base.loseCurrent = __glXDRIcontextLoseCurrent;
- context->base.copy = __glXDRIcontextCopy;
- context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
-
- context->driContext =
- (*core->createNewContext)(screen->driScreen,
- config->driConfig, driShare, context);
-
- return &context->base;
-}
-
-static __GLXdrawable *
-__glXDRIscreenCreateDrawable(ClientPtr client,
- __GLXscreen *screen,
- DrawablePtr pDraw,
- XID drawId,
- int type,
- XID glxDrawId,
- __GLXconfig *glxConfig)
-{
- XID gcvals[2];
- int status;
- __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
- __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
- __GLXDRIdrawable *private;
-
- private = calloc(1, sizeof *private);
- if (private == NULL)
- return NULL;
-
- private->screen = driScreen;
- if (!__glXDrawableInit(&private->base, screen,
- pDraw, type, glxDrawId, glxConfig)) {
- free(private);
- return NULL;
- }
-
- private->base.destroy = __glXDRIdrawableDestroy;
- private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
- private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
-
- gcvals[0] = GXcopy;
- private->gc = CreateGC(pDraw, GCFunction, gcvals, &status, (XID)0, serverClient);
- gcvals[1] = FALSE;
- private->swapgc = CreateGC(pDraw, GCFunction | GCGraphicsExposures, gcvals, &status, (XID)0, serverClient);
-
- private->driDrawable =
- (*driScreen->swrast->createNewDrawable)(driScreen->driScreen,
- config->driConfig,
- private);
-
- return &private->base;
-}
-
-static void
-swrastGetDrawableInfo(__DRIdrawable *draw,
- int *x, int *y, int *w, int *h,
- void *loaderPrivate)
-{
- __GLXDRIdrawable *drawable = loaderPrivate;
- DrawablePtr pDraw = drawable->base.pDraw;
-
- *x = pDraw->x;
- *y = pDraw->x;
- *w = pDraw->width;
- *h = pDraw->height;
-}
-
-static void
-swrastPutImage(__DRIdrawable *draw, int op,
- int x, int y, int w, int h, char *data,
- void *loaderPrivate)
-{
- __GLXDRIdrawable *drawable = loaderPrivate;
- DrawablePtr pDraw = drawable->base.pDraw;
- GCPtr gc;
-
- switch (op) {
- case __DRI_SWRAST_IMAGE_OP_DRAW:
- gc = drawable->gc;
- break;
- case __DRI_SWRAST_IMAGE_OP_SWAP:
- gc = drawable->swapgc;
- break;
- default:
- return;
- }
-
- ValidateGC(pDraw, gc);
-
- gc->ops->PutImage(pDraw, gc, pDraw->depth,
- x, y, w, h, 0, ZPixmap, data);
-}
-
-static void
-swrastGetImage(__DRIdrawable *draw,
- int x, int y, int w, int h, char *data,
- void *loaderPrivate)
-{
- __GLXDRIdrawable *drawable = loaderPrivate;
- DrawablePtr pDraw = drawable->base.pDraw;
- ScreenPtr pScreen = pDraw->pScreen;
-
- pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
-}
-
-static const __DRIswrastLoaderExtension swrastLoaderExtension = {
- { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
- swrastGetDrawableInfo,
- swrastPutImage,
- swrastGetImage
-};
-
-static const __DRIextension *loader_extensions[] = {
- &systemTimeExtension.base,
- &swrastLoaderExtension.base,
- NULL
-};
-
-static void
-initializeExtensions(__GLXDRIscreen *screen)
-{
- const __DRIextension **extensions;
- int i;
-
- extensions = screen->core->getExtensions(screen->driScreen);
-
- for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_COPY_SUB_BUFFER
- if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
- screen->copySubBuffer =
- (const __DRIcopySubBufferExtension *) extensions[i];
- /* GLX_MESA_copy_sub_buffer is always enabled. */
- }
-#endif
-
-#ifdef __DRI_TEX_BUFFER
- if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
- screen->texBuffer =
- (const __DRItexBufferExtension *) extensions[i];
- /* GLX_EXT_texture_from_pixmap is always enabled. */
- }
-#endif
- /* Ignore unknown extensions */
- }
-}
-
-static __GLXscreen *
-__glXDRIscreenProbe(ScreenPtr pScreen)
-{
- const char *driverName = "swrast";
- __GLXDRIscreen *screen;
- const __DRIconfig **driConfigs;
-
- screen = calloc(1, sizeof *screen);
- if (screen == NULL)
- return NULL;
-
- screen->base.destroy = __glXDRIscreenDestroy;
- screen->base.createContext = __glXDRIscreenCreateContext;
- screen->base.createDrawable = __glXDRIscreenCreateDrawable;
- screen->base.swapInterval = NULL;
- screen->base.pScreen = pScreen;
-
- screen->driver = glxProbeDriver(driverName,
- (void **)&screen->core,
- __DRI_CORE, __DRI_CORE_VERSION,
- (void **)&screen->swrast,
- __DRI_SWRAST, __DRI_SWRAST_VERSION);
- if (screen->driver == NULL) {
- goto handle_error;
- }
-
- screen->driScreen =
- (*screen->swrast->createNewScreen)(pScreen->myNum,
- loader_extensions,
- &driConfigs,
- screen);
-
- if (screen->driScreen == NULL) {
- LogMessage(X_ERROR,
- "AIGLX error: Calling driver entry point failed\n");
- goto handle_error;
- }
-
- initializeExtensions(screen);
-
- screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs,
- GLX_WINDOW_BIT |
- GLX_PIXMAP_BIT |
- GLX_PBUFFER_BIT);
-
- __glXScreenInit(&screen->base, pScreen);
-
- screen->base.GLXmajor = 1;
- screen->base.GLXminor = 4;
-
- LogMessage(X_INFO,
- "AIGLX: Loaded and initialized %s\n", driverName);
-
- return &screen->base;
-
- handle_error:
- if (screen->driver)
- dlclose(screen->driver);
-
- free(screen);
-
- LogMessage(X_ERROR, "GLX: could not load software renderer\n");
-
- return NULL;
-}
-
-_X_EXPORT __GLXprovider __glXDRISWRastProvider = {
- __glXDRIscreenProbe,
- "DRISWRAST",
- NULL
-};
+/* + * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr> + * Copyright © 2008 Red Hat, Inc + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> +#include <dlfcn.h> + +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> +#include <GL/glxtokens.h> + +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "gcstruct.h" +#include "os.h" + +#include "glxserver.h" +#include "glxutil.h" +#include "glxdricommon.h" + +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" +#include "extension_string.h" + +/* RTLD_LOCAL is not defined on Cygwin */ +#ifdef __CYGWIN__ +#ifndef RTLD_LOCAL +#define RTLD_LOCAL 0 +#endif +#endif + +typedef struct __GLXDRIscreen __GLXDRIscreen; +typedef struct __GLXDRIcontext __GLXDRIcontext; +typedef struct __GLXDRIdrawable __GLXDRIdrawable; + +struct __GLXDRIscreen { + __GLXscreen base; + __DRIscreen *driScreen; + void *driver; + + const __DRIcoreExtension *core; + const __DRIswrastExtension *swrast; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRItexBufferExtension *texBuffer; + const __DRIconfig **driConfigs; +}; + +struct __GLXDRIcontext { + __GLXcontext base; + __DRIcontext *driContext; +}; + +struct __GLXDRIdrawable { + __GLXdrawable base; + __DRIdrawable *driDrawable; + __GLXDRIscreen *screen; + + GCPtr gc; /* scratch GC for span drawing */ + GCPtr swapgc; /* GC for swapping the color buffers */ +}; + +static void +__glXDRIdrawableDestroy(__GLXdrawable *drawable) +{ + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIcoreExtension *core = private->screen->core; + + (*core->destroyDrawable)(private->driDrawable); + + FreeGC(private->gc, (GContext)0); + FreeGC(private->swapgc, (GContext)0); + + __glXDrawableRelease(drawable); + + free(private); +} + +static GLboolean +__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) +{ + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIcoreExtension *core = private->screen->core; + + (*core->swapBuffers)(private->driDrawable); + + return TRUE; +} + +static void +__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, + int x, int y, int w, int h) +{ + __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + const __DRIcopySubBufferExtension *copySubBuffer = + private->screen->copySubBuffer; + + if (copySubBuffer) + (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); +} + +static void +__glXDRIcontextDestroy(__GLXcontext *baseContext) +{ + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; + + (*screen->core->destroyContext)(context->driContext); + __glXContextDestroy(&context->base); + free(context); +} + +static int +__glXDRIcontextMakeCurrent(__GLXcontext *baseContext) +{ + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; + __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; + + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); +} + +static int +__glXDRIcontextLoseCurrent(__GLXcontext *baseContext) +{ + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; + + return (*screen->core->unbindContext)(context->driContext); +} + +static int +__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, + unsigned long mask) +{ + __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; + __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; + __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; + + return (*screen->core->copyContext)(dst->driContext, + src->driContext, mask); +} + +#ifdef __DRI_TEX_BUFFER + +static int +__glXDRIbindTexImage(__GLXcontext *baseContext, + int buffer, + __GLXdrawable *glxPixmap) +{ + __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; + const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + + if (texBuffer == NULL) + return Success; + +#if __DRI_TEX_BUFFER_VERSION >= 2 + if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { + (*texBuffer->setTexBuffer2)(context->driContext, + glxPixmap->target, + glxPixmap->format, + drawable->driDrawable); + } else +#endif + texBuffer->setTexBuffer(context->driContext, + glxPixmap->target, + drawable->driDrawable); + + return Success; +} + +static int +__glXDRIreleaseTexImage(__GLXcontext *baseContext, + int buffer, + __GLXdrawable *pixmap) +{ + /* FIXME: Just unbind the texture? */ + return Success; +} + +#else + +static int +__glXDRIbindTexImage(__GLXcontext *baseContext, + int buffer, + __GLXdrawable *glxPixmap) +{ + return Success; +} + +static int +__glXDRIreleaseTexImage(__GLXcontext *baseContext, + int buffer, + __GLXdrawable *pixmap) +{ + return Success; +} + +#endif + +static __GLXtextureFromPixmap __glXDRItextureFromPixmap = { + __glXDRIbindTexImage, + __glXDRIreleaseTexImage +}; + +static void +__glXDRIscreenDestroy(__GLXscreen *baseScreen) +{ + int i; + + __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; + + (*screen->core->destroyScreen)(screen->driScreen); + + dlclose(screen->driver); + + __glXScreenDestroy(baseScreen); + + if (screen->driConfigs) { + for (i = 0; screen->driConfigs[i] != NULL; i++) + free((__DRIconfig **)screen->driConfigs[i]); + free(screen->driConfigs); + } + + free(screen); +} + +static __GLXcontext * +__glXDRIscreenCreateContext(__GLXscreen *baseScreen, + __GLXconfig *glxConfig, + __GLXcontext *baseShareContext) +{ + __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; + __GLXDRIcontext *context, *shareContext; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; + const __DRIcoreExtension *core = screen->core; + __DRIcontext *driShare; + + shareContext = (__GLXDRIcontext *) baseShareContext; + if (shareContext) + driShare = shareContext->driContext; + else + driShare = NULL; + + context = calloc(1, sizeof *context); + if (context == NULL) + return NULL; + + context->base.destroy = __glXDRIcontextDestroy; + context->base.makeCurrent = __glXDRIcontextMakeCurrent; + context->base.loseCurrent = __glXDRIcontextLoseCurrent; + context->base.copy = __glXDRIcontextCopy; + context->base.textureFromPixmap = &__glXDRItextureFromPixmap; + + context->driContext = + (*core->createNewContext)(screen->driScreen, + config->driConfig, driShare, context); + + return &context->base; +} + +static __GLXdrawable * +__glXDRIscreenCreateDrawable(ClientPtr client, + __GLXscreen *screen, + DrawablePtr pDraw, + XID drawId, + int type, + XID glxDrawId, + __GLXconfig *glxConfig) +{ + XID gcvals[2]; + int status; + __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; + __GLXDRIdrawable *private; + + private = calloc(1, sizeof *private); + if (private == NULL) + return NULL; + + private->screen = driScreen; + if (!__glXDrawableInit(&private->base, screen, + pDraw, type, glxDrawId, glxConfig)) { + free(private); + return NULL; + } + + private->base.destroy = __glXDRIdrawableDestroy; + private->base.swapBuffers = __glXDRIdrawableSwapBuffers; + private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; + + gcvals[0] = GXcopy; + private->gc = CreateGC(pDraw, GCFunction, gcvals, &status, (XID)0, serverClient); + gcvals[1] = FALSE; + private->swapgc = CreateGC(pDraw, GCFunction | GCGraphicsExposures, gcvals, &status, (XID)0, serverClient); + + private->driDrawable = + (*driScreen->swrast->createNewDrawable)(driScreen->driScreen, + config->driConfig, + private); + + return &private->base; +} + +static void +swrastGetDrawableInfo(__DRIdrawable *draw, + int *x, int *y, int *w, int *h, + void *loaderPrivate) +{ + __GLXDRIdrawable *drawable = loaderPrivate; + DrawablePtr pDraw = drawable->base.pDraw; + + *x = pDraw->x; + *y = pDraw->x; + *w = pDraw->width; + *h = pDraw->height; +} + +static void +swrastPutImage(__DRIdrawable *draw, int op, + int x, int y, int w, int h, char *data, + void *loaderPrivate) +{ + __GLXDRIdrawable *drawable = loaderPrivate; + DrawablePtr pDraw = drawable->base.pDraw; + GCPtr gc; + + switch (op) { + case __DRI_SWRAST_IMAGE_OP_DRAW: + gc = drawable->gc; + break; + case __DRI_SWRAST_IMAGE_OP_SWAP: + gc = drawable->swapgc; + break; + default: + return; + } + + ValidateGC(pDraw, gc); + + gc->ops->PutImage(pDraw, gc, pDraw->depth, + x, y, w, h, 0, ZPixmap, data); +} + +static void +swrastGetImage(__DRIdrawable *draw, + int x, int y, int w, int h, char *data, + void *loaderPrivate) +{ + __GLXDRIdrawable *drawable = loaderPrivate; + DrawablePtr pDraw = drawable->base.pDraw; + ScreenPtr pScreen = pDraw->pScreen; + + pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data); +} + +static const __DRIswrastLoaderExtension swrastLoaderExtension = { + { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION }, + swrastGetDrawableInfo, + swrastPutImage, + swrastGetImage +}; + +static const __DRIextension *loader_extensions[] = { + &systemTimeExtension.base, + &swrastLoaderExtension.base, + NULL +}; + +static void +initializeExtensions(__GLXDRIscreen *screen) +{ + const __DRIextension **extensions; + int i; + + extensions = screen->core->getExtensions(screen->driScreen); + + for (i = 0; extensions[i]; i++) { +#ifdef __DRI_COPY_SUB_BUFFER + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { + screen->copySubBuffer = + (const __DRIcopySubBufferExtension *) extensions[i]; + /* GLX_MESA_copy_sub_buffer is always enabled. */ + } +#endif + +#ifdef __DRI_TEX_BUFFER + if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { + screen->texBuffer = + (const __DRItexBufferExtension *) extensions[i]; + /* GLX_EXT_texture_from_pixmap is always enabled. */ + } +#endif + /* Ignore unknown extensions */ + } +} + +static __GLXscreen * +__glXDRIscreenProbe(ScreenPtr pScreen) +{ + const char *driverName = "swrast"; + __GLXDRIscreen *screen; + + screen = calloc(1, sizeof *screen); + if (screen == NULL) + return NULL; + + screen->base.destroy = __glXDRIscreenDestroy; + screen->base.createContext = __glXDRIscreenCreateContext; + screen->base.createDrawable = __glXDRIscreenCreateDrawable; + screen->base.swapInterval = NULL; + screen->base.pScreen = pScreen; + + screen->driver = glxProbeDriver(driverName, + (void **)&screen->core, + __DRI_CORE, __DRI_CORE_VERSION, + (void **)&screen->swrast, + __DRI_SWRAST, __DRI_SWRAST_VERSION); + if (screen->driver == NULL) { + goto handle_error; + } + + screen->driScreen = + (*screen->swrast->createNewScreen)(pScreen->myNum, + loader_extensions, + &screen->driConfigs, + screen); + + if (screen->driScreen == NULL) { + LogMessage(X_ERROR, + "AIGLX error: Calling driver entry point failed\n"); + goto handle_error; + } + + initializeExtensions(screen); + + screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs, + GLX_WINDOW_BIT | + GLX_PIXMAP_BIT | + GLX_PBUFFER_BIT); + + __glXScreenInit(&screen->base, pScreen); + + screen->base.GLXmajor = 1; + screen->base.GLXminor = 4; + + LogMessage(X_INFO, + "AIGLX: Loaded and initialized %s\n", driverName); + + return &screen->base; + + handle_error: + if (screen->driver) + dlclose(screen->driver); + + free(screen); + + LogMessage(X_ERROR, "GLX: could not load software renderer\n"); + + return NULL; +} + +_X_EXPORT __GLXprovider __glXDRISWRastProvider = { + __glXDRIscreenProbe, + "DRISWRAST", + NULL +}; diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c index c4ad42648..928cf0c92 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -419,7 +419,17 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) void __glXScreenDestroy(__GLXscreen *screen) { + __GLXconfig *head, *next; + + head = screen->fbconfigs; + while (head) { + next = head->next; + free(head); + head = next; + } + free(screen->GLXvendor); free(screen->GLXextensions); free(screen->GLextensions); + free(screen->visuals); } diff --git a/xorg-server/glx/single2.c b/xorg-server/glx/single2.c index 4abd4c084..9f8254b01 100644 --- a/xorg-server/glx/single2.c +++ b/xorg-server/glx/single2.c @@ -1,386 +1,384 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "glxserver.h"
-#include "glxutil.h"
-#include "glxext.h"
-#include "indirect_dispatch.h"
-#include "unpack.h"
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-
-int __glXDisp_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc)
-{
- GLsizei size;
- GLenum type;
- __GLXcontext *cx;
- int error;
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- pc += __GLX_SINGLE_HDR_SIZE;
- size = *(GLsizei *)(pc+0);
- type = *(GLenum *)(pc+4);
- if (cx->feedbackBufSize < size) {
- cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
- (size_t)size
- * __GLX_SIZE_FLOAT32);
- if (!cx->feedbackBuf) {
- cl->client->errorValue = size;
- return BadAlloc;
- }
- cx->feedbackBufSize = size;
- }
- CALL_FeedbackBuffer( GET_DISPATCH(), (size, type, cx->feedbackBuf) );
- cx->hasUnflushedCommands = GL_TRUE;
- return Success;
-}
-
-int __glXDisp_SelectBuffer(__GLXclientState *cl, GLbyte *pc)
-{
- __GLXcontext *cx;
- GLsizei size;
- int error;
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- pc += __GLX_SINGLE_HDR_SIZE;
- size = *(GLsizei *)(pc+0);
- if (cx->selectBufSize < size) {
- cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
- (size_t) size
- * __GLX_SIZE_CARD32);
- if (!cx->selectBuf) {
- cl->client->errorValue = size;
- return BadAlloc;
- }
- cx->selectBufSize = size;
- }
- CALL_SelectBuffer( GET_DISPATCH(), (size, cx->selectBuf) );
- cx->hasUnflushedCommands = GL_TRUE;
- return Success;
-}
-
-int __glXDisp_RenderMode(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client;
- xGLXRenderModeReply reply;
- __GLXcontext *cx;
- GLint nitems=0, retBytes=0, retval, newModeCheck;
- GLubyte *retBuffer = NULL;
- GLenum newMode;
- int error;
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- pc += __GLX_SINGLE_HDR_SIZE;
- newMode = *(GLenum*) pc;
- retval = CALL_RenderMode( GET_DISPATCH(), (newMode) );
-
- /* Check that render mode worked */
- CALL_GetIntegerv( GET_DISPATCH(), (GL_RENDER_MODE, &newModeCheck) );
- if (newModeCheck != newMode) {
- /* Render mode change failed. Bail */
- newMode = newModeCheck;
- goto noChangeAllowed;
- }
-
- /*
- ** Render mode might have still failed if we get here. But in this
- ** case we can't really tell, nor does it matter. If it did fail, it
- ** will return 0, and thus we won't send any data across the wire.
- */
-
- switch (cx->renderMode) {
- case GL_RENDER:
- cx->renderMode = newMode;
- break;
- case GL_FEEDBACK:
- if (retval < 0) {
- /* Overflow happened. Copy the entire buffer */
- nitems = cx->feedbackBufSize;
- } else {
- nitems = retval;
- }
- retBytes = nitems * __GLX_SIZE_FLOAT32;
- retBuffer = (GLubyte*) cx->feedbackBuf;
- cx->renderMode = newMode;
- break;
- case GL_SELECT:
- if (retval < 0) {
- /* Overflow happened. Copy the entire buffer */
- nitems = cx->selectBufSize;
- } else {
- GLuint *bp = cx->selectBuf;
- GLint i;
-
- /*
- ** Figure out how many bytes of data need to be sent. Parse
- ** the selection buffer to determine this fact as the
- ** return value is the number of hits, not the number of
- ** items in the buffer.
- */
- nitems = 0;
- i = retval;
- while (--i >= 0) {
- GLuint n;
-
- /* Parse select data for this hit */
- n = *bp;
- bp += 3 + n;
- }
- nitems = bp - cx->selectBuf;
- }
- retBytes = nitems * __GLX_SIZE_CARD32;
- retBuffer = (GLubyte*) cx->selectBuf;
- cx->renderMode = newMode;
- break;
- }
-
- /*
- ** First reply is the number of elements returned in the feedback or
- ** selection array, as per the API for glRenderMode itself.
- */
- noChangeAllowed:;
- client = cl->client;
- reply.length = nitems;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.retval = retval;
- reply.size = nitems;
- reply.newMode = newMode;
- WriteToClient(client, sz_xGLXRenderModeReply, (char *)&reply);
- if (retBytes) {
- WriteToClient(client, retBytes, (char *)retBuffer);
- }
- return Success;
-}
-
-int __glXDisp_Flush(__GLXclientState *cl, GLbyte *pc)
-{
- __GLXcontext *cx;
- int error;
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- CALL_Flush( GET_DISPATCH(), () );
- cx->hasUnflushedCommands = GL_FALSE;
- return Success;
-}
-
-int __glXDisp_Finish(__GLXclientState *cl, GLbyte *pc)
-{
- __GLXcontext *cx;
- ClientPtr client;
- int error;
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- /* Do a local glFinish */
- CALL_Finish( GET_DISPATCH(), () );
- cx->hasUnflushedCommands = GL_FALSE;
-
- /* Send empty reply packet to indicate finish is finished */
- client = cl->client;
- __GLX_BEGIN_REPLY(0);
- __GLX_SEND_HEADER();
- return Success;
-}
-
-#define SEPARATOR " "
-
-char *__glXcombine_strings(const char *cext_string, const char *sext_string)
-{
- size_t clen, slen;
- char *combo_string, *token, *s1;
- const char *s2, *end;
-
- /* safeguard to prevent potentially fatal errors in the string functions */
- if (!cext_string)
- cext_string = "";
- if (!sext_string)
- sext_string = "";
-
- /*
- ** String can't be longer than min(cstring, sstring)
- ** pull tokens out of shortest string
- ** include space in combo_string for final separator and null terminator
- */
- clen = strlen(cext_string);
- slen = strlen(sext_string);
- if (clen > slen) {
- combo_string = (char *) malloc(slen + 2);
- s1 = (char *) malloc(slen + 2);
- if (s1) strcpy(s1, sext_string);
- s2 = cext_string;
- } else {
- combo_string = (char *) malloc(clen + 2);
- s1 = (char *) malloc(clen + 2);
- if (s1) strcpy(s1, cext_string);
- s2 = sext_string;
- }
- if (!combo_string || !s1) {
- free(combo_string);
- free(s1);
- return NULL;
- }
- combo_string[0] = '\0';
-
- /* Get first extension token */
- token = strtok( s1, SEPARATOR);
- while ( token != NULL ) {
-
- /*
- ** if token in second string then save it
- ** beware of extension names which are prefixes of other extension names
- */
- const char *p = s2;
- end = p + strlen(p);
- while (p < end) {
- size_t n = strcspn(p, SEPARATOR);
- if ((strlen(token) == n) && (strncmp(token, p, n) == 0)) {
- combo_string = strcat(combo_string, token);
- combo_string = strcat(combo_string, SEPARATOR);
- }
- p += (n + 1);
- }
-
- /* Get next extension token */
- token = strtok( NULL, SEPARATOR);
- }
- free(s1);
- return combo_string;
-}
-
-int DoGetString(__GLXclientState *cl, GLbyte *pc, GLboolean need_swap)
-{
- ClientPtr client;
- __GLXcontext *cx;
- GLenum name;
- const char *string;
- __GLX_DECLARE_SWAP_VARIABLES;
- int error;
- char *buf = NULL, *buf1 = NULL;
- GLint length = 0;
-
- /* If the client has the opposite byte order, swap the contextTag and
- * the name.
- */
- if ( need_swap ) {
- __GLX_SWAP_INT(pc + 4);
- __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE);
- }
-
- cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
- if (!cx) {
- return error;
- }
-
- pc += __GLX_SINGLE_HDR_SIZE;
- name = *(GLenum *)(pc + 0);
- string = (const char *) CALL_GetString( GET_DISPATCH(), (name) );
- client = cl->client;
-
- if (string == NULL)
- string = "";
-
- /*
- ** Restrict extensions to those that are supported by both the
- ** implementation and the connection. That is, return the
- ** intersection of client, server, and core extension strings.
- */
- if (name == GL_EXTENSIONS) {
- buf1 = __glXcombine_strings(string,
- cl->GLClientextensions);
- buf = __glXcombine_strings(buf1,
- cx->pGlxScreen->GLextensions);
- free(buf1);
- string = buf;
- }
- else if ( name == GL_VERSION ) {
- if ( atof( string ) > atof( GLServerVersion ) ) {
- buf = malloc( strlen( string ) + strlen( GLServerVersion ) + 4 );
- if ( buf == NULL ) {
- string = GLServerVersion;
- }
- else {
- sprintf( buf, "%s (%s)", GLServerVersion, string );
- string = buf;
- }
- }
- }
- if (string) {
- length = strlen((const char *) string) + 1;
- }
-
- __GLX_BEGIN_REPLY(length);
- __GLX_PUT_SIZE(length);
-
- if ( need_swap ) {
- __GLX_SWAP_REPLY_SIZE();
- __GLX_SWAP_REPLY_HEADER();
- }
-
- __GLX_SEND_HEADER();
- WriteToClient(client, length, (char *) string);
- free(buf);
-
- return Success;
-}
-
-int __glXDisp_GetString(__GLXclientState *cl, GLbyte *pc)
-{
- return DoGetString(cl, pc, GL_FALSE);
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * 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 including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * 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 + * SILICON GRAPHICS, INC. 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. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "glxserver.h" +#include "glxutil.h" +#include "glxext.h" +#include "indirect_dispatch.h" +#include "unpack.h" +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" + +int __glXDisp_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc) +{ + GLsizei size; + GLenum type; + __GLXcontext *cx; + int error; + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + pc += __GLX_SINGLE_HDR_SIZE; + size = *(GLsizei *)(pc+0); + type = *(GLenum *)(pc+4); + if (cx->feedbackBufSize < size) { + cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf, + (size_t)size + * __GLX_SIZE_FLOAT32); + if (!cx->feedbackBuf) { + cl->client->errorValue = size; + return BadAlloc; + } + cx->feedbackBufSize = size; + } + CALL_FeedbackBuffer( GET_DISPATCH(), (size, type, cx->feedbackBuf) ); + cx->hasUnflushedCommands = GL_TRUE; + return Success; +} + +int __glXDisp_SelectBuffer(__GLXclientState *cl, GLbyte *pc) +{ + __GLXcontext *cx; + GLsizei size; + int error; + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + pc += __GLX_SINGLE_HDR_SIZE; + size = *(GLsizei *)(pc+0); + if (cx->selectBufSize < size) { + cx->selectBuf = (GLuint *) realloc(cx->selectBuf, + (size_t) size + * __GLX_SIZE_CARD32); + if (!cx->selectBuf) { + cl->client->errorValue = size; + return BadAlloc; + } + cx->selectBufSize = size; + } + CALL_SelectBuffer( GET_DISPATCH(), (size, cx->selectBuf) ); + cx->hasUnflushedCommands = GL_TRUE; + return Success; +} + +int __glXDisp_RenderMode(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client; + xGLXRenderModeReply reply; + __GLXcontext *cx; + GLint nitems=0, retBytes=0, retval, newModeCheck; + GLubyte *retBuffer = NULL; + GLenum newMode; + int error; + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + pc += __GLX_SINGLE_HDR_SIZE; + newMode = *(GLenum*) pc; + retval = CALL_RenderMode( GET_DISPATCH(), (newMode) ); + + /* Check that render mode worked */ + CALL_GetIntegerv( GET_DISPATCH(), (GL_RENDER_MODE, &newModeCheck) ); + if (newModeCheck != newMode) { + /* Render mode change failed. Bail */ + newMode = newModeCheck; + goto noChangeAllowed; + } + + /* + ** Render mode might have still failed if we get here. But in this + ** case we can't really tell, nor does it matter. If it did fail, it + ** will return 0, and thus we won't send any data across the wire. + */ + + switch (cx->renderMode) { + case GL_RENDER: + cx->renderMode = newMode; + break; + case GL_FEEDBACK: + if (retval < 0) { + /* Overflow happened. Copy the entire buffer */ + nitems = cx->feedbackBufSize; + } else { + nitems = retval; + } + retBytes = nitems * __GLX_SIZE_FLOAT32; + retBuffer = (GLubyte*) cx->feedbackBuf; + cx->renderMode = newMode; + break; + case GL_SELECT: + if (retval < 0) { + /* Overflow happened. Copy the entire buffer */ + nitems = cx->selectBufSize; + } else { + GLuint *bp = cx->selectBuf; + GLint i; + + /* + ** Figure out how many bytes of data need to be sent. Parse + ** the selection buffer to determine this fact as the + ** return value is the number of hits, not the number of + ** items in the buffer. + */ + nitems = 0; + i = retval; + while (--i >= 0) { + GLuint n; + + /* Parse select data for this hit */ + n = *bp; + bp += 3 + n; + } + nitems = bp - cx->selectBuf; + } + retBytes = nitems * __GLX_SIZE_CARD32; + retBuffer = (GLubyte*) cx->selectBuf; + cx->renderMode = newMode; + break; + } + + /* + ** First reply is the number of elements returned in the feedback or + ** selection array, as per the API for glRenderMode itself. + */ + noChangeAllowed:; + client = cl->client; + reply.length = nitems; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.retval = retval; + reply.size = nitems; + reply.newMode = newMode; + WriteToClient(client, sz_xGLXRenderModeReply, (char *)&reply); + if (retBytes) { + WriteToClient(client, retBytes, (char *)retBuffer); + } + return Success; +} + +int __glXDisp_Flush(__GLXclientState *cl, GLbyte *pc) +{ + __GLXcontext *cx; + int error; + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + CALL_Flush( GET_DISPATCH(), () ); + cx->hasUnflushedCommands = GL_FALSE; + return Success; +} + +int __glXDisp_Finish(__GLXclientState *cl, GLbyte *pc) +{ + __GLXcontext *cx; + ClientPtr client; + int error; + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + /* Do a local glFinish */ + CALL_Finish( GET_DISPATCH(), () ); + cx->hasUnflushedCommands = GL_FALSE; + + /* Send empty reply packet to indicate finish is finished */ + client = cl->client; + __GLX_BEGIN_REPLY(0); + __GLX_SEND_HEADER(); + return Success; +} + +#define SEPARATOR " " + +char *__glXcombine_strings(const char *cext_string, const char *sext_string) +{ + size_t clen, slen; + char *combo_string, *token, *s1; + const char *s2, *end; + + /* safeguard to prevent potentially fatal errors in the string functions */ + if (!cext_string) + cext_string = ""; + if (!sext_string) + sext_string = ""; + + /* + ** String can't be longer than min(cstring, sstring) + ** pull tokens out of shortest string + ** include space in combo_string for final separator and null terminator + */ + clen = strlen(cext_string); + slen = strlen(sext_string); + if (clen > slen) { + combo_string = (char *) malloc(slen + 2); + s1 = (char *) malloc(slen + 2); + if (s1) strcpy(s1, sext_string); + s2 = cext_string; + } else { + combo_string = (char *) malloc(clen + 2); + s1 = (char *) malloc(clen + 2); + if (s1) strcpy(s1, cext_string); + s2 = sext_string; + } + if (!combo_string || !s1) { + free(combo_string); + free(s1); + return NULL; + } + combo_string[0] = '\0'; + + /* Get first extension token */ + token = strtok( s1, SEPARATOR); + while ( token != NULL ) { + + /* + ** if token in second string then save it + ** beware of extension names which are prefixes of other extension names + */ + const char *p = s2; + end = p + strlen(p); + while (p < end) { + size_t n = strcspn(p, SEPARATOR); + if ((strlen(token) == n) && (strncmp(token, p, n) == 0)) { + combo_string = strcat(combo_string, token); + combo_string = strcat(combo_string, SEPARATOR); + } + p += (n + 1); + } + + /* Get next extension token */ + token = strtok( NULL, SEPARATOR); + } + free(s1); + return combo_string; +} + +int DoGetString(__GLXclientState *cl, GLbyte *pc, GLboolean need_swap) +{ + ClientPtr client; + __GLXcontext *cx; + GLenum name; + const char *string; + __GLX_DECLARE_SWAP_VARIABLES; + int error; + char *buf = NULL, *buf1 = NULL; + GLint length = 0; + + /* If the client has the opposite byte order, swap the contextTag and + * the name. + */ + if ( need_swap ) { + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE); + } + + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; + } + + pc += __GLX_SINGLE_HDR_SIZE; + name = *(GLenum *)(pc + 0); + string = (const char *) CALL_GetString( GET_DISPATCH(), (name) ); + client = cl->client; + + if (string == NULL) + string = ""; + + /* + ** Restrict extensions to those that are supported by both the + ** implementation and the connection. That is, return the + ** intersection of client, server, and core extension strings. + */ + if (name == GL_EXTENSIONS) { + buf1 = __glXcombine_strings(string, + cl->GLClientextensions); + buf = __glXcombine_strings(buf1, + cx->pGlxScreen->GLextensions); + free(buf1); + string = buf; + } + else if ( name == GL_VERSION ) { + if ( atof( string ) > atof( GLServerVersion ) ) { + if ( asprintf( &buf, "%s (%s)", GLServerVersion, string ) == -1) { + string = GLServerVersion; + } + else { + string = buf; + } + } + } + if (string) { + length = strlen((const char *) string) + 1; + } + + __GLX_BEGIN_REPLY(length); + __GLX_PUT_SIZE(length); + + if ( need_swap ) { + __GLX_SWAP_REPLY_SIZE(); + __GLX_SWAP_REPLY_HEADER(); + } + + __GLX_SEND_HEADER(); + WriteToClient(client, length, (char *) string); + free(buf); + + return Success; +} + +int __glXDisp_GetString(__GLXclientState *cl, GLbyte *pc) +{ + return DoGetString(cl, pc, GL_FALSE); +} |