diff options
Diffstat (limited to 'xorg-server/glx/glxdriswrast.c')
-rw-r--r-- | xorg-server/glx/glxdriswrast.c | 996 |
1 files changed, 502 insertions, 494 deletions
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 +}; |